# Listings API V1 ## Overview The Listings API V1 is a **venue-aggregated** discovery interface. The response root carries `meta` and `listings[]`. Each entry in `listings[]` is a `ListingGroup` — one per operator (venue-group / chain), carrying a `groupName` and an `items[]` array. Each `item` represents a single venue (or a standalone event when no venue is known): it carries the venue `name`, a `location`, and a `capabilities[]` array. Each entry in `capabilities[]` is a `Listing` with exactly **one** capability (`table_reservation` or `event_ticket`), and carries its own `photos[]`. A venue that also hosts a ticketed event therefore yields a single item with two capabilities — one for the venue, one for the event. All bookable units (venue products, event ticket types, future capability types) are unified under a single `bookableProducts[]` array. Every entry is a single `Bookable` shape; capability-specific fields are nullable and the parent Listing's `capability` sets the context. Temporal information (venue opening hours, event occurrences, blackout dates) is unified under a single `availabilityOccurrence[]` field of `CalendarRule`s. Both capabilities use the same shape. Pre-order assets (packages, menus) are unified under a single `preorders` container — applicable to either capability when the listing supports pre-orders. ## ID formats — two distinct identifiers, both CompositeId-encoded `Listing.id` (venue or event, as returned in `/v1/listings`) is 3 segments: `{VenueGroupId}|{RmsSlug}|{ResourceId}`. For a hybrid entity the event-side row uses the EventExt's CompositeId (different `RmsSlug` + `ResourceId`) so the two rows are unambiguous. `Bookable.compositeId` (a specific bookable product/ticket type — used in `bookableProducts[]`, and as the `compositeId` in `/v1/availabilities` and `/v1/orders`) is 4 segments: `{VenueGroupId}|{RmsSlug}|{ResourceId}|{AdditionalId}`. These are two different identifiers for two different things, not two interchangeable formats for the same one — a `Listing.id` never appears where a `Bookable.compositeId` is expected, or vice versa. Version: 1.0.0 ## Servers Live ``` https://api.bookabletech.com ``` Sandbox ``` https://api-sandbox.bookabletech.com ``` ## Security ### Live OAuth 2.0 client credentials (Auth0) — Live. Type: oauth2 ### Sandbox OAuth 2.0 client credentials (Auth0) — Sandbox. Type: oauth2 ## Download OpenAPI description [Listings API V1](https://docs.bookabletech.com/_bundle/apis/production/ListingsApiV1.yaml) ## Listings Discover and retrieve bookable listings ### Retrieve the full bookable catalogue (paginated, venue-aggregated) - [GET /v1/listings](https://docs.bookabletech.com/apis/production/listingsapiv1/listings/getlistings.md): Returns the entire bookable catalogue available to the caller, paginated and venue-aggregated. Results are grouped by operator (ListingGroup); each group carries its venues (ListingItem), and each venue carries one Listing per capability it offers (table_reservation, event_ticket). A venue that also hosts a ticketed event therefore appears once, with two entries in its capabilities[] — one per capability. Optional query filters (capability, name, location, features, date, …) narrow the catalogue; with no filters the whole catalogue is returned page by page. ### Check availability for multiple bookable products in one call - [POST /v1/availabilities](https://docs.bookabletech.com/apis/production/listingsapiv1/listings/checkavailabilities.md): Batch availability check. Modelled as a command (POST), not a search. The request carries root-level date, quantity and optional time, plus a bookableProducts[] list. Each entry has a required compositeId and may override date, quantity and time. When an entry omits any of those, the root-level value is used. quantity carries the count for either capability, same as in POST /v1/orders — number of covers for a table reservation, number of tickets for an event-ticket line. Every entry must end up with date and quantity resolved (either from the entry or the root). time is optional — event capabilities are queried by date alone; for table reservations it narrows the slot when supplied. An entry that cannot resolve date and quantity is reported as an error result and does not block the others. Searches run independently: a failure on one compositeId yields an error on that result only — all other results are returned normally. The response carries one AvailabilityResult per requested compositeId, preserving request order. There is no 404 response: an unknown/nonexistent compositeId is not a request-level failure — it's reported as an error on that entry's AvailabilityResult, same as any other per-entry failure (e.g. unresolved date/quantity), never as an HTTP-level not-found for the whole call. ## Orders Create and manage orders ### Create an order — one or more independent bookings, across any platform - [POST /v1/orders](https://docs.bookabletech.com/apis/production/listingsapiv1/orders/createorder.md): Creates an order containing one or more bookings. Each item is resolved and booked independently — there is no cross-item transaction. A failure on one item (e.g. the venue/event on one platform is fully booked) does not block or roll back the others. The response carries one OrderItemResult per requested item, preserving request order — mirroring how POST /v1/availabilities reports one result per compositeId. Because every item is self-sufficient via its own compositeId (which embeds VenueGroupId + RmsSlug), a single order can span multiple venues and even multiple RMS platforms (e.g. one item on Collins, another on Zonal) — there is no top-level listingId constraining the order to one platform. Each OrderItem is unified (no capability field, no oneOf) — quantity carries the count for either capability (covers for a table reservation, ticket count for an event-ticket line); time additionally applies to table reservations. Capability is resolved server-side from the compositeId's RMS slug, not from which fields are populated. An order's items may mix capabilities and platforms freely. ### Update one or more bookings within an order - [PATCH /v1/orders/{orderId}](https://docs.bookabletech.com/apis/production/listingsapiv1/orders/updateorder.md): Partial update — each OrderItemUpdate only carries the fields being changed; anything omitted keeps its current value. Items are resolved and updated independently, same isolation model as POST /v1/orders: a failure on one item does not block the others. Capability (table reservation vs. event ticket) is resolved server-side from the existing booking, not from the request — every field below applies uniformly to either capability at the API level, even where the RMS-side effect currently differs (noted per field). compositeId moves the booking to a different bookable product — the same identifier used everywhere else (Bookable.compositeId, the only thing taken from a listing's bookableProducts[]), not a ticket-specific field. Supported for both capabilities: for event tickets it changes the ticket type (the compositeId's 4th segment); for table reservations it changes the booked product/space. The new compositeId must reference the same venue group, RMS and venue/event as the booking's current product — only the trailing product/ticket-type segment may differ; a cross-venue or cross-event move is rejected (400 ORDER-N-007). firstName/lastName/email/phone update the guest's details, either capability. Preorders (table-reservation only in practice — event tickets have no preorder concept, these fields are accepted but a no-op for them today): preorders is a full replacement of the current preorder set (omit to leave unchanged, send empty arrays to clear). preorderChanges is the incremental alternative — add or remove specific packages/menus without resending the rest; mutually exclusive with preorders on the same item (400 ORDER-N-008). ### Cancel bookings within an order, or the entire order - [DELETE /v1/orders/{orderId}](https://docs.bookabletech.com/apis/production/listingsapiv1/orders/deleteorder.md): Cancels the bookings listed in bookingIds. When bookingIds is omitted or empty, cancels every booking belonging to orderId. Each cancellation is independent — one failure does not block the others.