Reading reservations
getReservationspages withpageNumberandpageSize(we used 100). It filters bycheckInFromandcheckInTo. Pass every status explicitly (status=confirmed,not_confirmed,canceled,checked_in,checked_out,no_show) if you need them all. A short page means you’ve reached the end.getReservationreturns the booking with aguestListkeyed by guest ID. Each guest hasisMainGuestandrooms[]with the real integerroomIDandsubReservationID.- To get the rate plan a booking was sold on, use v1.3
getReservationsWithRateDetails(rooms[].rateID/rateName).getReservationdoesn’t include it. - Money:
getReservationInvoiceInformationgives the invoice, includingreservationAdditionalProducts(add-ons) andbalanceDetailed.getTransactionsgives each debit and credit withtransactionType,transactionCategoryandtransactionCode. See Folios and payments. - Notes:
getReservationNotes.
Creating: postReservation
POST https://api.cloudbeds.com/api/v1.2/postReservation, PHP-form-encoded (see Requests).
rooms[]carriesroomTypeID,quantity,roomIDandroomRateID.adults[]andchildren[]carryroomTypeID,roomIDandquantity. The array indexes must line up withrooms[].- One guest only.
postReservationtakes a single guest, and the booking puts that guest on every room. To give each room its own guest, see Per-room guests. - The whole booking shares one date range. A booking whose rooms have different dates can’t be created in one call.
putReservationaccepts per-roomcheckinDate/checkoutDateafterwards, but the create still has to pass the availability check first. - Status isn’t settable here. New bookings are
confirmed; set any other status afterwards withputReservation. - Room charges are generated automatically at the property’s current rate plan, not at the price you’re copying from. Expect the folio total to differ from the source booking and plan to correct it (see Rate differences).
- Set
thirdPartyIdentifierto your own reference (we used the source reservation number). It’s the only practical way to find a booking you created; see Avoiding duplicates. - On
putReservation, sendsendStatusChangeEmail=falseso guests aren’t emailed during back-office status changes.
sourceID: only third-party sources work
sourceID must be formatted to match the source’s type, built from getSources (sourceID, isThirdParty, paymentCollect):
Store the raw IDs and build the formatted string when you post. Don’t store formatted strings.
paymentMethod
Use a real code from the property’s getPaymentMethods. The values shown in the API docs (cash, credit, ebanking, pay_pal) are just examples. Custom methods work in both postReservation.paymentMethod and postPayment.type. We created a method coded Paidatanotherlocation to record money already taken by the previous owner.
customFields: leave them out unless you have the shortcodes
Sending customFields as {customFieldID, customFieldValue} makes the whole create fail: “fieldName and fieldValue are mandatory options for customFields”. The fields are keyed by the destination’s field shortcode (from getCustomFields). We left custom fields out of the create, since they held non-critical occasion notes.
Validation errors and fixes
Each of these returnssuccess:false and creates nothing, so you can safely fix the field and post again. We retried up to 4 times per booking and recorded each change in a note on the booking:
Pre-empt the country and email problems by cleaning them before the first post, then keep the reactive retry as a safety net.
Status: putReservation
- Statuses are
confirmed,not_confirmed,canceled,checked_in,checked_outandno_show. - A refused change returns HTTP 200 with
success:false: a silent no-op that leaves the booking onconfirmed. Check the body. - Try the target status directly first. If it’s refused, walk the chain
confirmed→checked_in→checked_out, checking each step. (canceledandno_showcan be set directly.) checked_inneeds a room assigned.checked_outis refused while the folio has a balance (“There is still a balance remaining”). Post charges and payments before setting status. On a two-folio booking (Agent + Guest), an outstanding agent balance did not block checkout.
Per-room guests
On a multi-room booking each room can have its own guest, butpostReservation can’t set that. Two calls afterwards do; neither shows in the API explorer’s postReservation page, but both are in llms.txt:
postGuest:reservationID,guestFirstName,guestLastName,guestEmailandguestCountryare all required. ReturnsguestID. The docs list it under v1.3, but we called it onhttps://api.cloudbeds.com/api/v1.2with the other writes and it worked.postGuestsToRoom(v1.2):reservationID,roomID(the integer room ID, which must already be assigned),guestIDs(comma-separated) and optionalmainGuestId(must be one ofguestIDs; makes that guest the room’s lead).
roomIDs back with getReservation, because the room string you posted at create (e.g. 676220-0) isn’t what postGuestsToRoom takes. Match rooms by name when both sides use the same labels, and only fall back to matching by order when the counts are equal and you’ve told someone to check.
Do this after the create and before setting status. A checked_out booking is locked for edits.
postGuest HTML-encodes & on store: a guest named “Josie, Thomas & Caroline” shows as & in the new Cloudbeds UI. postReservation doesn’t do this for the main guest. We send the plain &. We didn’t test whether sending an entity avoids it (it may double-encode).Notes: postReservationNote
- One call per note.
- Notes render as HTML and collapse whitespace. Both
\nand\r\nshow as one long line, so convert line breaks to<br>.
Avoiding duplicates
Creating a reservation isn’t idempotent. Posting the same booking twice makes two bookings, andpostReservation has no reference ID to stop it.
- Stamp
thirdPartyIdentifieron every booking you create. - If a create times out or its response is ambiguous, don’t post again blind. Look first: page
getReservationsfor that check-in date (checkInFrom=checkInTo= the date, all statuses) and matchthirdPartyIdentifier. - Treat a lookup that errored, or hit your page limit before the end, as “might exist”: hold the booking for review rather than risk a duplicate.
- Notes and payments aren’t idempotent either. If you find an orphaned booking, mark it for manual checking rather than replaying its follow-up calls.
- To redo a booking you created, delete it in Cloudbeds first, then clear your own record of it.
Cancelled bookings
When a booking is cancelled, the source voids the room charge and refunds payments. Its total, paid and balance then no longer describe a normal booking:balanceDetailed.paid is gross of refunds, so a cancelled booking can show paid far above its total. Recreating one means the destination charges the full room again. We left cancellations out of the automatic migration: ones with no money were simply excluded, and ones carrying money were handled by hand.
Notes are a separate call
postReservation has no free-text note field. Anything the booker typed
goes as postReservationNote once the reservation exists, which means a booking
can be created and its note then fail. Decide which of those you treat as the
outcome; we treat the reservation as the thing that happened and surface the
note failure separately.
Direct and third-party sources are different sources
getSources returns both, and the same operator can exist as both: one
trading partner of ours is third-party ss-353543 and direct s-1055799,
with different rate plans behind each. They are not duplicates to be merged.
- For creating a booking, only third-party (
ss-…) sources are assignable — seesourceID. - For reading, filter deliberately. A tool that offers a booker “the source list” usually wants direct sources only, because a third-party source belongs to the channel manager; say so in the UI, or the first question you get is why a channel is missing.