Getting Started
Request Conventions
The rules that hold across every endpoint: addressing, pagination, idempotency, partial results, limits and timeouts.
Base URL and Versioning
All client endpoints live under a single versioned prefix. The version is in the path, so a
future /api/v2 can appear without disturbing anything you have built.
Requests and Responses
- Request bodies are JSON and need
Content-Type: application/json. Responses are always JSON, including errors. - Dates are
YYYY-MM-DD. Timestamps are ISO 8601 with an offset. - Currencies are ISO 4217 three-letter codes; countries and nationalities are ISO 3166 two-letter codes.
- Monetary amounts are JSON numbers in the stated currency's major unit —
164.00is one hundred and sixty-four dollars, not cents. - Fields the API does not recognise are ignored, not rejected, so a misspelt optional field does nothing rather than failing. Check spelling against the endpoint's page.
Identifiers
propertyIduuid optional- A Gateway Stream property id. Stable within an environment, meaningless across environments. Returned by
/propertiesand/search. rateKeystring optional- An opaque, single-use handle on one priced rate. Valid for about 30 minutes. Never parse it.
bookingIduuid optional- A Gateway Stream booking. What
/bookings/:idtakes. requestIdstring optional- Carried on every error. Quote it when asking Gateway Stream about a specific failure.
Pagination
List endpoints are cursor-paginated. Ask for a page, and if there is more, the response carries
a nextCursor; pass it back as cursor to continue. When nextCursor is absent, you have reached the end.
Idempotency
POST /bookings requires an Idempotency-Key header: a value between 8
and 100 characters that is unique to that attempt to book. A UUID is the obvious choice.
- First request with a given key →
201and the new booking. - A repeat of the same request with the same key →
200and the same booking. Nothing is created twice.
So a timeout or a dropped connection is safe to retry: resend the identical body with the identical key. What is never safe is retrying with a new key, or a new rate key, after an ambiguous answer — see Book.
Partial Results, Not Failures
Search and property listing ask several sources at once. One being slow, switched off or broken
does not fail the call: the results that arrived are returned, and meta.complete says whether anything may be missing.
meta.complete
trueboolean optional- Every source answered. The result is whole.
falseboolean optional- At least one source did not answer inside the request’s timeout, or failed. What came back is real, but some rates or hotels may be missing. It does not say which source, or why — try again, or raise
timeoutMson a search.
Show the rates you got and treat complete: false as “there may be more”, not as “there
is nothing”. Blocking a whole page on one slow source is the most common avoidable mistake in an integration.
Timeouts
POST /search takes an optional timeoutMs — how long to wait for the
sources, between 1 and 8000 milliseconds, defaulting to 2500. It is a budget, not a
promise of speed: whatever has answered when it elapses is what you get.
Set your own HTTP client's timeout comfortably above it. A client timeout shorter than timeoutMs throws away results the server was about to return.
Rate Limits
Requests are rate-limited per key. Over the limit you get 429 with details.retryAfterSeconds; back off for that long rather than retrying immediately.
If your traffic pattern needs a higher ceiling, that is a conversation with Gateway Stream rather than something to work around with parallel keys.