ChatBedsDevelopers
API reference

Folios and payments

Read a booking's bill, post charges, record payments you took, send a card payment link on the hotel's Stripe account, and check a payment's status.

Every reservation has a folio: the guest's bill. Room nights, extras, fees and tax go on it as charges when the booking is made; payments go on it as they are received. balance is what is still owed.

Bookings made through the API are pay at the hotel. If your app takes the money, record it with folio.addPayment; if the hotel should take it by card, send the guest a payment link. The Take payments guide walks through both.

Get the folio

GET/reservations/{reservation_id}/folio
Scope folios:readOperation folio.get

Returns every line on the bill (voided lines included and marked), the totals, the balance and the payments.

Parameters

reservation_id uuid (path)required
The reservation.

Example

Request
curl -X GET "https://api.chatbeds.app/partner/v1/reservations/a589df05-30ad-4ee5-9832-16ff6c2c1d0e/folio" \
  -H "Authorization: Bearer cbk_••••"
200 OK
{
  "folio": {
    "reservation_id": "a589df05-30ad-4ee5-9832-16ff6c2c1d0e",
    "currency": "USD",
    "lines": [
      {
        "id": "bdaead22-6697-49a1-ad00-510f88b151cc",
        "type": "ROOM_CHARGE",
        "description": "Standard, night of 2026-10-31",
        "amount": 90.0,
        "service_date": "2026-10-31",
        "posted_at": "2026-10-10T05:09:47.274835",
        "voided": false,
        "void_reason": null,
        "payment_id": null
      },
      {
        "id": "7df0796f-3e3e-48ff-8361-eeeff715f7b4",
        "type": "ROOM_CHARGE",
        "description": "Standard, night of 2026-11-01",
        "amount": 90.0,
        "service_date": "2026-11-01",
        "posted_at": "2026-10-10T05:09:47.277372",
        "voided": false,
        "void_reason": null,
        "payment_id": null
      },
      {
        "id": "442f2691-f69f-4da3-bfc6-de650d9a9866",
        "type": "INCIDENTAL",
        "description": "Airport transfer",
        "amount": 35.0,
        "service_date": "2026-10-10",
        "posted_at": "2026-10-10T05:09:47.387569",
        "voided": false,
        "void_reason": null,
        "payment_id": null
      },
      {
        "id": "d3dc1f18-4b15-42b5-bf9f-a3b375b3435e",
        "type": "PAYMENT",
        "description": "Paid through Sandbox key",
        "amount": 100.0,
        "service_date": null,
        "posted_at": "2026-10-10T05:09:47.406626",
        "voided": false,
        "void_reason": null,
        "payment_id": "763300e8-3898-4fba-a0b0-0a0cc86ba611"
      }
    ],
    "total_charges": 215.0,
    "total_payments": 100.0,
    "balance": 115.0,
    "payments": [
      {
        "id": "763300e8-3898-4fba-a0b0-0a0cc86ba611",
        "reservation_id": "a589df05-30ad-4ee5-9832-16ff6c2c1d0e",
        "kind": "PAYMENT",
        "amount": 100.0,
        "currency": "USD",
        "method": "CARD",
        "status": "COMPLETED",
        "reference": "BK-PAY-88231",
        "paid_at": "2026-10-10T05:09:47.406608+00:00",
        "created_at": "2026-10-10T05:09:47.405620+00:00",
        "url": null,
        "expires_at": null
      }
    ]
  }
}
FieldMeaning
lines[].typeROOM_CHARGE (one per night), INCIDENTAL (extras and charges), FEE, TAX, PAYMENT, REFUND
lines[].service_dateThe night or day the charge is for; null for payments
lines[].voidedtrue when the hotel took the line off the bill; void_reason says why. Voided lines do not count in the totals
lines[].payment_idOn PAYMENT and REFUND lines, the payment it records
total_chargesAll charges not voided
total_paymentsPayments received, less refunds
balancetotal_charges minus total_payments. Negative means the hotel owes the guest money
payments[]Every payment, including links not yet paid

Errors

StatusdetailWhen
403The app token lacks folios:read
404Reservation not found

Add a charge

POST/reservations/{reservation_id}/folio/charges
Scope folios:writeOperation folio.addCharge

Puts something the guest had on the bill: a transfer, a meal, a tour you sold. The line is amount times quantity, dated today at the hotel, and tax is recalculated. Returns the whole folio.

Body

reservation_id uuid (path)required
The reservation.
description stringrequired
1 to 120 characters, as the guest will see it, for example Airport transfer.
amount numberrequired
The price of one. More than 0, up to 99,999,999.99, in the booking's currency.
quantity integer
1 to 99. Default 1. Above 1 the line reads Airport transfer x2.

Example

Request
curl -X POST "https://api.chatbeds.app/partner/v1/reservations/a589df05-30ad-4ee5-9832-16ff6c2c1d0e/folio/charges" \
  -H "Authorization: Bearer cbk_••••" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: BK-104233-charge-transfer" \
  -d '{"description": "Airport transfer", "amount": 35, "quantity": 1}'
200 OK
{
  "folio": {
    "reservation_id": "a589df05-30ad-4ee5-9832-16ff6c2c1d0e",
    "currency": "USD",
    "lines": [
      {
        "id": "bdaead22-6697-49a1-ad00-510f88b151cc",
        "type": "ROOM_CHARGE",
        "description": "Standard, night of 2026-10-31",
        "amount": 90.0,
        "service_date": "2026-10-31",
        "posted_at": "2026-10-10T05:09:47.274835",
        "voided": false,
        "void_reason": null,
        "payment_id": null
      },
      // ... the night of 2026-11-01
      {
        "id": "442f2691-f69f-4da3-bfc6-de650d9a9866",
        "type": "INCIDENTAL",
        "description": "Airport transfer",
        "amount": 35.0,
        "service_date": "2026-10-10",
        "posted_at": "2026-10-10T05:09:47.387569",
        "voided": false,
        "void_reason": null,
        "payment_id": null
      }
    ],
    "total_charges": 215.0,
    "total_payments": 0.0,
    "balance": 215.0,
    "payments": []
  }
}

Errors

StatusdetailWhen
409A cancelled booking takes no new charges.
409The stay is over: the hotel adds any late charge itself.The guest has checked out
403The app token lacks folios:write
404Reservation not found
422description empty or over 120 characters, amount not above 0, quantity out of range

Record a payment

POST/reservations/{reservation_id}/folio/payments
Scope folios:writeOperation folio.addPayment

Records money you took for the hotel (on your own payment gateway, say), so the bill shows it paid. ChatBeds does not move any money here. You can record at most what is owed. Returns the payment and the updated folio.

Body

reservation_id uuid (path)required
The reservation.
amount numberrequired
More than 0, and at most the folio's balance.
method stringrequired
CASH, CARD or BANK_TRANSFER.
reference string
Up to 255 characters: your transaction ID, so the hotel can match it.

Example

Request
curl -X POST "https://api.chatbeds.app/partner/v1/reservations/a589df05-30ad-4ee5-9832-16ff6c2c1d0e/folio/payments" \
  -H "Authorization: Bearer cbk_••••" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: BK-PAY-88231" \
  -d '{"amount": 100, "method": "CARD", "reference": "BK-PAY-88231"}'
200 OK
{
  "payment": {
    "id": "763300e8-3898-4fba-a0b0-0a0cc86ba611",
    "reservation_id": "a589df05-30ad-4ee5-9832-16ff6c2c1d0e",
    "kind": "PAYMENT",
    "amount": 100.0,
    "currency": "USD",
    "method": "CARD",
    "status": "COMPLETED",
    "reference": "BK-PAY-88231",
    "paid_at": "2026-10-10T05:09:47.406608+00:00",
    "created_at": "2026-10-10T05:09:47.405620+00:00",
    "url": null,
    "expires_at": null
  },
  "folio": {
    "reservation_id": "a589df05-30ad-4ee5-9832-16ff6c2c1d0e",
    "currency": "USD",
    "lines": [
      // ... the two nights and the airport transfer, as above
      {
        "id": "d3dc1f18-4b15-42b5-bf9f-a3b375b3435e",
        "type": "PAYMENT",
        "description": "Paid through Sandbox key",
        "amount": 100.0,
        "service_date": null,
        "posted_at": "2026-10-10T05:09:47.406626",
        "voided": false,
        "void_reason": null,
        "payment_id": "763300e8-3898-4fba-a0b0-0a0cc86ba611"
      }
    ],
    "total_charges": 215.0,
    "total_payments": 100.0,
    "balance": 115.0,
    "payments": [
      {
        "id": "763300e8-3898-4fba-a0b0-0a0cc86ba611",
        "reservation_id": "a589df05-30ad-4ee5-9832-16ff6c2c1d0e",
        "kind": "PAYMENT",
        "amount": 100.0,
        "currency": "USD",
        "method": "CARD",
        "status": "COMPLETED",
        "reference": "BK-PAY-88231",
        "paid_at": "2026-10-10T05:09:47.406608+00:00",
        "created_at": "2026-10-10T05:09:47.405620+00:00",
        "url": null,
        "expires_at": null
      }
    ]
  }
}

The payment line reads "Paid through" and your key's or app's name, so the hotel knows where the money is.

Errors

StatusdetailWhen
400Only USD 115.00 is owed on this booking.amount is more than the balance
403The app token lacks folios:write
404Reservation not found
422amount not above 0, or method not one of the three
POST/reservations/{reservation_id}/payment-link
Scope payments:writeOperation payment.createLink

Makes a Stripe Checkout page on the hotel's own Stripe account for the guest to pay by card. The money goes to the hotel; ChatBeds marks the payment completed when Stripe confirms it. The link stays open for 23 hours. Send the returned url to the guest.

It works only when the hotel has connected Stripe: check features.payment_links in GET /capabilities.

Body

reservation_id uuid (path)required
The reservation.
amount number
More than 0, up to what is owed. Default: everything owed, less any link still open. The body is optional.

Example

Request
curl -X POST "https://api.chatbeds.app/partner/v1/reservations/a589df05-30ad-4ee5-9832-16ff6c2c1d0e/payment-link" \
  -H "Authorization: Bearer cbk_••••" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: BK-104233-link-1" \
  -d '{}'

The sandbox hotel has no Stripe account connected, so the recorded call answers 400:

400 Bad Request
{
  "detail": "Card payments are not set up for this hotel. An owner connects Stripe on the Finance page."
}

With Stripe connected, the answer is 200 OK with {"payment": {...}}: a payment with method: "STRIPE", status: "PENDING", the Checkout page in url and its expires_at. Poll payment.getStatus to see when it is paid.

Errors

StatusdetailWhen
400Card payments are not set up for this hotel. An owner connects Stripe on the Finance page.No Stripe. Do not offer card payment for this hotel
400Nothing is owed on this booking.No amount and the balance is 0
400A card payment link for ... is already open for what is owed.A link for the whole balance is still open. Use it, or wait for it to expire
400Only ... is owed on this booking (... more is on a card link still open).amount is more than is owed
402The hotel's plan does not include card payments
409This booking is cancelled.
502Stripe could not be reached. Try again in a moment., Stripe did not accept the hotel's key. ..., or Stripe: ... with Stripe's messageStripe refused or did not answer. No link was made; retry later, or tell the hotel if its key was refused
403The app token lacks payments:write
404Reservation not found

Get a payment

GET/payments/{payment_id}
Scope folios:readOperation payment.getStatus

Returns one payment at the property: one you recorded, a payment link, or a payment taken at the front desk.

Parameters

payment_id uuid (path)required
The payment's id, from a payment link, a recorded payment or the folio.

Example

Request
curl -X GET "https://api.chatbeds.app/partner/v1/payments/763300e8-3898-4fba-a0b0-0a0cc86ba611" \
  -H "Authorization: Bearer cbk_••••"
200 OK
{
  "payment": {
    "id": "763300e8-3898-4fba-a0b0-0a0cc86ba611",
    "reservation_id": "a589df05-30ad-4ee5-9832-16ff6c2c1d0e",
    "kind": "PAYMENT",
    "amount": 100.0,
    "currency": "USD",
    "method": "CARD",
    "status": "COMPLETED",
    "reference": "BK-PAY-88231",
    "paid_at": "2026-10-10T05:09:47.406608+00:00",
    "created_at": "2026-10-10T05:09:47.405620+00:00",
    "url": null,
    "expires_at": null
  }
}

The payment object

FieldMeaning
kindPAYMENT or REFUND
methodCASH, CARD, BANK_TRANSFER, or STRIPE for a payment link
statusSee below
referenceThe reference you or the hotel gave. Always null for STRIPE
paid_atWhen it was paid; set only when COMPLETED
urlThe Checkout page; set only while PENDING
expires_atWhen a payment link closes
StatusMeaning
PENDINGA payment link not paid yet. url is the page to send
COMPLETEDPaid. Counts on the folio
EXPIREDA payment link nobody paid before expires_at. Create a new one
VOIDEDEntered by mistake and taken off the folio by the hotel
FAILEDThe payment did not go through

Errors

StatusdetailWhen
403The app token lacks folios:read
404Payment not foundNot a payment at this property

Building something?

On this page