Developers

API reference

Read provider-neutral property and reservation records through a small, stable contract.

Base URL and schema

Text
https://supahost.io/api/v1

The machine-readable OpenAPI 3.1 schema is available at /api/v1/openapi.json.

Test keys and sandbox data

Create a test key in Settings to build an integration without touching real data. Test keys start with sh_test_; live keys start with sh_live_.

A test key serves a fixed synthetic dataset: three sandbox properties with room types, rate plans, and calendar days, plus eight sandbox reservations across every status and channel. Filters, cursor pagination, and error responses behave exactly as they do for live keys.

  • Sandbox records are clearly fake: names like Sandbox Seaside Resort, @example.com emails, and 555 phone numbers.
  • The dataset is stable, so a cursor chain reads the same records on every run. Unknown IDs return not_found, the same as live keys.
  • Test keys share the scopes, rate limit, and request audit of live keys. The audit record marks the key environment.

Writes need a live key. Test keys answer every write endpoint (property, task, message, calendar, rate-plan, and webhook management) with sandbox_read_only.

Properties

Property endpoints require the properties:read scope. Required response fields are always present; nullable fields include null in their type.

GET /properties

Return one stable page of properties.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Query parameters
FieldTypeRequiredDescription
limitintegerOptionalRecords per page, from 1 through 200. The default is 100.
cursorstringOptionalSend meta.page.nextCursor without changing any other filter.
updated_afterstring (date-time)OptionalReturn records changed after this ISO 8601 date and time.
status'active' | 'inactive' | 'all'OptionalFilter by property status. The default is active.
200 JSON response
FieldTypeRequiredDescription
dataProperty[]RequiredA stable page of property records.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
meta.pageobjectRequiredCursor pagination state.
meta.page.hasMorebooleanRequiredWhether another page is available.
meta.page.limitintegerRequiredThe page size applied to this response.
meta.page.nextCursorstring | nullRequiredThe cursor for the next page, or null when the page is final.
meta.page.snapshotAtstring (date-time)RequiredThe stable read boundary shared by every page in the cursor chain.
data[].idstringRequiredStable property ID.
data[].codestringRequiredProperty code.
data[].namestringRequiredDisplay name.
data[].timezonestringRequiredIANA time zone.
data[].status'active' | 'inactive'RequiredProperty status.
data[].updatedAtstring (date-time)RequiredLast property change time.
data[].inventoryobjectRequiredProperty inventory summary.
data[].inventory.maxGuestsintegerRequiredMaximum occupancy across active room types.
data[].inventory.physicalUnitsintegerRequiredNumber of active physical units.
data[].inventory.strategiesstring[]RequiredInventory strategies used by active pools.
data[].channelsstring[]RequiredActive channel names.
data[].startingRateobject | nullRequiredLowest active starting rate, or null when no rate exists.
data[].startingRate.amountMinorstringConditionalRequired when startingRate is an object. Amount in the currency minor unit.
data[].startingRate.currencystringConditionalRequired when startingRate is an object. Three-letter currency code.

GET /properties/{propertyId}

Return one property from the API key workspace.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Path parameters
FieldTypeRequiredDescription
propertyIdstringRequiredPositive property database ID.
200 JSON response
FieldTypeRequiredDescription
dataPropertyRequiredThe requested property.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
data.idstringRequiredStable property ID.
data.codestringRequiredProperty code.
data.namestringRequiredDisplay name.
data.timezonestringRequiredIANA time zone.
data.status'active' | 'inactive'RequiredProperty status.
data.updatedAtstring (date-time)RequiredLast property change time.
data.inventoryobjectRequiredProperty inventory summary.
data.inventory.maxGuestsintegerRequiredMaximum occupancy across active room types.
data.inventory.physicalUnitsintegerRequiredNumber of active physical units.
data.inventory.strategiesstring[]RequiredInventory strategies used by active pools.
data.channelsstring[]RequiredActive channel names.
data.startingRateobject | nullRequiredLowest active starting rate, or null when no rate exists.
data.startingRate.amountMinorstringConditionalRequired when startingRate is an object. Amount in the currency minor unit.
data.startingRate.currencystringConditionalRequired when startingRate is an object. Three-letter currency code.

PUT /properties/{propertyId}

Replace the writable details of one property. This endpoint requires the properties:write scope. Only name and timezone are writable; the other read fields are ignored when sent back.

The response is the updated property record. On a channel-connected property the change also queues to the channel sync outbox and propagates to connected channels asynchronously. An archived property must be restored in the dashboard before editing.

Send an Idempotency-Key header to make retries safe: a repeated PUT with the same key and the same payload returns the original record and applies nothing twice; the same key with a different payload fails with 409 idempotency_key_reused. A write that lands while a channel sync is still in progress fails with 409 sync_in_progress; retry once the sync completes.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Idempotency-KeystringOptional1 to 200 characters. Makes retries safe.
Path parameters
FieldTypeRequiredDescription
propertyIdstringRequiredPositive property database ID.
JSON body
FieldTypeRequiredDescription
namestringRequiredDisplay name, 2 to 100 characters.
timezonestringRequiredIANA time zone. Other read fields sent back on round-trip are ignored.
200 JSON response
FieldTypeRequiredDescription
dataPropertyRequiredThe requested property.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
data.idstringRequiredStable property ID.
data.codestringRequiredProperty code.
data.namestringRequiredDisplay name.
data.timezonestringRequiredIANA time zone.
data.status'active' | 'inactive'RequiredProperty status.
data.updatedAtstring (date-time)RequiredLast property change time.
data.inventoryobjectRequiredProperty inventory summary.
data.inventory.maxGuestsintegerRequiredMaximum occupancy across active room types.
data.inventory.physicalUnitsintegerRequiredNumber of active physical units.
data.inventory.strategiesstring[]RequiredInventory strategies used by active pools.
data.channelsstring[]RequiredActive channel names.
data.startingRateobject | nullRequiredLowest active starting rate, or null when no rate exists.
data.startingRate.amountMinorstringConditionalRequired when startingRate is an object. Amount in the currency minor unit.
data.startingRate.currencystringConditionalRequired when startingRate is an object. Three-letter currency code.

GET /properties/{propertyId}/rooms

Return one stable page of room types for one property, each with its physical units. Inactive records stay in the response with status inactive.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Path parameters
FieldTypeRequiredDescription
propertyIdstringRequiredPositive property database ID.
Query parameters
FieldTypeRequiredDescription
limitintegerOptionalRecords per page, from 1 through 200. The default is 100.
cursorstringOptionalSend meta.page.nextCursor without changing any other filter.
updated_afterstring (date-time)OptionalReturn records changed after this ISO 8601 date and time.
200 JSON response
FieldTypeRequiredDescription
dataRoomType[]RequiredA stable page of room type records, each with its physical units.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
meta.pageobjectRequiredCursor pagination state.
meta.page.hasMorebooleanRequiredWhether another page is available.
meta.page.limitintegerRequiredThe page size applied to this response.
meta.page.nextCursorstring | nullRequiredThe cursor for the next page, or null when the page is final.
meta.page.snapshotAtstring (date-time)RequiredThe stable read boundary shared by every page in the cursor chain.
data[].idstringRequiredStable room type ID.
data[].codestringRequiredRoom type code.
data[].namestringRequiredRoom type display name.
data[].status'active' | 'inactive'RequiredRoom type status.
data[].maxOccupancyintegerRequiredMaximum occupancy.
data[].bedroomsintegerRequiredBedroom count.
data[].bathroomsintegerRequiredBathroom count.
data[].updatedAtstring (date-time)RequiredLast room type or physical unit change time.
data[].unitsobject[]RequiredPhysical units of this room type.
data[].units[].idstringRequiredStable physical unit ID.
data[].units[].codestringRequiredPhysical unit code.
data[].units[].namestringRequiredPhysical unit display name.
data[].units[].floorstring | nullRequiredFloor label, or null.
data[].units[].status'active' | 'inactive'RequiredPhysical unit status.

GET /properties/{propertyId}/rate-plans

Return one stable page of rate plans for one property. This endpoint requires the rate-plans:read scope.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Path parameters
FieldTypeRequiredDescription
propertyIdstringRequiredPositive property database ID.
Query parameters
FieldTypeRequiredDescription
limitintegerOptionalRecords per page, from 1 through 200. The default is 100.
cursorstringOptionalSend meta.page.nextCursor without changing any other filter.
updated_afterstring (date-time)OptionalReturn records changed after this ISO 8601 date and time.
200 JSON response
FieldTypeRequiredDescription
dataRatePlan[]RequiredA stable page of rate plan records.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
meta.pageobjectRequiredCursor pagination state.
meta.page.hasMorebooleanRequiredWhether another page is available.
meta.page.limitintegerRequiredThe page size applied to this response.
meta.page.nextCursorstring | nullRequiredThe cursor for the next page, or null when the page is final.
meta.page.snapshotAtstring (date-time)RequiredThe stable read boundary shared by every page in the cursor chain.
data[].idstringRequiredStable rate plan ID.
data[].codestringRequiredRate plan code.
data[].namestringRequiredRate plan display name.
data[].status'active' | 'inactive'RequiredRate plan status.
data[].updatedAtstring (date-time)RequiredLast rate plan or inventory pool change time.
data[].inventoryPoolobjectRequiredInventory pool this rate plan prices.
data[].inventoryPool.idstringRequiredStable inventory pool ID.
data[].inventoryPool.codestringRequiredInventory pool code.
data[].inventoryPool.namestringRequiredInventory pool display name.
data[].inventoryPool.strategy'pooled' | 'fixed_unit' | 'entitlement'RequiredInventory strategy of the pool.
data[].inventoryPool.roomTypeIdstringRequiredRoom type the pool sells.
data[].baseRateobjectRequiredDefault nightly rate.
data[].baseRate.amountMinorstringRequiredAmount in the currency minor unit.
data[].baseRate.currencystringRequiredThree-letter currency code.
data[].includedOccupancyintegerRequiredGuests included in the base rate.
data[].extraGuestRateobjectRequiredNightly rate for each extra guest.
data[].extraGuestRate.amountMinorstringRequiredAmount in the currency minor unit.
data[].extraGuestRate.currencystringRequiredThree-letter currency code.

PUT /properties/{propertyId}/rate-plans

Create and update rate plans for one property. This endpoint requires the rate-plans:write scope. The body is an array of rate plan entries shaped like the read rows.

Each entry is an upsert keyed by id: an entry with an id replaces that plan’s fields — nights that inherit the base rate follow the new rate — and an entry without an id creates a plan under inventoryPool.id. Plans not mentioned stay untouched. Changes queue to the channel sync outbox and propagate to connected channels asynchronously.

Send an Idempotency-Key header to make retries safe: a repeated PUT with the same key and the same payload returns the original summary and applies nothing twice; the same key with a different payload fails with 409 idempotency_key_reused. A write that lands while a channel sync is still in progress fails with 409 sync_in_progress; retry once the sync completes.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Idempotency-KeystringOptional1 to 200 characters. Makes retries safe.
Path parameters
FieldTypeRequiredDescription
propertyIdstringRequiredPositive property database ID.
JSON body
FieldTypeRequiredDescription
ratePlans[].idstringOptionalRate plan ID to update. Omit to create a rate plan.
ratePlans[].codestringRequiredRate plan code, unique within its inventory pool. 2–40 letters, numbers, or hyphens.
ratePlans[].namestringRequiredRate plan display name, 2 to 100 characters.
ratePlans[].statusstringRequiredOnly active is writable. inactive is accepted on plans already inactive; archiving is not supported.
ratePlans[].inventoryPool.idstringConditionalInventory pool ID the plan prices. Required when creating; on update it must match the plan’s pool. Other read fields on inventoryPool are ignored.
ratePlans[].baseRateobjectRequiredamountMinor/currency pair for the default nightly rate. All rate plans on one property share one currency.
ratePlans[].includedOccupancyintegerRequiredGuests included in the base rate, 1 to 500.
ratePlans[].extraGuestRateobject | nullRequiredamountMinor/currency pair for each extra guest, or null for no extra-guest rate.
200 JSON response
FieldTypeRequiredDescription
dataRatePlansWriteResultRequiredThe applied rate-plans write summary.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
data.propertyIdstringRequiredProperty the rate-plans write applied to.
data.plansWrittenintegerRequiredRate plan entries applied by the write.

GET /properties/{propertyId}/calendar

Return per-day availability, lowest rate, and minimum stay for every active inventory pool of one property. This endpoint requires the calendar:read scope. The range spans at most 92 days and defaults to the next 31 days in the property time zone. Dates accept years 1 through 9999. The response is limited to 2000 rows (dates × active pools); larger requests fail with calendar_result_too_large, so narrow the range or pass pool_id.

availableUnits subtracts reservations and availability blocks from the sellable count and is 0 on closed dates. rate and minStay come from the lowest-priced sellable rate plan; both are null when no active plan sells the date, and stopSell is true when every active plan is stop-sold.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Path parameters
FieldTypeRequiredDescription
propertyIdstringRequiredPositive property database ID.
Query parameters
FieldTypeRequiredDescription
fromstring (date)OptionalFirst stay date, inclusive. The default is today in the property time zone.
tostring (date)OptionalLast stay date, inclusive. The default is 30 days after from; the range can span at most 92 days.
pool_idstringOptionalReturn rows for one inventory pool ID.
200 JSON response
FieldTypeRequiredDescription
dataCalendarDay[]RequiredOne row per active inventory pool per stay date in the range.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
data[].datestring (date)RequiredStay date in YYYY-MM-DD format.
data[].inventoryPoolobjectRequiredInventory pool this row describes.
data[].inventoryPool.idstringRequiredStable inventory pool ID.
data[].inventoryPool.codestringRequiredInventory pool code.
data[].inventoryPool.namestringRequiredInventory pool display name.
data[].inventoryPool.strategy'pooled' | 'fixed_unit' | 'entitlement'RequiredInventory strategy of the pool.
data[].inventoryPool.roomTypeIdstringRequiredRoom type the pool sells.
data[].availableUnitsintegerRequiredUnits left after reservations and blocks; 0 when the pool is closed.
data[].closedbooleanRequiredWhether the pool is closed on this date.
data[].stopSellbooleanRequiredWhether every active rate plan is stop-sold on this date.
data[].rateobject | nullRequiredLowest nightly rate across sellable active rate plans, or null when none sells.
data[].rate.amountMinorstringConditionalRequired when rate is an object. Amount in the currency minor unit.
data[].rate.currencystringConditionalRequired when rate is an object. Three-letter currency code.
data[].minStayinteger | nullRequiredMinimum stay of the lowest sellable rate plan, or null when no rate exists.

PUT /properties/{propertyId}/calendar

Bulk-update per-day availability, rates, and restrictions for one property. This endpoint requires the calendar:write scope. The body is an array of day entries shaped like the read rows.

Each entry is an upsert: days not mentioned stay untouched, and a null rate or minStay leaves the stored value unchanged. Without ratePlanId an entry writes every active rate plan on the pool; with it, only that plan’s nightly state changes. Entries for the same pool and date may target different rate plans, but their pool-level fields (availableUnits, closed) must agree, and a pool-level entry cannot share a date with targeted entries. availableUnits is the target availability — reservations and blocks are added back when the sellable count is stored. A request can form at most 90 disjoint date ranges in total; batch genuinely sparse updates into multiple requests. Changes queue to the channel sync outbox and propagate to connected channels asynchronously.

Send an Idempotency-Key header to make retries safe: a repeated PUT with the same key and the same payload returns the original summary and applies nothing twice; the same key with a different payload fails with 409 idempotency_key_reused.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Idempotency-KeystringOptional1 to 200 characters. Makes retries safe.
Path parameters
FieldTypeRequiredDescription
propertyIdstringRequiredPositive property database ID.
JSON body
FieldTypeRequiredDescription
days[].datestring (date)RequiredStay date in YYYY-MM-DD format.
days[].inventoryPool.idstringRequiredInventory pool ID this entry writes. Other read fields on inventoryPool are ignored.
days[].ratePlanIdstringOptionalActive rate plan ID on the pool to write. Omit to write every active rate plan on the pool. Entries sharing a pool and date must target different plans with matching pool-level fields.
days[].availableUnitsintegerRequiredTarget available units after reservations and blocks.
days[].closedbooleanRequiredWhether the pool is closed on this date.
days[].stopSellbooleanRequiredWhether active rate plans stop selling this date.
days[].rateobject | nullRequiredamountMinor/currency pair — the amount must be positive — or null to leave the stored rate unchanged.
days[].minStayinteger | nullRequiredMinimum stay, or null to leave the stored value unchanged.
200 JSON response
FieldTypeRequiredDescription
dataCalendarWriteResultRequiredThe applied calendar write summary.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
data.propertyIdstringRequiredProperty the calendar write applied to.
data.daysAppliedintegerRequiredPer-day entries applied by the write.

Reservations

Reservation endpoints require the reservations:read scope. Required response fields are always present; nullable fields include null in their type.

items lists the booked room lines of the reservation. Line totals are the booked amounts in the currency the nights were priced under; an item cancelled before booked totals were recorded returns total null.

Money uses amountMinor strings and 3-letter currency codes. This format prevents floating-point errors.

GET /reservations

Return one stable page of reservations.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Query parameters
FieldTypeRequiredDescription
limitintegerOptionalRecords per page, from 1 through 200. The default is 100.
cursorstringOptionalSend meta.page.nextCursor without changing any other filter.
updated_afterstring (date-time)OptionalReturn records changed after this ISO 8601 date and time.
property_idstringOptionalReturn reservations for one property ID.
arrival_fromstring (date)OptionalReturn arrivals on or after this YYYY-MM-DD date.
arrival_tostring (date)OptionalReturn arrivals on or before this YYYY-MM-DD date.
200 JSON response
FieldTypeRequiredDescription
dataReservation[]RequiredA stable page of reservation records.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
meta.pageobjectRequiredCursor pagination state.
meta.page.hasMorebooleanRequiredWhether another page is available.
meta.page.limitintegerRequiredThe page size applied to this response.
meta.page.nextCursorstring | nullRequiredThe cursor for the next page, or null when the page is final.
meta.page.snapshotAtstring (date-time)RequiredThe stable read boundary shared by every page in the cursor chain.
data[].idstringRequiredStable reservation ID.
data[].confirmationCodestringRequiredGuest-facing confirmation code.
data[].status'pending' | 'confirmed' | 'in_house' | 'completed' | 'cancelled'RequiredReservation lifecycle status.
data[].updatedAtstring (date-time)RequiredLast reservation change time.
data[].guestobjectRequiredGuest contact summary.
data[].guest.namestringRequiredGuest name.
data[].guest.emailstring | nullRequiredGuest email address, or null.
data[].guest.phonestring | nullRequiredGuest phone number, or null.
data[].propertyobjectRequiredReserved property summary.
data[].property.idstringRequiredProperty ID.
data[].property.namestringRequiredProperty name.
data[].stayobjectRequiredStay dates and length.
data[].stay.arrivalDatestring (date)RequiredArrival date in YYYY-MM-DD format.
data[].stay.departureDatestring (date)RequiredDeparture date in YYYY-MM-DD format.
data[].stay.nightsintegerRequiredNumber of nights.
data[].occupancyobjectRequiredGuest and room counts.
data[].occupancy.adultsintegerRequiredAdult count.
data[].occupancy.childrenintegerRequiredChild count.
data[].occupancy.roomsintegerRequiredBooked room quantity.
data[].totalobjectRequiredReservation total.
data[].total.amountMinorstringRequiredAmount in the currency minor unit.
data[].total.currencystringRequiredThree-letter currency code.
data[].sourceobjectRequiredReservation origin.
data[].source.type'direct' | 'channel'RequiredWhether the reservation was direct or arrived from a channel.
data[].source.channelstringConditionalRequired when source.type is channel.
data[].itemsobject[]RequiredBooked room lines with per-line totals from their nightly rates.
data[].items[].idstringRequiredStable reservation item ID.
data[].items[].status'pending' | 'confirmed' | 'cancelled'RequiredItem lifecycle status.
data[].items[].checkInDatestring (date)RequiredCheck-in date in YYYY-MM-DD format.
data[].items[].checkOutDatestring (date)RequiredCheck-out date in YYYY-MM-DD format.
data[].items[].nightsintegerRequiredNumber of nights.
data[].items[].quantityintegerRequiredBooked room quantity.
data[].items[].adultsintegerRequiredAdult count.
data[].items[].childrenintegerRequiredChild count.
data[].items[].inventoryPoolIdstringRequiredInventory pool the item books.
data[].items[].ratePlanIdstringRequiredRate plan the item is priced with.
data[].items[].totalobject | nullRequiredBooked item total in the currency the nights were priced under; null only for items cancelled before booked totals were recorded.
data[].items[].total.amountMinorstringConditionalRequired when total is an object. Amount in the currency minor unit.
data[].items[].total.currencystringConditionalRequired when total is an object. Three-letter currency code.

GET /reservations/{reservationId}

Return one reservation from the API key workspace.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Path parameters
FieldTypeRequiredDescription
reservationIdstringRequiredPositive reservation database ID.
200 JSON response
FieldTypeRequiredDescription
dataReservationRequiredThe requested reservation.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
data.idstringRequiredStable reservation ID.
data.confirmationCodestringRequiredGuest-facing confirmation code.
data.status'pending' | 'confirmed' | 'in_house' | 'completed' | 'cancelled'RequiredReservation lifecycle status.
data.updatedAtstring (date-time)RequiredLast reservation change time.
data.guestobjectRequiredGuest contact summary.
data.guest.namestringRequiredGuest name.
data.guest.emailstring | nullRequiredGuest email address, or null.
data.guest.phonestring | nullRequiredGuest phone number, or null.
data.propertyobjectRequiredReserved property summary.
data.property.idstringRequiredProperty ID.
data.property.namestringRequiredProperty name.
data.stayobjectRequiredStay dates and length.
data.stay.arrivalDatestring (date)RequiredArrival date in YYYY-MM-DD format.
data.stay.departureDatestring (date)RequiredDeparture date in YYYY-MM-DD format.
data.stay.nightsintegerRequiredNumber of nights.
data.occupancyobjectRequiredGuest and room counts.
data.occupancy.adultsintegerRequiredAdult count.
data.occupancy.childrenintegerRequiredChild count.
data.occupancy.roomsintegerRequiredBooked room quantity.
data.totalobjectRequiredReservation total.
data.total.amountMinorstringRequiredAmount in the currency minor unit.
data.total.currencystringRequiredThree-letter currency code.
data.sourceobjectRequiredReservation origin.
data.source.type'direct' | 'channel'RequiredWhether the reservation was direct or arrived from a channel.
data.source.channelstringConditionalRequired when source.type is channel.
data.itemsobject[]RequiredBooked room lines with per-line totals from their nightly rates.
data.items[].idstringRequiredStable reservation item ID.
data.items[].status'pending' | 'confirmed' | 'cancelled'RequiredItem lifecycle status.
data.items[].checkInDatestring (date)RequiredCheck-in date in YYYY-MM-DD format.
data.items[].checkOutDatestring (date)RequiredCheck-out date in YYYY-MM-DD format.
data.items[].nightsintegerRequiredNumber of nights.
data.items[].quantityintegerRequiredBooked room quantity.
data.items[].adultsintegerRequiredAdult count.
data.items[].childrenintegerRequiredChild count.
data.items[].inventoryPoolIdstringRequiredInventory pool the item books.
data.items[].ratePlanIdstringRequiredRate plan the item is priced with.
data.items[].totalobject | nullRequiredBooked item total in the currency the nights were priced under; null only for items cancelled before booked totals were recorded.
data.items[].total.amountMinorstringConditionalRequired when total is an object. Amount in the currency minor unit.
data.items[].total.currencystringConditionalRequired when total is an object. Three-letter currency code.

POST /reservations

Create one direct reservation. This endpoint requires the reservations:write scope. The body mirrors the read row: guest, stay, occupancy, and one items line with the ratePlanId to book.

The rate plan, its inventory pool, and the property must be active, and a channel-mapped (OTA) rate plan cannot take a direct booking. The total prices from the plan’s base rate for every night. Inventory allocates inside the same transaction and the availability change queues to the channel sync outbox asynchronously. Owner (entitlement) inventory cannot be booked through this endpoint.

Capacity failures return 400 insufficient_inventory. Send an Idempotency-Key header to make retries safe: a repeated POST with the same key and the same payload returns the original reservation instead of booking twice; the same key with a different payload fails with 409 idempotency_key_reused.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Idempotency-KeystringOptional1 to 200 characters. Makes retries safe.
JSON body
FieldTypeRequiredDescription
guest.namestringRequiredGuest name, 2 to 120 characters.
guest.emailstring | nullRequiredGuest email address, or null.
stay.arrivalDatestring (date)RequiredArrival date in YYYY-MM-DD format.
stay.departureDatestring (date)RequiredDeparture date in YYYY-MM-DD format, 1 to 365 nights after arrival.
occupancy.adultsintegerRequiredAdult count, 1 to 500. Adults plus children must fit the room capacity.
occupancy.childrenintegerRequiredChild count, 0 to 500.
occupancy.roomsintegerRequiredBooked room quantity, 1 to 100.
items[].ratePlanIdstringRequiredRate plan the line books. Exactly one line; other read fields on items are ignored.
201 JSON response
FieldTypeRequiredDescription
dataReservationRequiredThe stored reservation after the write.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
data.idstringRequiredStable reservation ID.
data.confirmationCodestringRequiredGuest-facing confirmation code.
data.status'pending' | 'confirmed' | 'in_house' | 'completed' | 'cancelled'RequiredReservation lifecycle status.
data.updatedAtstring (date-time)RequiredLast reservation change time.
data.guestobjectRequiredGuest contact summary.
data.guest.namestringRequiredGuest name.
data.guest.emailstring | nullRequiredGuest email address, or null.
data.guest.phonestring | nullRequiredGuest phone number, or null.
data.propertyobjectRequiredReserved property summary.
data.property.idstringRequiredProperty ID.
data.property.namestringRequiredProperty name.
data.stayobjectRequiredStay dates and length.
data.stay.arrivalDatestring (date)RequiredArrival date in YYYY-MM-DD format.
data.stay.departureDatestring (date)RequiredDeparture date in YYYY-MM-DD format.
data.stay.nightsintegerRequiredNumber of nights.
data.occupancyobjectRequiredGuest and room counts.
data.occupancy.adultsintegerRequiredAdult count.
data.occupancy.childrenintegerRequiredChild count.
data.occupancy.roomsintegerRequiredBooked room quantity.
data.totalobjectRequiredReservation total.
data.total.amountMinorstringRequiredAmount in the currency minor unit.
data.total.currencystringRequiredThree-letter currency code.
data.sourceobjectRequiredReservation origin.
data.source.type'direct' | 'channel'RequiredWhether the reservation was direct or arrived from a channel.
data.source.channelstringConditionalRequired when source.type is channel.
data.itemsobject[]RequiredBooked room lines with per-line totals from their nightly rates.
data.items[].idstringRequiredStable reservation item ID.
data.items[].status'pending' | 'confirmed' | 'cancelled'RequiredItem lifecycle status.
data.items[].checkInDatestring (date)RequiredCheck-in date in YYYY-MM-DD format.
data.items[].checkOutDatestring (date)RequiredCheck-out date in YYYY-MM-DD format.
data.items[].nightsintegerRequiredNumber of nights.
data.items[].quantityintegerRequiredBooked room quantity.
data.items[].adultsintegerRequiredAdult count.
data.items[].childrenintegerRequiredChild count.
data.items[].inventoryPoolIdstringRequiredInventory pool the item books.
data.items[].ratePlanIdstringRequiredRate plan the item is priced with.
data.items[].totalobject | nullRequiredBooked item total in the currency the nights were priced under; null only for items cancelled before booked totals were recorded.
data.items[].total.amountMinorstringConditionalRequired when total is an object. Amount in the currency minor unit.
data.items[].total.currencystringConditionalRequired when total is an object. Three-letter currency code.

PUT /reservations/{reservationId}

Replace the writable fields of one direct reservation. This endpoint requires the reservations:write scope. The body is the same shape as the create body; the stored allocation moves to the new dates, rate plan, and room quantity, and the total reprices.

Channel reservations must be changed in the connected channel (400 channel_managed). Cancelled, started, or completed reservations cannot be changed, and reservations with assigned units or multiple item records need the dashboard.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Idempotency-KeystringOptional1 to 200 characters. Makes retries safe.
Path parameters
FieldTypeRequiredDescription
reservationIdstringRequiredPositive reservation database ID.
JSON body
FieldTypeRequiredDescription
guest.namestringRequiredGuest name, 2 to 120 characters.
guest.emailstring | nullRequiredGuest email address, or null.
stay.arrivalDatestring (date)RequiredArrival date in YYYY-MM-DD format.
stay.departureDatestring (date)RequiredDeparture date in YYYY-MM-DD format, 1 to 365 nights after arrival.
occupancy.adultsintegerRequiredAdult count, 1 to 500. Adults plus children must fit the room capacity.
occupancy.childrenintegerRequiredChild count, 0 to 500.
occupancy.roomsintegerRequiredBooked room quantity, 1 to 100.
items[].ratePlanIdstringRequiredRate plan the line books. Exactly one line; other read fields on items are ignored.
200 JSON response
FieldTypeRequiredDescription
dataReservationRequiredThe stored reservation after the write.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
data.idstringRequiredStable reservation ID.
data.confirmationCodestringRequiredGuest-facing confirmation code.
data.status'pending' | 'confirmed' | 'in_house' | 'completed' | 'cancelled'RequiredReservation lifecycle status.
data.updatedAtstring (date-time)RequiredLast reservation change time.
data.guestobjectRequiredGuest contact summary.
data.guest.namestringRequiredGuest name.
data.guest.emailstring | nullRequiredGuest email address, or null.
data.guest.phonestring | nullRequiredGuest phone number, or null.
data.propertyobjectRequiredReserved property summary.
data.property.idstringRequiredProperty ID.
data.property.namestringRequiredProperty name.
data.stayobjectRequiredStay dates and length.
data.stay.arrivalDatestring (date)RequiredArrival date in YYYY-MM-DD format.
data.stay.departureDatestring (date)RequiredDeparture date in YYYY-MM-DD format.
data.stay.nightsintegerRequiredNumber of nights.
data.occupancyobjectRequiredGuest and room counts.
data.occupancy.adultsintegerRequiredAdult count.
data.occupancy.childrenintegerRequiredChild count.
data.occupancy.roomsintegerRequiredBooked room quantity.
data.totalobjectRequiredReservation total.
data.total.amountMinorstringRequiredAmount in the currency minor unit.
data.total.currencystringRequiredThree-letter currency code.
data.sourceobjectRequiredReservation origin.
data.source.type'direct' | 'channel'RequiredWhether the reservation was direct or arrived from a channel.
data.source.channelstringConditionalRequired when source.type is channel.
data.itemsobject[]RequiredBooked room lines with per-line totals from their nightly rates.
data.items[].idstringRequiredStable reservation item ID.
data.items[].status'pending' | 'confirmed' | 'cancelled'RequiredItem lifecycle status.
data.items[].checkInDatestring (date)RequiredCheck-in date in YYYY-MM-DD format.
data.items[].checkOutDatestring (date)RequiredCheck-out date in YYYY-MM-DD format.
data.items[].nightsintegerRequiredNumber of nights.
data.items[].quantityintegerRequiredBooked room quantity.
data.items[].adultsintegerRequiredAdult count.
data.items[].childrenintegerRequiredChild count.
data.items[].inventoryPoolIdstringRequiredInventory pool the item books.
data.items[].ratePlanIdstringRequiredRate plan the item is priced with.
data.items[].totalobject | nullRequiredBooked item total in the currency the nights were priced under; null only for items cancelled before booked totals were recorded.
data.items[].total.amountMinorstringConditionalRequired when total is an object. Amount in the currency minor unit.
data.items[].total.currencystringConditionalRequired when total is an object. Three-letter currency code.

POST /reservations/{reservationId}/cancel

Cancel one direct reservation and release its inventory. This endpoint requires the reservations:write scope. Cancelling an already cancelled reservation succeeds without changing anything.

Channel reservations must be cancelled in the connected channel (400 channel_managed), and completed reservations cannot be cancelled (400 reservation_completed). The release queues to the channel sync outbox asynchronously.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Idempotency-KeystringOptional1 to 200 characters. Makes retries safe.
Path parameters
FieldTypeRequiredDescription
reservationIdstringRequiredPositive reservation database ID.
200 JSON response
FieldTypeRequiredDescription
dataReservationRequiredThe stored reservation after the write.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
data.idstringRequiredStable reservation ID.
data.confirmationCodestringRequiredGuest-facing confirmation code.
data.status'pending' | 'confirmed' | 'in_house' | 'completed' | 'cancelled'RequiredReservation lifecycle status.
data.updatedAtstring (date-time)RequiredLast reservation change time.
data.guestobjectRequiredGuest contact summary.
data.guest.namestringRequiredGuest name.
data.guest.emailstring | nullRequiredGuest email address, or null.
data.guest.phonestring | nullRequiredGuest phone number, or null.
data.propertyobjectRequiredReserved property summary.
data.property.idstringRequiredProperty ID.
data.property.namestringRequiredProperty name.
data.stayobjectRequiredStay dates and length.
data.stay.arrivalDatestring (date)RequiredArrival date in YYYY-MM-DD format.
data.stay.departureDatestring (date)RequiredDeparture date in YYYY-MM-DD format.
data.stay.nightsintegerRequiredNumber of nights.
data.occupancyobjectRequiredGuest and room counts.
data.occupancy.adultsintegerRequiredAdult count.
data.occupancy.childrenintegerRequiredChild count.
data.occupancy.roomsintegerRequiredBooked room quantity.
data.totalobjectRequiredReservation total.
data.total.amountMinorstringRequiredAmount in the currency minor unit.
data.total.currencystringRequiredThree-letter currency code.
data.sourceobjectRequiredReservation origin.
data.source.type'direct' | 'channel'RequiredWhether the reservation was direct or arrived from a channel.
data.source.channelstringConditionalRequired when source.type is channel.
data.itemsobject[]RequiredBooked room lines with per-line totals from their nightly rates.
data.items[].idstringRequiredStable reservation item ID.
data.items[].status'pending' | 'confirmed' | 'cancelled'RequiredItem lifecycle status.
data.items[].checkInDatestring (date)RequiredCheck-in date in YYYY-MM-DD format.
data.items[].checkOutDatestring (date)RequiredCheck-out date in YYYY-MM-DD format.
data.items[].nightsintegerRequiredNumber of nights.
data.items[].quantityintegerRequiredBooked room quantity.
data.items[].adultsintegerRequiredAdult count.
data.items[].childrenintegerRequiredChild count.
data.items[].inventoryPoolIdstringRequiredInventory pool the item books.
data.items[].ratePlanIdstringRequiredRate plan the item is priced with.
data.items[].totalobject | nullRequiredBooked item total in the currency the nights were priced under; null only for items cancelled before booked totals were recorded.
data.items[].total.amountMinorstringConditionalRequired when total is an object. Amount in the currency minor unit.
data.items[].total.currencystringConditionalRequired when total is an object. Three-letter currency code.

Tasks

Read endpoints require the tasks:read scope; write endpoints require tasks:write. Required response fields are always present; nullable fields include null in their type.

Tasks embed stable IDs only, so list pages never go stale when a name changes: resolve property names through GET /properties. Tasks without a property link return property and reservationId as null. Tasks without an assignee return assignee as null.

Test keys cannot create or update tasks. Writes with a test key return sandbox_read_only.

GET /tasks

Return one stable page of tasks.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Query parameters
FieldTypeRequiredDescription
limitintegerOptionalRecords per page, from 1 through 200. The default is 100.
cursorstringOptionalSend meta.page.nextCursor without changing any other filter.
updated_afterstring (date-time)OptionalReturn records changed after this ISO 8601 date and time.
status'open' | 'in_progress' | 'completed' | 'cancelled' | 'all'OptionalFilter by task status. The default is all.
property_idstringOptionalReturn tasks for one property ID.
200 JSON response
FieldTypeRequiredDescription
dataTask[]RequiredA stable page of task records.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
meta.pageobjectRequiredCursor pagination state.
meta.page.hasMorebooleanRequiredWhether another page is available.
meta.page.limitintegerRequiredThe page size applied to this response.
meta.page.nextCursorstring | nullRequiredThe cursor for the next page, or null when the page is final.
meta.page.snapshotAtstring (date-time)RequiredThe stable read boundary shared by every page in the cursor chain.
data[].idstringRequiredStable task ID.
data[].titlestringRequiredTask title.
data[].descriptionstring | nullRequiredTask description, or null.
data[].category'cleaning' | 'maintenance' | 'guest' | 'inspection' | 'listing' | 'operations'RequiredTask category.
data[].priority'low' | 'normal' | 'high' | 'urgent'RequiredTask priority.
data[].status'open' | 'in_progress' | 'completed' | 'cancelled'RequiredTask status.
data[].source'manual' | 'automation'RequiredWhether the task was created manually or by an automation rule.
data[].dueAtstring (date-time) | nullRequiredWhen the task is due, or null.
data[].propertyobject | nullRequiredLinked property, or null. Resolve names via the properties endpoint.
data[].property.idstringConditionalRequired when property is an object. Property ID.
data[].reservationIdstring | nullRequiredLinked reservation ID, or null.
data[].assigneeobject | nullRequiredAssigned workspace member, or null.
data[].assignee.idstringConditionalRequired when assignee is an object. Workspace member user ID.
data[].createdAtstring (date-time)RequiredTask creation time.
data[].updatedAtstring (date-time)RequiredLast task change time.

POST /tasks

Create a task. Send an Idempotency-Key header to make retries safe: a repeated POST with the same key and the same payload returns 200 with the original task and creates nothing new; the same key with a different payload fails with 409 idempotency_key_reused.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Idempotency-KeystringOptional1 to 200 characters. Makes create retries safe.
JSON body
FieldTypeRequiredDescription
titlestringRequiredTask title, 2 to 200 characters.
category'cleaning' | 'maintenance' | 'guest' | 'inspection' | 'listing' | 'operations'RequiredTask category.
priority'low' | 'normal' | 'high' | 'urgent'RequiredTask priority.
descriptionstring | nullOptionalTask description, up to 2,000 characters.
dueAtstring (date-time) | nullOptionalWhen the task is due; a time-zone offset is allowed.
propertyIdstring | nullOptionalPositive property database ID.
reservationIdstring | nullOptionalPositive reservation database ID. Requires propertyId.
assigneeUserIdstring | nullOptionalAssigned workspace member user ID, 1 to 255 characters.
201 JSON response
FieldTypeRequiredDescription
dataTaskRequiredThe created task.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
data.idstringRequiredStable task ID.
data.titlestringRequiredTask title.
data.descriptionstring | nullRequiredTask description, or null.
data.category'cleaning' | 'maintenance' | 'guest' | 'inspection' | 'listing' | 'operations'RequiredTask category.
data.priority'low' | 'normal' | 'high' | 'urgent'RequiredTask priority.
data.status'open' | 'in_progress' | 'completed' | 'cancelled'RequiredTask status.
data.source'manual' | 'automation'RequiredWhether the task was created manually or by an automation rule.
data.dueAtstring (date-time) | nullRequiredWhen the task is due, or null.
data.propertyobject | nullRequiredLinked property, or null. Resolve names via the properties endpoint.
data.property.idstringConditionalRequired when property is an object. Property ID.
data.reservationIdstring | nullRequiredLinked reservation ID, or null.
data.assigneeobject | nullRequiredAssigned workspace member, or null.
data.assignee.idstringConditionalRequired when assignee is an object. Workspace member user ID.
data.createdAtstring (date-time)RequiredTask creation time.
data.updatedAtstring (date-time)RequiredLast task change time.

GET /tasks/{taskId}

Return one task from the API key workspace.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Path parameters
FieldTypeRequiredDescription
taskIdstringRequiredPositive task database ID.
200 JSON response
FieldTypeRequiredDescription
dataTaskRequiredThe requested task.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
data.idstringRequiredStable task ID.
data.titlestringRequiredTask title.
data.descriptionstring | nullRequiredTask description, or null.
data.category'cleaning' | 'maintenance' | 'guest' | 'inspection' | 'listing' | 'operations'RequiredTask category.
data.priority'low' | 'normal' | 'high' | 'urgent'RequiredTask priority.
data.status'open' | 'in_progress' | 'completed' | 'cancelled'RequiredTask status.
data.source'manual' | 'automation'RequiredWhether the task was created manually or by an automation rule.
data.dueAtstring (date-time) | nullRequiredWhen the task is due, or null.
data.propertyobject | nullRequiredLinked property, or null. Resolve names via the properties endpoint.
data.property.idstringConditionalRequired when property is an object. Property ID.
data.reservationIdstring | nullRequiredLinked reservation ID, or null.
data.assigneeobject | nullRequiredAssigned workspace member, or null.
data.assignee.idstringConditionalRequired when assignee is an object. Workspace member user ID.
data.createdAtstring (date-time)RequiredTask creation time.
data.updatedAtstring (date-time)RequiredLast task change time.

PUT /tasks/{taskId}

Replace one task. PUT is a full replacement: an omitted status resets the task to open.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Path parameters
FieldTypeRequiredDescription
taskIdstringRequiredPositive task database ID.
JSON body
FieldTypeRequiredDescription
titlestringRequiredTask title, 2 to 200 characters.
category'cleaning' | 'maintenance' | 'guest' | 'inspection' | 'listing' | 'operations'RequiredTask category.
priority'low' | 'normal' | 'high' | 'urgent'RequiredTask priority.
descriptionstring | nullOptionalTask description, up to 2,000 characters.
dueAtstring (date-time) | nullOptionalWhen the task is due; a time-zone offset is allowed.
propertyIdstring | nullOptionalPositive property database ID.
reservationIdstring | nullOptionalPositive reservation database ID. Requires propertyId.
assigneeUserIdstring | nullOptionalAssigned workspace member user ID, 1 to 255 characters.
status'open' | 'in_progress' | 'completed' | 'cancelled'OptionalFull replacement: the default is open.
200 JSON response
FieldTypeRequiredDescription
dataTaskRequiredThe requested task.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
data.idstringRequiredStable task ID.
data.titlestringRequiredTask title.
data.descriptionstring | nullRequiredTask description, or null.
data.category'cleaning' | 'maintenance' | 'guest' | 'inspection' | 'listing' | 'operations'RequiredTask category.
data.priority'low' | 'normal' | 'high' | 'urgent'RequiredTask priority.
data.status'open' | 'in_progress' | 'completed' | 'cancelled'RequiredTask status.
data.source'manual' | 'automation'RequiredWhether the task was created manually or by an automation rule.
data.dueAtstring (date-time) | nullRequiredWhen the task is due, or null.
data.propertyobject | nullRequiredLinked property, or null. Resolve names via the properties endpoint.
data.property.idstringConditionalRequired when property is an object. Property ID.
data.reservationIdstring | nullRequiredLinked reservation ID, or null.
data.assigneeobject | nullRequiredAssigned workspace member, or null.
data.assignee.idstringConditionalRequired when assignee is an object. Workspace member user ID.
data.createdAtstring (date-time)RequiredTask creation time.
data.updatedAtstring (date-time)RequiredLast task change time.

Conversations

Read endpoints require the conversations:read scope; replies require conversations:write. channel names the sales channel (airbnb, vrbo, direct, or other); internal channel manager identifiers are never exposed.

Test keys cannot send replies. Writes with a test key return sandbox_read_only.

GET /conversations

Return one stable page of conversations, newest activity first.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Query parameters
FieldTypeRequiredDescription
limitintegerOptionalRecords per page, from 1 through 200. The default is 100.
cursorstringOptionalSend meta.page.nextCursor without changing any other filter.
updated_afterstring (date-time)OptionalReturn records changed after this ISO 8601 date and time.
status'open' | 'closed' | 'all'OptionalFilter by conversation status. The default is all.
property_idstringOptionalReturn conversations for one property ID.
200 JSON response
FieldTypeRequiredDescription
dataConversation[]RequiredA stable page of conversation records, newest activity first.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
meta.pageobjectRequiredCursor pagination state.
meta.page.hasMorebooleanRequiredWhether another page is available.
meta.page.limitintegerRequiredThe page size applied to this response.
meta.page.nextCursorstring | nullRequiredThe cursor for the next page, or null when the page is final.
meta.page.snapshotAtstring (date-time)RequiredThe stable read boundary shared by every page in the cursor chain.
data[].idstringRequiredStable conversation ID.
data[].guestNamestringRequiredGuest name on the thread.
data[].subjectstring | nullRequiredThread subject, or null.
data[].status'open' | 'closed'RequiredThread status.
data[].channel'airbnb' | 'vrbo' | 'direct' | 'other'RequiredSales channel the thread runs on.
data[].propertyobjectRequiredProperty the thread belongs to.
data[].property.idstringRequiredProperty ID.
data[].property.namestringRequiredProperty name.
data[].reservationIdstring | nullRequiredLinked reservation ID, or null.
data[].lastMessageAtstring (date-time)RequiredLast message time.
data[].lastMessageobjectRequiredLast message summary.
data[].lastMessage.direction'inbound' | 'outbound'RequiredDirection of the last message.
data[].lastMessage.snippetstringRequiredBody of the last message.
data[].updatedAtstring (date-time)RequiredLast conversation change time.

GET /conversations/{conversationId}/messages

Return one stable page of messages in chronological order.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Path parameters
FieldTypeRequiredDescription
conversationIdstringRequiredPositive conversation database ID.
Query parameters
FieldTypeRequiredDescription
limitintegerOptionalRecords per page, from 1 through 200. The default is 100.
cursorstringOptionalSend meta.page.nextCursor without changing any other filter.
200 JSON response
FieldTypeRequiredDescription
dataMessage[]RequiredA stable page of messages in chronological order.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
meta.pageobjectRequiredCursor pagination state.
meta.page.hasMorebooleanRequiredWhether another page is available.
meta.page.limitintegerRequiredThe page size applied to this response.
meta.page.nextCursorstring | nullRequiredThe cursor for the next page, or null when the page is final.
meta.page.snapshotAtstring (date-time)RequiredThe stable read boundary shared by every page in the cursor chain.
data[].idstringRequiredStable message ID.
data[].direction'inbound' | 'outbound'RequiredMessage direction.
data[].senderType'guest' | 'staff' | 'system'RequiredWho sent the message.
data[].senderNamestring | nullRequiredStaff sender name, or null.
data[].bodystringRequiredMessage body.
data[].occurredAtstring (date-time)RequiredWhen the message was sent.

POST /conversations/{conversationId}/messages

Queue a reply for delivery through the channel connection. The 201 response returns the stored message. Replying fails with replies_not_supported when the connection cannot send messages, and with conversation_closed when the thread is closed.

Send an Idempotency-Key header to make retries safe: a repeated POST with the same key and the same payload returns 200 with the original message and queues nothing new; the same key with a different payload fails with 409 idempotency_key_reused.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Idempotency-KeystringOptional1 to 200 characters. Makes create retries safe.
Path parameters
FieldTypeRequiredDescription
conversationIdstringRequiredPositive conversation database ID.
JSON body
FieldTypeRequiredDescription
bodystringRequiredReply body, 1 to 10,000 characters.
201 JSON response
FieldTypeRequiredDescription
dataMessageRequiredThe queued reply.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
data.idstringRequiredStable message ID.
data.direction'inbound' | 'outbound'RequiredMessage direction.
data.senderType'guest' | 'staff' | 'system'RequiredWho sent the message.
data.senderNamestring | nullRequiredStaff sender name, or null.
data.bodystringRequiredMessage body.
data.occurredAtstring (date-time)RequiredWhen the message was sent.

Channels

Channel endpoints require the channels:read scope. Each connection carries its rate plan mappings; a mapping with null external codes is not linked on the sales channel yet.

Connection credentials are never returned. channelActive reports whether the connection is live on the sales channel, and syncState shows a queued or failed channel manager sync.

GET /channels

Return one stable page of channel connections.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Query parameters
FieldTypeRequiredDescription
limitintegerOptionalRecords per page, from 1 through 200. The default is 100.
cursorstringOptionalSend meta.page.nextCursor without changing any other filter.
updated_afterstring (date-time)OptionalReturn records changed after this ISO 8601 date and time.
property_idstringOptionalReturn channel connections for one property ID.
200 JSON response
FieldTypeRequiredDescription
dataChannelConnection[]RequiredA stable page of channel connection records.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
meta.pageobjectRequiredCursor pagination state.
meta.page.hasMorebooleanRequiredWhether another page is available.
meta.page.limitintegerRequiredThe page size applied to this response.
meta.page.nextCursorstring | nullRequiredThe cursor for the next page, or null when the page is final.
meta.page.snapshotAtstring (date-time)RequiredThe stable read boundary shared by every page in the cursor chain.
data[].idstringRequiredStable channel connection ID.
data[].titlestringRequiredConnection display name.
data[].channelstringRequiredSales channel this connection distributes through, or other.
data[].status'draft' | 'pending' | 'active' | 'error'RequiredConnection status.
data[].channelActivebooleanRequiredWhether the connection is live on the sales channel.
data[].syncState'pending' | 'failed'RequiredPending channel manager sync state, or null when nothing is queued.
data[].currencystring | nullRequiredRate currency override, or null.
data[].propertyobjectRequiredProperty this connection distributes.
data[].property.idstringRequiredProperty ID.
data[].property.namestringRequiredProperty name.
data[].mappingsobject[]RequiredRate plan mappings for this connection.
data[].mappings[].idstringRequiredStable channel mapping ID.
data[].mappings[].ratePlanIdstringRequiredMapped rate plan ID.
data[].mappings[].ratePlanNamestringRequiredMapped rate plan name.
data[].mappings[].roomTypeNamestringRequiredRoom type of the mapped rate plan.
data[].mappings[].externalRoomCodestring | nullRequiredRoom code on the sales channel, or null when unmapped.
data[].mappings[].externalRateCodestring | nullRequiredRate code on the sales channel, or null when unmapped.
data[].mappings[].primaryOccupancybooleanRequiredWhether the mapping drives the primary occupancy rate.
data[].createdAtstring (date-time)RequiredConnection creation time.
data[].updatedAtstring (date-time)RequiredLast connection change time.

Webhooks

Webhook endpoints require the webhooks:manage scope. The signing secret appears exactly once, in the create response; list and get responses never return it.

Test keys cannot create, update, or delete webhook endpoints. Writes with a test key return sandbox_read_only.

GET /webhooks

Return one stable page of webhook endpoints, newest first.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Query parameters
FieldTypeRequiredDescription
limitintegerOptionalRecords per page, from 1 through 200. The default is 100.
cursorstringOptionalSend meta.page.nextCursor without changing any other filter.
200 JSON response
FieldTypeRequiredDescription
dataWebhookEndpoint[]RequiredA stable page of webhook endpoint records, newest first.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
meta.pageobjectRequiredCursor pagination state.
meta.page.hasMorebooleanRequiredWhether another page is available.
meta.page.limitintegerRequiredThe page size applied to this response.
meta.page.nextCursorstring | nullRequiredThe cursor for the next page, or null when the page is final.
meta.page.snapshotAtstring (date-time)RequiredThe stable read boundary shared by every page in the cursor chain.
data[].idstringRequiredStable webhook endpoint ID.
data[].urlstringRequiredEndpoint URL.
data[].descriptionstringRequiredEndpoint description, or an empty string.
data[].eventsstring[]RequiredSubscribed event types.
data[].status'active' | 'disabled'RequiredEndpoint status.
data[].createdAtstring (date-time)RequiredEndpoint creation time.

POST /webhooks

Create a webhook endpoint. The URL must be a public https:// address without embedded credentials: loopback, private, link-local, and reserved hosts are rejected at save time, and delivery re-checks DNS answers and every redirect hop before connecting.

Send an Idempotency-Key header to make retries safe. A repeated POST with the same key and the same payload returns 200 with the original endpoint and creates nothing new; the same key with a different payload fails with 409 idempotency_key_reused.

The 201 response is the only one that includes signingSecret. A replayed request returns 200 without the secret.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Idempotency-KeystringOptional1 to 200 characters. Makes create retries safe.
JSON body
FieldTypeRequiredDescription
urlstringRequiredPublic https:// endpoint URL.
eventsstring[]RequiredSubscribed event types from the event catalog.
descriptionstringOptionalEndpoint description.
enabledbooleanOptionalSet false to disable the endpoint. The default is true.
201 JSON response
FieldTypeRequiredDescription
dataWebhookEndpointRequiredThe created webhook endpoint, including its signing secret.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
data.idstringRequiredStable webhook endpoint ID.
data.urlstringRequiredEndpoint URL.
data.descriptionstringRequiredEndpoint description, or an empty string.
data.eventsstring[]RequiredSubscribed event types.
data.status'active' | 'disabled'RequiredEndpoint status.
data.createdAtstring (date-time)RequiredEndpoint creation time.
data.signingSecretstringRequiredPayload signing secret. Returned only in the create response.

GET /webhooks/{webhookId}

Return one webhook endpoint from the API key workspace.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Path parameters
FieldTypeRequiredDescription
webhookIdstringRequiredPositive webhook endpoint database ID.
200 JSON response
FieldTypeRequiredDescription
dataWebhookEndpointRequiredThe requested webhook endpoint.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
data.idstringRequiredStable webhook endpoint ID.
data.urlstringRequiredEndpoint URL.
data.descriptionstringRequiredEndpoint description, or an empty string.
data.eventsstring[]RequiredSubscribed event types.
data.status'active' | 'disabled'RequiredEndpoint status.
data.createdAtstring (date-time)RequiredEndpoint creation time.

PUT /webhooks/{webhookId}

Replace the URL, description, and subscribed events of one webhook endpoint. Set enabled to change the status.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Path parameters
FieldTypeRequiredDescription
webhookIdstringRequiredPositive webhook endpoint database ID.
JSON body
FieldTypeRequiredDescription
urlstringRequiredPublic https:// endpoint URL.
eventsstring[]RequiredSubscribed event types from the event catalog.
descriptionstringOptionalEndpoint description.
enabledbooleanOptionalSet false to disable the endpoint. The default is true.
200 JSON response
FieldTypeRequiredDescription
dataWebhookEndpointRequiredThe requested webhook endpoint.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
data.idstringRequiredStable webhook endpoint ID.
data.urlstringRequiredEndpoint URL.
data.descriptionstringRequiredEndpoint description, or an empty string.
data.eventsstring[]RequiredSubscribed event types.
data.status'active' | 'disabled'RequiredEndpoint status.
data.createdAtstring (date-time)RequiredEndpoint creation time.

DELETE /webhooks/{webhookId}

Delete one webhook endpoint. A successful delete returns 204 with no body.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Path parameters
FieldTypeRequiredDescription
webhookIdstringRequiredPositive webhook endpoint database ID.

GET /webhooks/{webhookId}/deliveries

Return one stable page of delivery attempts for the endpoint, newest first.

Headers
FieldTypeRequiredDescription
AuthorizationstringRequiredSend Bearer $SUPAHOST_API_KEY.
Path parameters
FieldTypeRequiredDescription
webhookIdstringRequiredPositive webhook endpoint database ID.
Query parameters
FieldTypeRequiredDescription
limitintegerOptionalRecords per page, from 1 through 200. The default is 100.
cursorstringOptionalSend meta.page.nextCursor without changing any other filter.
200 JSON response
FieldTypeRequiredDescription
dataWebhookDelivery[]RequiredA stable page of delivery records, newest first.
metaobjectRequiredResponse metadata.
meta.requestIdstringRequiredSupport identifier for this request.
meta.pageobjectRequiredCursor pagination state.
meta.page.hasMorebooleanRequiredWhether another page is available.
meta.page.limitintegerRequiredThe page size applied to this response.
meta.page.nextCursorstring | nullRequiredThe cursor for the next page, or null when the page is final.
meta.page.snapshotAtstring (date-time)RequiredThe stable read boundary shared by every page in the cursor chain.
data[].idstringRequiredStable delivery ID.
data[].eventType'reservation.created' | 'reservation.updated' | 'reservation.cancelled' | 'message.received' | 'message.sent' | 'property.created' | 'property.updated' | 'task.created' | 'task.updated' | 'calendar.updated'RequiredDelivered event type.
data[].eventKeystringRequiredLogical event identity; repeated deliveries of one event share it.
data[].status'pending' | 'delivered' | 'failed' | 'exhausted'RequiredDelivery status.
data[].attemptCountintegerRequiredDelivery attempts so far.
data[].responseStatusinteger | nullRequiredHTTP status the endpoint returned, or null.
data[].durationMsinteger | nullRequiredLast attempt duration in milliseconds, or null.
data[].nextAttemptAtstring (date-time) | nullRequiredNext scheduled retry, or null.
data[].createdAtstring (date-time)RequiredDelivery creation time.

Stable cursor pagination

List endpoints return 100 records by default. Set limit from 1 through 200.

If hasMore is true, send nextCursor as the next cursor. Keep all other filters unchanged.

The cursor holds a snapshot boundary. Records that change during a multi-page read do not move between its pages.

One rate limit

Each API key can make 120 requests per minute. Supahost does not combine second, minute, and hour quotas.

  • RateLimit-Limit shows the key limit.
  • RateLimit-Remaining shows the requests left in the current window.
  • RateLimit-Reset shows the seconds until the window resets.
  • Retry-After appears with a 429 response.

Request audit

Supahost records each authenticated request. The record has the key, route, status, duration, and request ID.

Supahost does not store request bodies, response bodies, credentials, or URL query values in this audit record.