Skip to main content

Idempotency & retries

Networks fail and providers can be slow. The API is designed so that you can always retry without booking twice.

Book is idempotent per internal_reference​

Every book carries your own order reference in internal_reference. Use one unique value per booking (per leg for round trips). We record the attempt before calling the provider, so re-sending the same request is safe:

You send book again with the same internal_reference and…Result
the same request, and the first booking succeeded (completed, pending, or since cancelled)200 with the original response and header Idempotent-Replayed: true. No second booking, even after the offer token has expired.
the same request, and the first attempt failedA new attempt (nothing was booked the first time)
the same request, while the first is still running or its outcome is unknown409 duplicate_booking. Nothing is booked. Wait and send it again.
a different request (other offer or travellers)409 duplicate_booking. Use a new internal_reference for a new booking.

"The same request" means the same provider, rate_key and travellers.

Replayed response
HTTP/1.1 200 OK
Idempotent-Replayed: true
X-Request-Id: 9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d
Content-Type: application/json

{"status": "completed", "supplier_booking_ref": "PRV0000001", "...": "original response"}
409 duplicate_booking
{
"error": {
"code": "duplicate_booking",
"message": "A booking with this internal_reference is in progress; retry this request later",
"provider": null,
"request_id": "5e4f3a2b-1c0d-4e9f-8a7b-6c5d4e3f2a1b"
}
}

When book times out or answers unknown​

A book can end without a definite answer: a client timeout, a network error, a 5xx, or status: unknown with error.code: book_outcome_unknown (the provider received the request but did not answer in time). A booking may exist. An unknown response has an empty supplier_reference, so there is nothing to look up yet. We are notified and reconcile every unknown booking with the provider.

  1. Mark the order "booking being confirmed". Do not charge or confirm the customer yet.
  2. Re-send the identical book request (same internal_reference, provider_context and travellers) with backoff, for example after 1, 5 and 15 minutes. You get one of:
    • the booking (completed or pending, Idempotent-Replayed: true) with its supplier_reference: continue with booking details as usual;
    • failed: nothing was booked; you can recheck and book again;
    • 409 duplicate_booking: the outcome is still being confirmed; keep waiting.
  3. Still 409 after about 30 minutes? Contact success@pathfndr.io with the internal_reference and the X-Request-Id of the first attempt.
Never rebook with a new reference

Do not send a new internal_reference, or book another offer for the same order, while an outcome is unknown. That is the one way to create a duplicate booking.

200 OK, status unknown
{
"status": "unknown",
"supplier_booking_id": null,
"supplier_booking_ref": null,
"supplier_reference": {},
"total_price": null,
"currency": null,
"booking_details": {},
"error": {
"code": "book_outcome_unknown",
"message": "The booking outcome could not be confirmed with the provider. Do not book again: retry the same request (same internal_reference) later, or contact support with the request_id",
"provider": "provider_a"
}
}
import time

def book_with_retries(payload):
"""Re-send the identical request until the outcome is known."""
for delay in (0, 60, 300, 900):
time.sleep(delay)
try:
r = requests.post(f"{BASE_URL}/v1/transfer/book", json=payload,
headers=HEADERS, timeout=150)
except requests.RequestException:
continue # outcome unknown: same request again
if r.status_code == 409: # still being confirmed
continue
if r.status_code >= 500:
continue
body = r.json()
if body.get("status") != "unknown":
return body # completed, pending or failed
raise RuntimeError("Outcome still unknown: contact support")

Retry guidance per call​

CallSafe to retry?Guidance
SearchYesRetry on network errors, 429 (after Retry-After) and 5xx with backoff (1 s, 2 s, 4 s; at most 3 attempts). A per-provider failure in errors[] is not a reason to retry the whole search.
RecheckYesRead-only.
Booking detailsYesRead-only.
BookOnly the identical requestNever automatically with a new internal_reference. Follow the steps above.
CancelYes, after checkingA booking we already cancelled is answered from our records (Idempotent-Replayed: true) without calling the provider again. After a timeout, 5xx or status: unknown, call booking details first and cancel again only if the booking is still confirmed or pending.

Never retry 401, 403, 404, 413 or 422 without changing the request. A 200 with status: failed is a definite failure, so it is safe to recheck and book again.

Recommended client timeouts: search 60 s; recheck, booking details and cancel 100 s; book 150 s (a provider can take up to about 135 s to confirm).