Skip to content

Developers

TravelCore API documentation

Written for the person who will actually integrate this, including the parts that will go wrong. The hotel surface is in design-partner preview; the rest is documented so you can design against it before it exists.

Idempotency

How to make a booking exactly once, even across network failures.

Every state-changing endpoint requires an Idempotency-Key header carrying a UUID you generate. The key is stored with the outcome for 24 hours. Replaying the same key returns the original response rather than performing the action again.

This matters because the dangerous case in travel is not the request that fails cleanly. It is the request whose response you never received. Retrying without a key risks a second booking; not retrying risks losing a booking your customer has already paid for.

The contract

  • Generate one key per logical operation, not per attempt. All retries of the same booking share a key.
  • Reusing a key with a different request body returns 422 with code idempotency_key_reuse, rather than quietly booking something else.
  • A replay returns the original status code and body, plus X-Idempotent-Replay: true.
  • Keys expire after 24 hours. After that the same key is treated as new.

Handling an unknown outcome

If a booking call times out on your side, do not assume anything. Retry with the same idempotency key. If the original succeeded you get the original booking back; if it never happened, the retry creates it. Either way you end with exactly one booking.

Node
const key = crypto.randomUUID();
 
async function book(body, attempt = 0) {
try {
return await post("/v1/hotels/bookings", body, {
"Idempotency-Key": key, // same key on every attempt
});
} catch (err) {
if (attempt < 3 && isRetryable(err)) {
await sleep(2 ** attempt * 500);
return book(body, attempt + 1);
}
throw err;
}
}