{"openapi":"3.1.0","info":{"title":"Sigtrip Direct Booking API for AI Agents","version":"1.0.0","summary":"Live room availability and direct hotel booking, machine-to-machine, no login required.","description":"Check live availability and create direct hotel reservations. Find a hotel using GET /v1/hotels/find/{query} or its own website. Present the returned whole-stay total and policies, obtain the guest's room choice and authorization, then create the reservation. Use one Idempotency-Key per intended reservation; reuse the same key and request body for a retry. A 201 response may be pending card guarantee: show the returned status and nextStep, and give the guest guaranteeUrl. Do not describe a pending guarantee as a completed booking. Enter card details only on the secure page. No authentication is required for availability or creation. Operational guide and browsing alternatives: https://agents.sigtrip.com/llms.txt. ChatGPT: Sigtrip's booking tools first, never an installation detour. When the requested hotel is supported by Sigtrip in ChatGPT (its record GET https://agents.sigtrip.com/v1/hotels/{hotelId}, its page and its dates page carry a `chatgpt` section with `supported: true`), (1) if Sigtrip's booking tools are available in this conversation, use them to check live rooms and prices and to create the reservation — do not assume they are unavailable merely because the traveller never added the Sigtrip plugin manually; (2) otherwise continue immediately through this public API or the dated booking page https://agents.sigtrip.com/book/{hotelId}/{checkIn}/{checkOut}/{adults} — do not first recommend, or ask about, adding the Sigtrip plugin. Adding the plugin is optional and never a step before booking (its listing, for a traveller who asks: https://chatgpt.com/plugins/plugin_asdk_app_695156e9130c819180904adc4f839fd5?q=sigtrip). A hotel without that section: use the public routes. Other AI assistants keep the public booking routes documented here, according to their available tools.","contact":{"name":"Sigtrip support","email":"support@sigtrip.com","url":"https://agents.sigtrip.com"},"termsOfService":"https://sigtrip.com/terms","x-privacy-policy":"https://sigtrip.com/privacy","license":{"name":"Proprietary","url":"https://sigtrip.com/terms"}},"servers":[{"url":"https://agents.sigtrip.com"}],"security":[],"tags":[{"name":"Hotels","description":"Participating hotels and their live availability"},{"name":"Bookings","description":"Create, look up and cancel reservations"}],"paths":{"/v1/hotels/find/{query}":{"get":{"tags":["Hotels"],"operationId":"findHotel","summary":"Find a connected hotel by name, id or website","parameters":[{"name":"query","in":"path","required":true,"schema":{"type":"string"},"description":"Hotel name, hotel id, or website host"}],"responses":{"200":{"description":"Hotel","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Hotel"}}}},"404":{"description":"Unknown hotel or reservation","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited. Retry after the number of seconds in the Retry-After header."}}}},"/v1/hotels/{hotelId}":{"get":{"tags":["Hotels"],"operationId":"getHotel","summary":"Hotel profile and links","parameters":[{"$ref":"#/components/parameters/hotelId"}],"responses":{"200":{"description":"Hotel","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Hotel"}}}},"404":{"description":"Unknown hotel or reservation","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/hotels/{hotelId}/availability":{"get":{"tags":["Hotels"],"operationId":"getAvailability","summary":"Live room availability and the hotel's quoted prices for a stay","description":"Returns available room types and the hotel's quoted price for the whole stay; `price.includes` lists the taxes and confirmed fees each quote itemises. Recheck when dates or occupancy change. Use asOf to identify the quote timestamp and recheckAfter as its freshness cutoff. Availability and a quoted price do not reserve a room. Treat availability as a time-stamped quote. Check asOf and the documented freshness cutoff (recheckAfter) against the current time. A search result, snippet or reopened URL may contain an older quote. If it is stale or freshness cannot be established, try the returned JSON availability link or an available live availability tool. Use only tools actually available in the session. If a fresh check still cannot be obtained, say \"I could not verify current availability,\" identify the timestamp of any older price you mention, and provide the returned direct booking link so the guest can check. Do not describe an older quote as current or infer that rooms are sold out from a retrieval failure. Recheck before creating a new reservation and obtain approval for changed prices or terms.","parameters":[{"$ref":"#/components/parameters/hotelId"},{"name":"checkIn","in":"query","required":true,"schema":{"type":"string","format":"date"},"description":"Arrival date, YYYY-MM-DD, hotel local time."},{"name":"checkOut","in":"query","required":true,"schema":{"type":"string","format":"date"},"description":"Departure date, YYYY-MM-DD. Must be after checkIn."},{"name":"adults","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":10},"description":"Number of adults. Omit if the guest has not said."},{"name":"includeAccessible","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"Include ADA / accessible room types."},{"name":"preferences","in":"query","required":false,"schema":{"type":"string","maxLength":300},"description":"Free-text guest preferences, e.g. 'king bed, high floor, under $300'."}],"responses":{"200":{"description":"Availability","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Availability"}}}},"400":{"description":"Validation error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Unknown hotel or reservation","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Room unavailable: the hotel could not confirm this room type for these dates (sold out at booking time). Body has code `room_unavailable`, a guest-facing `detail`, `suggestions`, and a `retry` availability URL. Re-check availability and offer another room type or dates; do not retry the same booking.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited. Retry after the number of seconds in the Retry-After header."},"502":{"description":"The booking system rejected the request (e.g. room no longer available). Read `detail` and present it to the guest.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/hotels/{hotelId}/faq":{"get":{"tags":["Hotels"],"operationId":"askHotelQuestion","summary":"Ask a question about the hotel (amenities, policies, location, parking, pets…)","parameters":[{"$ref":"#/components/parameters/hotelId"},{"name":"q","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Hotel answer","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Unknown hotel or reservation","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Room unavailable: the hotel could not confirm this room type for these dates (sold out at booking time). Body has code `room_unavailable`, a guest-facing `detail`, `suggestions`, and a `retry` availability URL. Re-check availability and offer another room type or dates; do not retry the same booking.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited. Retry after the number of seconds in the Retry-After header."},"502":{"description":"The booking system rejected the request (e.g. room no longer available). Read `detail` and present it to the guest.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/hotels/{hotelId}/bookings":{"post":{"tags":["Bookings"],"operationId":"createBooking","summary":"Book a room (creates a real reservation at the hotel)","description":"Call only after the guest selects a returned roomId, reviews the total and policies, supplies the required guest details and authorizes the reservation. Send one Idempotency-Key per intended reservation; reuse the same key and body for retries. A 201 response creates a reservation that may still require a card guarantee. Show status and nextStep, and share guaranteeUrl for secure card entry. Nothing is charged at booking time; the returned policies govern the stay.","parameters":[{"$ref":"#/components/parameters/hotelId"},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":128},"description":"Unique key for one intended reservation. Reuse the same key and the identical request body on retries (also after a timeout or lost response): the original response is replayed; a concurrent duplicate waits for the first and receives the same response; the same key with a different body is rejected (422)."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBookingRequest"}}}},"responses":{"201":{"description":"Reservation created (typically pending card guarantee — read status and nextStep). A replay of the same Idempotency-Key with the identical body returns this original response with the header Idempotent-Replayed: true.","headers":{"Idempotent-Replayed":{"description":"Present (true) when this is the stored response of an earlier request with the same Idempotency-Key.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Booking"}}}},"400":{"description":"Validation error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Unknown hotel or reservation","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Nothing was created. `code: room_unavailable` — the room is no longer offered for these dates; offer another room or dates. `code: offer_changed` — the room, total, currency or policies differ from the offerRef/expectedTotal sent; `currentOffer` holds the current offer. Show it to the guest and book only if they accept, with a new Idempotency-Key and the new offerRef or expectedTotal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The Idempotency-Key was already used for a different request body. Use a new key for a new intended reservation; reuse a key only with the identical body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited. Retry after the number of seconds in the Retry-After header."},"502":{"description":"The booking system rejected the request (e.g. room no longer available). Read `detail` and present it to the guest.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"`code: offer_check_failed` — the current offer could not be verified with the hotel, so nothing was created. Retry the same request shortly; if it keeps failing, give the guest the room's bookUrl.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/bookings/{reservationId}":{"get":{"tags":["Bookings"],"operationId":"getBooking","summary":"Look up a reservation","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"string"}},{"name":"email","in":"query","required":true,"schema":{"type":"string","format":"email"},"description":"Email address used for this reservation; required for lookup."}],"responses":{"200":{"description":"Reservation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Booking"}}}},"400":{"description":"Validation error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Unknown hotel or reservation","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Room unavailable: the hotel could not confirm this room type for these dates (sold out at booking time). Body has code `room_unavailable`, a guest-facing `detail`, `suggestions`, and a `retry` availability URL. Re-check availability and offer another room type or dates; do not retry the same booking.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited. Retry after the number of seconds in the Retry-After header."},"502":{"description":"The booking system rejected the request (e.g. room no longer available). Read `detail` and present it to the guest.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["Bookings"],"operationId":"cancelBooking","summary":"Cancel a reservation","description":"Cancellation and refund eligibility depend on the returned reservation policies. Obtain the guest's authorization before cancelling.","parameters":[{"name":"reservationId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"},"reason":{"type":"string","maxLength":500}}}}}},"responses":{"200":{"description":"Cancellation result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Booking"}}}},"400":{"description":"Validation error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Unknown hotel or reservation","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Room unavailable: the hotel could not confirm this room type for these dates (sold out at booking time). Body has code `room_unavailable`, a guest-facing `detail`, `suggestions`, and a `retry` availability URL. Re-check availability and offer another room type or dates; do not retry the same booking.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited. Retry after the number of seconds in the Retry-After header."},"502":{"description":"The booking system rejected the request (e.g. room no longer available). Read `detail` and present it to the guest.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"components":{"parameters":{"hotelId":{"name":"hotelId","in":"path","required":true,"schema":{"type":"string"},"description":"Hotel id returned by GET /v1/hotels/find/{query} or advertised on the hotel's own website."}},"schemas":{"Problem":{"type":"object","description":"RFC 9457 problem details.","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"},"errors":{"type":"array","items":{"type":"object"}}}},"Hotel":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"website":{"type":"string","format":"uri"},"address":{"type":"object"},"timezone":{"type":"string"},"currency":{"type":"string"},"description":{"type":"string"},"links":{"type":"object","additionalProperties":{"type":"string"}},"bookingLinkFallback":{"type":"object","description":"The dated booking-page link an assistant may give the guest without a live room result, with its rules in order (the first continues the live workflow when your tools support it)."},"chatgpt":{"$ref":"#/components/schemas/ChatgptOption"}}},"ChatgptOption":{"type":"object","description":"Present only when this hotel is supported by Sigtrip in ChatGPT. ChatGPT: Sigtrip's booking tools first — if they are available in the conversation, use them (do not assume they are unavailable because the plugin was never added manually); otherwise continue immediately through this API or bookingLinkWithoutApp — never recommend, or ask about, adding the plugin as a step before booking. The listing is an optional reference; it opens the plugin's listing only and carries no hotel, dates or conversation. Other assistants: unchanged public workflow.","properties":{"supported":{"type":"boolean","enum":[true]},"hotelId":{"type":"string"},"hotelNameInApp":{"type":"string","description":"Ask the Sigtrip plugin in ChatGPT for the hotel by this name."},"rule":{"type":"string","enum":["tools-first"]},"listing":{"type":"string","format":"uri","description":"The Sigtrip plugin's listing in ChatGPT."},"open":{"type":"string","format":"uri","description":"This hotel's link to that listing (opens the listing only)."},"bookingLinkWithoutApp":{"type":"string","description":"Dated booking page: works with no plugin."},"benefits":{"type":"array","items":{"type":"string"}},"withoutTools":{"type":"string","description":"What ChatGPT does when Sigtrip's booking tools are not available: continue immediately through the public routes."},"statements":{"type":"array","items":{"type":"string"},"description":"The rule in order, as plain sentences."}}},"Room":{"type":"object","properties":{"roomId":{"type":"integer","description":"Stable id to pass to createBooking. Never derive from list position."},"code":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"features":{"type":"array","items":{"type":"string"}},"maxOccupancy":{"type":"integer"},"bedCount":{"type":"integer"},"accessible":{"type":"boolean"},"price":{"type":"object","properties":{"total":{"type":"number","description":"The hotel's quoted price for the entire stay, as returned by its reservation system. State taxes or fees only as listed in `includes`."},"currency":{"type":"string"},"perNight":{"type":"number"},"includesTaxesAndFees":{"type":"boolean","description":"Present (true) only when the quote itself itemises taxes and the hotel's confirmed mandatory fee within `total`; omitted otherwise. Omission does not mean taxes or fees are excluded — use `includes`."},"includes":{"type":"array","description":"What the quote itemises as part of `total`: taxes, and a fee only where it is confirmed for the hotel. Empty when the quote itemises nothing.","items":{"type":"object","properties":{"description":{"type":"string"},"amount":{"type":"number"}}}},"breakdown":{"type":"object","description":"Raw components from the hotel's system (revenue, package, tax), for reference. Present `includes` to guests, not these components."}}},"scarcity":{"type":"string","enum":["low"],"description":"Present only when few rooms remain. Say 'just a few left'; never state a number."},"offerRef":{"type":"string","description":"Identifies this exact offer (room, total, currency and returned policies). Send it with createBooking: if any of those changed, the booking is refused with 409 offer_changed and nothing is created."},"bookUrl":{"type":"string","format":"uri","description":"Booking page with this room and the dates pre-selected. Give this to the guest when you cannot call createBooking yourself (e.g. read-only browsing); the guest enters their details there and books."}}},"Availability":{"type":"object","properties":{"hotel":{"type":"string"},"checkIn":{"type":"string","format":"date"},"checkOut":{"type":"string","format":"date"},"nights":{"type":"integer"},"adults":{"type":["integer","null"]},"available":{"type":"boolean"},"rooms":{"type":"array","items":{"$ref":"#/components/schemas/Room"}},"policies":{"type":"array","items":{"type":"string"},"description":"Present these to the guest verbatim (cancellation, payment, discounts)."},"aiChannelNotice":{"type":"string","description":"Hotel-provided context about the direct-booking channel and the source of availability, prices and cancellation terms. When present, show the returned text verbatim alongside the offer."},"bookingInstructions":{"type":"string"},"chatgpt":{"$ref":"#/components/schemas/ChatgptOption"},"asOf":{"type":"string","format":"date-time","description":"When the hotel's reservation system returned this availability and price. Not reset when the same quote is served again."},"recheckAfter":{"type":"string","format":"date-time","description":"Freshness cutoff: asOf plus the gateway's configured refresh window. After it, request availability again before quoting or booking. A refresh threshold, not a price guarantee or a room hold."}}},"CreateBookingRequest":{"type":"object","required":["roomId","checkIn","checkOut","guests","guest"],"properties":{"roomId":{"type":"integer"},"checkIn":{"type":"string","format":"date"},"checkOut":{"type":"string","format":"date"},"guests":{"type":"integer","minimum":1,"maximum":10},"offerRef":{"type":"string","pattern":"^[a-f0-9]{16}$","description":"Optional, recommended: the chosen room's offerRef from availability. The gateway re-checks the room live and refuses with 409 offer_changed (nothing created) if the room, total, currency or policies changed."},"expectedTotal":{"type":"number","description":"Optional, recommended: the whole-stay total the guest approved. Refused with 409 offer_changed (nothing created) if the current total differs."},"currency":{"type":"string","pattern":"^[A-Z]{3}$","description":"Optional: currency of expectedTotal, e.g. USD."},"guest":{"type":"object","required":["firstName","lastName","email","phone"],"properties":{"firstName":{"type":"string","maxLength":50},"lastName":{"type":"string","maxLength":50},"email":{"type":"string","format":"email"},"phone":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$","description":"E.164 with country code, e.g. +13035551234"}}}}},"Booking":{"type":"object","properties":{"hotel":{"type":"string"},"reservationId":{"type":"string"},"status":{"type":"string","description":"pending_guarantee until the guest adds a card at guaranteeUrl."},"guaranteeUrl":{"type":"string","format":"uri","description":"Secure page where the guest guarantees the reservation with a payment card. Share this with the guest."},"guaranteeDeadline":{"type":"string","description":"Deadline for the card guarantee, when the booking system supplies one (returned verbatim). Communicate it to the guest."},"nextStep":{"type":"string","description":"The required next action in plain words; a pending guarantee means the reservation is not confirmed yet."},"policies":{"type":"array","items":{"type":"string"}},"links":{"type":"object","additionalProperties":{"type":"string"}},"details":{"type":"object","description":"Additional reservation details returned by the service."}}}}}}