Reservations
A reservation is one guest stay at a property. This guide covers the reservation operations most integrations need. Every field and filter is listed on the operation’s page in the API Reference.
| Operation | Request | Permission |
|---|---|---|
listReservations | GET /reservations | view_reservations |
getReservation | GET /reservations/{id} | view_reservations |
createReservation | POST /reservations | modify_reservations |
updateReservation | PATCH /reservations/{id} | modify_reservations |
updateCheckInState | POST /reservations/{id}/check-in-state | modify_reservations |
Paths are relative to your region’s base URL, for example https://api-us.suiteop.com/api/v1. See Authentication for permissions.
Listing reservations
Section titled “Listing reservations”GET /reservations is paginated (default limit 20, maximum 100). Rows are ordered by the resolved check-in, ascending, which can differ from the checkIn returned.
curl "https://api-us.suiteop.com/api/v1/reservations?statuses=confirmed&dateFrom=2026-07-05T00:00:00.000Z&dateTo=2026-07-11T00:00:00.000Z&dateType=check_in" \ -H "Authorization: Bearer sk_live_your_key_here"const params = new URLSearchParams({ dateFrom: '2026-07-05T00:00:00.000Z', dateTo: '2026-07-11T00:00:00.000Z', dateType: 'check_in',})params.append('statuses', 'confirmed')params.append('statuses', 'reserved')
const res = await fetch(`https://api-us.suiteop.com/api/v1/reservations?${params}`, { headers: { Authorization: `Bearer ${process.env.SUITEOP_API_KEY}` },})const { data, meta } = await res.json()console.log(`${data.length} of ${meta.pagination.total} stays`)Useful filters:
| Filter | Notes |
|---|---|
statuses | Booking status, e.g. confirmed or canceled. Omit it and cancelled and declined stays are included |
checkInStates | not_checked_in, checked_in, checked_out |
dateFrom, dateTo | ISO 8601 instants, e.g. 2026-07-05T00:00:00.000Z. Only the UTC date is used, as a calendar day at the property, so an offset counts after conversion: 2026-07-05T00:00:00+02:00 is July 4. Both ends are inclusive |
dateType | Which date the window applies to: check_in (default), check_out, booked_date, or stay_date (any overlap). check_in/check_out use the actual time once checkInState confirms it, else the override, else the scheduled time. Ignored without a window |
propertyIds, propertyGroupIds | Repeat the key for several values |
bookingSourceIds, integrationAccountId | Narrow by booking source or by connected PMS account |
codeStatuses | Door-code provisioning state, e.g. active, pending, failed |
verificationStatuses | Guest verification: verified, review, pending, decline, unknown |
search | Case- and accent-insensitive match on guest name, guest email, confirmation code and PMS reservation ID |
Each row carries fields such as id, guestFirstName, guestLastName, checkIn, checkOut, nightCount, confirmationCode, status, checkInState, codeStatus, totalPriceCents, propertyId, propertyName and verificationStatus. GET /reservations/{id} returns the whole stay, including the price breakdown (subtotalCents, totalFeeCents, totalTaxCents, totalDiscountCents), currency and the actual checkedInAt / checkedOutAt times. Amounts are integers in the currency’s minor unit (cents).
checkIn and checkOut are the stored values, so a stay your PMS sent as a bare date reads as midnight UTC. To show or compare stay times, both the list and getReservation (not the create or update response) add two computed pairs:
displayCheckInAt/displayCheckOutAt: the instant to show. The recorded arrival or departure oncecheckInStateconfirms it, else the override set on the stay, else the scheduled time. A date-only scheduled time is placed at the property’s default check-in or check-out hour in its time zone.scheduledCheckInAt/scheduledCheckOutAt: what the stay was booked for, placed the same way, ignoring overrides and recorded times. Compare it with the display pair to tell whether a boundary moved off schedule.
Creating a reservation
Section titled “Creating a reservation”Only for stays booked outside your PMS. Reservations owned by a connected PMS reach SuiteOp through that integration’s own sync.
propertyId, checkIn and checkOut are required:
curl -X POST https://api-us.suiteop.com/api/v1/reservations \ -H "Authorization: Bearer sk_live_your_key_here" \ -H "Idempotency-Key: 8f14e45f-ceea-467f-a0e6-7d1b2c3a4b5c" \ -H "Content-Type: application/json" \ -d '{ "propertyId": "9a3d7e40-…", "checkIn": "2026-07-05", "checkOut": "2026-07-08", "guestFirstName": "Ana", "guestLastName": "García", "guestEmail": "[email protected]", "guestPhone": "+34 612 345 678", "guestCount": 2 }'The response is 201 with the created reservation in data, including its id, nightCount and confirmationCode.
Field notes:
- Dates: a bare day such as
2026-07-05is placed at the property’s own check-in (or check-out) hour in its timezone. A full instant such as2026-07-05T15:00:00Zis stored exactly as given. statusdefaults toconfirmed. Onlyconfirmed,reservedandawaiting_paymentopen guest verification and schedule the property to flip to occupied at check-in and dirty at check-out.inquiry,blockedand the terminal statuses record the stay without either.guestPhoneis normalized to E.164. A number without a country code is read as a US number, so send international numbers in full.confirmationCodeis stored as given. Omit it and SuiteOp generates one shaped likeSO-AB1C2D3E4F. It is not checked for uniqueness.- Also accepted:
externalReservationId,bookingSourceId,sourceText,pmsProviderandsubtotalCents.
Updating a reservation
Section titled “Updating a reservation”PATCH /reservations/{id} takes the fields to change inside a data object: dates, guest details, guestCount, confirmationCode, externalReservationId, etaCheckIn, etaCheckOut, propertyId, sourceText and subtotalCents.
curl -X PATCH https://api-us.suiteop.com/api/v1/reservations/4e2a… \ -H "Authorization: Bearer sk_live_your_key_here" \ -H "Content-Type: application/json" \ -d '{"data": {"checkOut": "2026-07-09", "guestCount": 3}}'Changing a date recounts the nights and re-times any door codes already provisioned for the stay — unless the same call also changes propertyId, which skips the re-time. The booking status and the checkInState can’t be set here.
Checking guests in and out
Section titled “Checking guests in and out”POST /reservations/{id}/check-in-state records an arrival or departure. checkInState and occupancyMethod are both required:
curl -X POST https://api-us.suiteop.com/api/v1/reservations/4e2a…/check-in-state \ -H "Authorization: Bearer sk_live_your_key_here" \ -H "Content-Type: application/json" \ -d '{"checkInState": "checked_in", "occupancyMethod": "dashboard"}'- The flow runs one way:
not_checked_in→checked_in→checked_out, or straight fromnot_checked_intochecked_out. Any other move, including repeating the current state, is rejected. - Checking in marks the property occupied. Checking out marks it dirty and resets its inspection, unless another guest is still checked in there. A failed inspection is never overwritten.
occupancyMethodrecords how the change happened:dashboard,guest_portal,smart_lock,remote_controlorworkflow_action. It doesn’t trigger anything.- If the stay requires a check-in review, check-in is rejected until you send
acknowledgeCheckInReview: true.