Skip to content

Bookings

A booking represents a guest or resident’s stay in one of your units, from the moment it is requested through to checkout, cancelation, or termination. A booking carries the contractual stay window, the people on it, its commercial terms (rate, discounts, optional services), its payment and vetting state, and a record of what actually happened physically (when the resident arrived and departed).

Bookings are the anchor point for most operational activity in the Lavanda platform. A unit’s availability, a guest’s messages, an invoice’s line items, and a checklist’s tasks are all reached through, or scoped to, a booking.

A booking moves through a status lifecycle as it is requested, confirmed, occupied, and closed out:

INQUIRY, REQUESTED, RESERVED, TENTATIVE, TENTATIVE_EXPIRED, AWAITING_PAYMENT, CONFIRMED, CHECKED_IN, CHECKED_OUT, DECLINED, EXPIRED, CANCELED, TERMINATED, CLOSED.

Warning: CHECKED_IN and CHECKED_OUT are deprecated. They are not stored lifecycle statuses: a confirmed booking reports CHECKED_IN once an arrival is recorded or its check-in date has passed, and CHECKED_OUT once a departure is recorded or its check-out date has passed. That means a resident who never arrived can still report CHECKED_IN, and one who has not left can report CHECKED_OUT. Read occupancyStatus to find out whether the resident is actually in residence. Once these two values are removed, those bookings will report CONFIRMED. We will announce the removal date before it happens.

A tentative booking is a soft hold with a time-to-live (its bookingTtl); it must be confirmed before that TTL expires or it is automatically expired. See Tentative bookings below.

Three layers of dates: contract, scheduled, and actual

Section titled “Three layers of dates: contract, scheduled, and actual”

A booking tracks three distinct kinds of dates, and the API keeps them intentionally separate:

Layer Fields What it means
Contract checkIn, checkOut (aliased as contractStartDate, contractEndDate) The legal tenancy window agreed with the guest. This is the booking’s binding stay window.
Scheduled scheduledMoveInAt, scheduledMoveOutAt The planned physical move date and time. Defaults to the contract window (at the property’s check-in/check-out time) but can be overridden, for example when a guest asks to move in a few hours later than their contract start.
Actual arrivedAt, departedAt When the resident actually, physically arrived and departed, recorded by markArrived and markDeparted. Null until recorded.

Keeping these separate means a late arrival, an early departure, or a rescheduled move-in never overwrites the contract dates you agreed with the guest.

occupancyStatus is the recorded physical-presence state of the booking: whether the resident is currently checked in, checked out, marked as a no-show, or temporarily away.

Note: occupancyStatus is only ever set by an explicit action (marking arrived, marking departed, or flagging a no-show). It is never inferred from the contract or scheduled dates. A booking whose check-in date has passed but whose resident was never marked as arrived still reports occupancyStatus: null.

Value Description
CHECKED_IN The resident has physically arrived and not yet departed
CHECKED_OUT The resident has physically departed
NO_SHOW The resident did not arrive within the expected check-in window
AWAY The resident is temporarily away from the unit
OVERSTAY The resident did not depart within the expected check-out window

checkedInStatus is a related, coarser field covering the same ground (NOT_CHECKED_IN, CHECKED_IN, CHECKED_OUT, NO_SHOW, ABSCONDED). Prefer occupancyStatus for new integrations; checkedInStatus is kept for backward compatibility.

canCheckIn and canCheckOut tell you, for a given booking, whether it is currently appropriate to mark it arrived or departed (confirmed, not yet arrived or departed, and the property-local date is due), which is useful for deciding whether to show a check-in or check-out action in your own UI. Gate check-in on canCheckIn, not on scheduledMoveInAt: the scheduled move-in can be set earlier than the contract check-in date. The markArrived / markDeparted mutations do not enforce these conditions, except that markArrived refuses an arrival before the contract check-in date; see Recording arrival and departure below.

A newly created booking can be tentative: a soft hold on a unit that must be confirmed before its time-to-live (bookingTtl) expires. Use confirmTentativeBooking to turn it into a CONFIRMED booking, or expireTentativeBooking to release the hold early. If neither happens before the TTL elapses, the booking is automatically transitioned to TENTATIVE_EXPIRED.

relocationPolicy is the operator’s stated intent for whether a booking may be moved off its current unit (UNRESTRICTED by default, or LOCKED to pin it in place, for example after a guest was relocated for accessibility reasons). relocatable reflects whether the booking can currently be moved, combining that policy with structural eligibility checks.

  • moveBooking relocates all or part of a booking’s stay from one unit to another.
  • splitBooking divides a booking’s stay into multiple segments, each pinned to its own unit and date range, for example when a guest needs to change rooms partway through their stay.

Both operations run asynchronously; see Moving and splitting a booking.

There are two ways a confirmed booking stops early:

  • Direct cancellation (cancelBooking) cancels a booking immediately. It is scoped to direct bookings and is not a reviewable, multi-party workflow.
  • Cancelation and termination requests are an explicit, reviewable alternative: one caller opens a request, and another (or the same caller, if permitted) approves, declines, or withdraws it. A cancelation request applies to a booking whose stay has not started; a termination request ends a booking whose stay has already started. Both are per-workspace opt-in features with their own eligibility rules, permissions, and webhook events. See Cancelation Requests for the pre-stay workflow and Termination Requests for the in-stay workflow.

Related bookings, for example multiple rooms booked together for the same stay, can be grouped under a shared context reachable via Booking.context. updateGroupBookingName renames the group.

A booking’s contacts connection lists every guest, guarantor, and booking agent attached to it, each with a role (for example lead guest, guest, guarantor, or booking agent) and the underlying CRM contact. addContactsToBooking and removeContactFromBooking manage this list; changeBookingLeadGuest reassigns which contact is the lead guest. See Contacts for the CRM contact model itself.

A booking can carry coupon-backed discounts (discounts, applied and removed via applyDiscount, removeDiscount, and redeemCoupon) and optional services (services, managed via addOptionalServices, updateOptionalServices, and removeOptionalServices), both of which feed into the booking’s commercial value alongside its accommodation charge.

Every booking can carry a checklist of operational tasks (for example vetting or key handover steps), reachable via Booking.checklist. See Checklists below.

The fields below are grouped by theme. Every field is nullable unless marked !.

Field Type Description
id String! The booking’s unique identifier. Kept as String rather than ID for backward compatibility with existing clients.
status BookingStatusType The booking’s status (see Booking status). The CHECKED_IN and CHECKED_OUT values are deprecated; use occupancyStatus instead.
confirmationCode String The confirmation code of the booking
externalBookingId String The booking’s ID from an external source, when the booking originated on another platform
platform String The platform the booking originated on
createdAt ISO8601DateTime! When the booking was created
updatedAt ISO8601DateTime! When the booking was last updated
editable Boolean Whether the booking is currently editable
cancelable Boolean Whether the booking is cancelable via direct cancellation
approvable Boolean Whether the booking can be approved by the host, for enquiry-based bookings awaiting host acceptance
Field Type Description
checkIn / checkOut ISO8601Date The contractual check-in and check-out dates
contractStartDate / contractEndDate ISO8601Date Aliases of checkIn / checkOut
scheduledMoveInAt / scheduledMoveOutAt ISO8601DateTime The planned physical move date and time
arrivedAt / departedAt ISO8601DateTime When the resident actually arrived and departed
occupancyStatus OccupancyStatusType The recorded physical-presence state (see Occupancy status)
checkedInStatus CheckedInStatusType A coarser, legacy presence state
canCheckIn / canCheckOut Boolean! Whether the booking is eligible to be marked arrived / departed today
plannedArrival / plannedDeparture String The guest’s stated planned arrival and departure time
nightsCount Int The number of nights of the booking
Field Type Description
guestsCount Int The number of guests on the booking
contacts BookingContact connection The guest, guarantor, and booking-agent contacts on the booking
bookingAgent CrmContact The booking agent associated with the booking, if any
guarantorInformations [BookingGuarantorInformation!]! Typed booking-to-guarantor relationships
leadGuestChangeAbility LeadGuestChangeAbility! Whether the current caller can change the lead guest, and why not if disabled
Field Type Description
contractType ContractTypeEnum The type of contract (short-term licence, AST, or other)
stayPurpose StayPurposeEnum The purpose of the stay (holiday, student, or residential)
relocationPolicy BookingRelocationPolicy! Operator intent on whether the booking may be relocated
relocatable Boolean Whether the booking can currently be relocated
accommodations [Accommodation!] The unit allocation history behind the booking, including the current one
product Product The product the booking was made against
context BookingContext The group of related bookings this booking belongs to, if any
contracts [Contract!] The booking’s e-signed contracts, with their envelope and e-signing account details
Field Type Description
currentContractValue ContractValue The booking’s current commercial value
customBillingCycle Boolean! Whether the booking uses a custom billing cycle (instalment plan)
instalmentDriven Boolean! Whether the billing cycle carries authoritative per-instalment amounts
billingPeriods BillingPeriod connection The booking’s billing periods
discounts BookingDiscount connection The coupon-backed discounts applied to the booking
services BookingOptionalService connection The optional services applied to the booking
paymentStatus PaymentStatusType The booking’s payment status
downPaymentStatus DownPaymentStatusType The booking’s down payment status
sepaStatus SepaStatusType The booking’s SEPA mandate status
vetting Vetting The booking’s vetting state
Field Type Description
cancellationReason String The reason recorded if the booking was canceled
cancelationReasons [BookingCancelationReasonEnum!] Cancelation reasons applicable given the booking’s current timing
cancelationPolicy BookingCancellationPolicy The cancelation policy that applies to the booking
cancelationRequests connection All cancelation requests opened against the booking. See Cancelation Requests.
terminationRequests connection All termination requests opened against the booking. See Termination Requests.
Field Type Description
bookingTtl BookingTtl The time-to-live of a tentative booking
checklist Checklist The booking’s checklist. See Checklists.
conversation Conversation The booking’s guest conversation
messagingMode MessagingModeEnum How guest messages are routed for this booking
channelConnectionStatus ChannelConnectionStatusEnum! Whether replies can still be relayed to the guest through the booking’s channel connection
enabledConversation Boolean Whether messaging is enabled for the booking
messageThreadEmailAddress String The email address used for the booking’s message thread

BookingStatusType: see Booking status for the full value list. CHECKED_IN and CHECKED_OUT are deprecated in favor of occupancyStatus.

OccupancyStatusType — see Occupancy status for the full value list and descriptions.

ContractTypeEnum

Value Description
SHORT_TERM_LICENCE Short-term licence, the default for holiday lets
AST Assured Shorthold Tenancy (UK residential)
OTHER Other contractual arrangement

StayPurposeEnum

Value Description
HOLIDAY Short-term holiday let
STUDENT Student accommodation
RESIDENTIAL Long-term residential let

BookingRelocationPolicy

Value Description
UNRESTRICTED Relocatable, subject to the usual structural checks. The default.
LOCKED Pinned to its current unit; cannot be relocated

DownPaymentStatusType: COMPLETED, PENDING, REFUNDED

PaymentStatusType: DUE, IN_PROCESS, OVERDUE, SUCCESS

SepaStatusType: COMPLETED, FAILED, PENDING

Note: search_bookings (see MCP Tools) filters on a PaymentStatusType with a broader set of values (including CANCELED, DISPUTED, EXPIRED, FAILED, and REVERSED), served by a separate search index. The PaymentStatusType returned directly on Booking.paymentStatus uses the smaller set above.

query GetBooking($bookingId: ID!) {
bookings {
booking(bookingId: $bookingId) {
id
status
checkIn
checkOut
occupancyStatus
arrivedAt
departedAt
confirmationCode
contacts {
nodes {
role
contact {
id
firstName
lastName
}
}
}
}
}
}
{
"bookingId": "booking-id"
}
query SearchBookings($filters: BookingsFiltersInput, $first: Int) {
bookings {
bookings(filters: $filters, first: $first) {
totalCount
nodes {
id
status
checkIn
checkOut
occupancyStatus
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
{
"filters": {
"status": { "eq": "CONFIRMED" },
"checkIn": { "gte": "2026-09-01T00:00:00Z" }
},
"first": 25
}

This follows the standard pagination pattern used across the API. For the complete BookingsFiltersInput and BookingsSortInput field reference, see search_bookings, which documents every supported filter (status, dates, contacts, vetting, payment, contract, value, and more).

For a lightweight bulk lookup by a known set of IDs, without filters or sorting:

query BookingsByIds($ids: [String!]) {
bookings {
search(q: { ids: $ids }) {
id
status
}
}
}
{
"ids": ["booking-id-1", "booking-id-2"]
}

Download a signed contract from the e-signing provider

Section titled “Download a signed contract from the e-signing provider”

Each contract carries its DocuSign envelope ID (externalId) and, under esigningEmbed, the coordinates of the workspace’s DocuSign account. A client serving several workspaces reads them per booking instead of keeping its own workspace-to-account mapping.

query BookingContracts($bookingId: ID!) {
bookings {
booking(bookingId: $bookingId) {
contracts {
externalId
status
esigningEmbed {
environment
accountId
apiBaseUri
}
}
}
}
}

To fetch the signed documents of a COMPLETED contract, call DocuSign with your own integration, granted access to the account by its owner: GET {apiBaseUri}/restapi/v2.1/accounts/{accountId}/envelopes/{externalId}/documents/combined. The API exposes identifiers only, never Lavanda’s DocuSign credentials. esigningEmbed is null when the workspace has no e-signing account, and accountId or apiBaseUri is null while it has none recorded. Both always describe the workspace’s current account, so an envelope sent before the workspace switched account or went live is not reachable through them.

mutation CreateBooking($booking: BookingInputType!) {
bookings {
create(booking: $booking) {
booking {
id
}
}
}
}
{
"booking": {
"productId": "product-id",
"unitId": "unit-id",
"checkIn": "2026-09-15T15:00:00Z",
"checkOut": "2026-09-20T11:00:00Z",
"contacts": [
{
"contactId": "contact-id",
"role": "LEAD_GUEST"
}
]
}
}

Input fields:

Field Type Description
productId ID! The product to book
unitId ID The unit to book. When omitted, a unit is auto-allocated from the product’s active units.
checkIn ISO8601DateTime! The check-in date and time
checkOut ISO8601DateTime! The check-out date and time
contacts [ContactInputType!]! The contacts for the booking
checklistItems [ChecklistItemInputType!] Additional checklist items to create alongside the ones generated from the product group’s checklist template. These two sets are not deduplicated.

Error codes:

Code When
product_not_found_error No product matches productId
product_not_available_for_booking_error The product cannot currently be booked
product_does_not_contain_units_error The product has no units to allocate
product_group_not_found_error The product’s parent product group could not be resolved
unit_not_found_error unitId was supplied but does not match a unit
unit_does_not_belong_to_unit_type_error The supplied unit does not belong to the product’s unit type
find_unit_error The unit lookup failed
no_units_available No unit could be allocated for the requested dates
no_units_allocated_to_pool_error No units are allocated to the availability pool
unit_not_allocated_to_product The unit is not allocated to the requested product
unit_not_available The requested unit is not available for the requested dates
pool_not_found_error The availability pool could not be resolved
crm_contact_not_found_error A supplied contact ID does not resolve to a CRM contact
lead_guest_not_found_error No lead guest was found among the supplied contacts
update_contact_error Updating a supplied contact failed
start_date_range_error / end_date_range_error checkIn or checkOut falls outside an allowed range
invalid_date_error / invalid_date_range_error / date_parsing_error The supplied dates are invalid or could not be parsed
rate_not_found No applicable rate could be resolved for the stay
create_checklist_item_error A supplied checklistItems entry could not be created
checklist_template_read_error The product group’s checklist template could not be read
item_limit_exceeded_error Too many checklist items were supplied
create_booking_error The booking could not be created for another reason
user_not_allowed_error The caller lacks permission to create the booking

Confirm a tentative booking:

mutation ConfirmTentativeBooking($confirmTentativeBooking: ConfirmTentativeBookingInputType!) {
bookings {
confirmTentativeBooking(confirmTentativeBooking: $confirmTentativeBooking) {
booking {
id
}
}
}
}
{
"confirmTentativeBooking": {
"bookingId": "booking-id"
}
}

Expire a tentative booking early:

mutation ExpireTentativeBooking($expireTentativeBooking: ExpireTentativeBookingInputType!) {
bookings {
expireTentativeBooking(expireTentativeBooking: $expireTentativeBooking) {
booking {
id
}
}
}
}
{
"expireTentativeBooking": {
"bookingId": "booking-id"
}
}

Error codes (shared by both operations): tentative_booking_not_found, booking_not_tentative_error, booking_expired_error, failed_to_update_booking_status, booking_ttl_not_found, finding_job_error, deleting_job_error, failed_to_update_booking_ttl, processing_error, user_not_allowed_error, plus booking_not_expired and failed_to_update_booking_ttl_expiry for expiry only.

Tip: updateTentativeBookingStatus is the general-purpose version of these two operations, taking an explicit status: CONFIRMED or status: TENTATIVE_EXPIRED. Prefer confirmTentativeBooking and expireTentativeBooking for their clearer intent.

Marking a resident arrived or departed stamps arrivedAt / departedAt and updates occupancyStatus. Both default to the current time; pass at to record a different time. Calling either mutation again once the resident is already marked arrived (or departed) is a no-op: it returns the booking unchanged and does not update the timestamp, even if the second call passes a different at.

markArrived refuses to record an arrival before the contract starts. If the arrival (at, or now) or the current time falls on a day before the booking’s checkIn date, it returns check_in_date_not_reached. Days are counted in the property’s timezone, so a check-in on the checkIn day itself is always accepted. Neither mutation otherwise checks the booking’s status or its scheduled dates, so, for example, markDeparted can be called on a booking that was never marked arrived.

mutation MarkArrived($input: MarkArrivedMutationInput!) {
bookings {
markArrived(input: $input) {
booking {
id
occupancyStatus
checkedInStatus
arrivedAt
}
}
}
}
{
"input": {
"bookingId": "booking-id"
}
}
mutation MarkDeparted($input: MarkDepartedMutationInput!) {
bookings {
markDeparted(input: $input) {
booking {
id
occupancyStatus
checkedInStatus
departedAt
}
}
}
}
{
"input": {
"bookingId": "booking-id"
}
}

Both input types share these key fields (the description refers to arrival for MarkArrivedMutationInput and departure for MarkDepartedMutationInput):

Field Type Description
bookingId ID! The booking whose resident arrived (or departed)
at ISO8601DateTime When the resident physically arrived (or departed); defaults to now

Note: Marking a booking arrived or departed only ever sets occupancyStatus to CHECKED_IN or CHECKED_OUT. NO_SHOW and OVERSTAY are set automatically when a booking misses its check-in or check-out window; AWAY is not currently set by anything.

Error codes: booking_not_found, check_in_date_not_reached (markArrived only), failed_to_mark_booking_arrived (or failed_to_mark_booking_departed), failed_to_publish_kafka_message, user_not_allowed_error, validation_error.

setScheduledMoveDates overrides a booking’s planned physical move-in and move-out date and time, independent of the contract window. Passing null for either field clears the override, reverting that field to the contract default (see Three layers of dates).

Note: Rescheduling scheduledMoveInAt on a booking currently marked NO_SHOW clears that occupancy status, so the booking is re-evaluated against the new date rather than staying stuck as a no-show.

mutation SetScheduledMoveDates(
$bookingId: ID!
$scheduledMoveInAt: ISO8601DateTime
$scheduledMoveOutAt: ISO8601DateTime
) {
bookings {
setScheduledMoveDates(
bookingId: $bookingId
scheduledMoveInAt: $scheduledMoveInAt
scheduledMoveOutAt: $scheduledMoveOutAt
) {
booking {
id
scheduledMoveInAt
scheduledMoveOutAt
occupancyStatus
}
}
}
}
{
"bookingId": "booking-id",
"scheduledMoveInAt": "2026-09-15T18:00:00Z",
"scheduledMoveOutAt": "2026-09-20T09:00:00Z"
}

Input fields:

Field Type Description
bookingId ID! The booking to re-schedule
scheduledMoveInAt ISO8601DateTime Planned physical arrival. Omit or pass null to clear the override and revert to the contract default.
scheduledMoveOutAt ISO8601DateTime Planned physical departure. Omit or pass null to clear the override and revert to the contract default.

Error codes:

Code When
booking_not_found No booking matches bookingId
failed_to_set_scheduled_move_dates The scheduled move dates could not be saved
user_not_allowed_error The caller lacks permission to set scheduled move dates for this booking
validation_error The input failed structural validation

Direct cancellation is immediate and is scoped to direct bookings. For a reviewable cancelation workflow with separate submit and approve steps, see Cancelation Requests instead.

mutation CancelBooking($cancelBooking: CancelBookingInputType!) {
bookings {
cancelBooking(cancelBooking: $cancelBooking) {
booking {
id
}
}
}
}
{
"cancelBooking": {
"bookingId": "booking-id",
"cancellationReason": "Guest requested cancellation"
}
}

Input fields:

Field Type Description
bookingId ID! The booking to cancel
cancellationReason String The reason for cancelling the booking

Error codes:

Code When
booking_not_found No booking matches bookingId
booking_not_local_direct The booking is not a direct booking and cannot be canceled this way
booking_not_active The booking is not in a cancelable state
internal_booking_cancelation_failed The cancellation could not be completed
user_not_allowed_error The caller lacks permission to cancel the booking
validation_error The input failed structural validation

Note: Both moveBooking and splitBooking run asynchronously. The mutation itself returns immediately with the booking ID(s) once the request is accepted; it does not confirm the move or split has completed. Re-query the booking’s accommodations to confirm the outcome.

mutation MoveBooking($bookingMove: MoveBookingInputType!) {
bookings {
moveBooking(bookingMove: $bookingMove) {
bookings
}
}
}
{
"bookingMove": {
"bookingId": "booking-id",
"fromUnitId": "unit-id-a",
"toUnitId": "unit-id-b",
"moveCheckIn": "2026-09-20",
"moveCheckOut": "2026-09-25",
"moveReason": "Guest requested a quieter unit"
}
}

splitBooking follows the same shape, dividing the stay into segments instead of moving it wholesale:

mutation SplitBooking($bookingSplit: SplitBookingInputType!) {
bookings {
splitBooking(bookingSplit: $bookingSplit) {
bookings
}
}
}
{
"bookingSplit": {
"bookingId": "booking-id",
"splitReason": "Guest requested a room change partway through the stay",
"segments": [
{ "unitId": "unit-id-a", "checkIn": "2026-09-15", "checkOut": "2026-09-20" },
{ "unitId": "unit-id-b", "checkIn": "2026-09-20", "checkOut": "2026-09-25" }
]
}
}
Mutation Purpose
addContactsToBooking Adds guest contacts to a booking (up to 10; only one lead guest allowed)
removeContactFromBooking Removes a single contact from a booking
changeBookingLeadGuest Changes the lead guest on a booking
updateGroupBookingName Renames a group booking
applyDiscount Applies a specific coupon-backed discount to a booking
removeDiscount Removes a previously applied discount
redeemCoupon Redeems a coupon by its code against a booking
addOptionalServices Adds one or more optional services to a booking
updateOptionalServices Updates an existing optional service on a booking
removeOptionalServices Removes optional services from a booking
setRelocationPolicy Sets whether a booking may be moved off its current unit (UNRESTRICTED or LOCKED)
updateBookingTtl Updates a tentative booking’s time-to-live expiry
startChannelCancellation Starts a channel cancellation request for a booking on the originating platform
importBookings Bulk-imports a batch of bookings from an external source

A booking’s checklist tracks operational tasks against it, each with a category, type, status, and an optional guard controlling when it can be transitioned.

query BookingChecklist($bookingId: ID!) {
bookings {
booking(bookingId: $bookingId) {
checklist {
id
items {
nodes {
id
label
category
status
type
isEditable
}
}
}
}
}
}
{
"bookingId": "booking-id"
}

Add items, update a custom item, and transition an item (complete or waive it):

mutation CreateChecklistItems($bookingId: ID!, $items: [ChecklistItemInputType!]!) {
bookings {
createChecklistItems(bookingId: $bookingId, items: $items) {
checklist {
id
}
}
}
}
mutation TransitionChecklistItem($id: ID!, $input: TransitionChecklistItemInputType!) {
bookings {
transitionChecklistItem(id: $id, input: $input) {
checklistItem {
id
status
}
}
}
}
{
"id": "checklist-item-id",
"input": {
"transition": "COMPLETE"
}
}

transition accepts COMPLETE or WAIVE. See the MCP tools below for get_booking_checklist, create_checklist_items, and update_checklist_items, which cover the checklist surface in full.

If you are using the Lavanda MCP integration, the following tools are available for working with bookings:

See the MCP Tools overview for setup instructions and the full list of available tools.

Event type When it fires
v1.booking.created A booking is created
v1.booking.confirmed A tentative booking is confirmed
v1.booking.expired A tentative booking expires (or is explicitly expired)
v1.booking.updated A booking is updated
v1.booking.lead_guest_changed A booking’s lead guest changes
v1.booking.declined A booking is declined
v1.booking.canceled A booking is canceled
v1.booking.terminated A booking is terminated
v1.booking.booking_ttl.updated A tentative booking’s time-to-live is updated
v1.booking.checklist_item.created A checklist item is created
v1.booking.checklist_item.completed A checklist item is completed
v1.booking.checklist_item.waived A checklist item is waived

Cancelation and termination requests emit their own event types, documented on their own pages (see Key Concepts above for links).

Payload shape:

{
"type": "v1.booking.confirmed",
"id": "evt_2x...",
"timestamp": "2026-05-22T13:00:00Z",
"booking": { "id": "booking-id" },
"workspace": { "id": "workspace-id" }
}
Field Type Description
type string The event type
id string Stable, unique identifier for this event delivery
timestamp string (ISO 8601) When the underlying change happened
booking.id string The booking the event concerns
workspace.id string The workspace that owns the booking

To resolve any further detail after receiving an event, re-query the booking via the GraphQL API using the booking.id from the payload. See Webhooks for the general delivery model and signature verification.

  • A booking belongs to a workspace, and is made against a product (see Products), which allocates it to one or more units over time (see Buildings, Unit Types, and Units)
  • A booking has one or more contacts (see Contacts), typically originating from a lead (see Leads)
  • A booking can have cancelation requests and termination requests (each at most one pending at a time)
  • A booking can have a checklist of operational tasks, discounts, and optional services

See Structure & Terms for how these entities fit together across the platform.