Errors
The API uses conventional HTTP status codes and a single JSON error envelope for every 4xx and 5xx. Provider
outcomes (a declined booking, a provider that timed out during a search) are reported inside 200 responses, so
always check both the HTTP status and the body.
| Where | When | Shape |
|---|---|---|
HTTP 4xx / 5xx | The request was refused or failed before any provider result | Error envelope |
HTTP 200 with error | A provider declined or failed (recheck, book, booking details, cancel) | Operation errors |
HTTP 200 with errors[] | Some providers failed during a search; the others still return offers | Search errors |
The error envelope
| Field | Type | Meaning |
|---|---|---|
error.code | string | Stable, machine-readable code. Branch on this. |
error.message | string | Human-readable explanation. Wording may change: do not parse it or show it to customers as is. |
error.provider | string | null | The provider concerned, when there is one |
error.request_id | string | Same value as the X-Request-Id header. Quote it to support. |
error.details | array | 422 validation_error only: one entry per problem |
New codes can be added within v1: treat an unknown code by its HTTP status.
{
"error": {
"code": "provider_not_enabled",
"message": "Provider 'provider_d' is not enabled for this API key",
"provider": "provider_d",
"request_id": "6f1c2a9e-0d4b-4a57-9a51-3c2f8e1d7b20"
}
}
HTTP error codes
| Status | error.code | Meaning | What to do |
|---|---|---|---|
400 | bad_request | The HTTP request could not be read | Send valid JSON with Content-Type: application/json |
401 | unauthorized | Missing, unknown, revoked or malformed API key, or a key used on the wrong environment | Check the key and the base URL. Do not retry unchanged. |
403 | provider_not_enabled | provider_context.provider names a provider your key cannot use (recheck, book, booking details, cancel) | Use an enabled provider, or ask us to enable it |
404 | booking_not_found | The booking does not exist or was not made by your account | Check provider and supplier_reference |
404 | not_found | Unknown path | Check the URL; operations are under /v1 |
405 | method_not_allowed | Wrong HTTP method | Use POST (only /health is GET) |
409 | duplicate_booking | Book: the internal_reference belongs to a booking still in progress, with an unknown outcome, or to a different request | Same request: wait and re-send it. New booking: use a new internal_reference. Nothing was booked by this call. |
409 | offer_expired | The offer_token is more than 24 hours old | Search again |
409 | currency_unavailable | The offer can no longer be priced in your search currency | Search again |
413 | payload_too_large | The body is larger than 256 KB | Send a smaller body |
415 | unsupported_media_type | The body is not JSON | Send Content-Type: application/json |
422 | validation_error | The body is invalid; see error.details | Fix the request; do not retry unchanged |
422 | unsupported_currency | The search currency is not a supported ISO 4217 code | Use a supported code |
422 | invalid_offer_token | The offer_token was changed, truncated, is missing, or belongs to another key, environment, provider or offer | Send the token unchanged with the same provider and rate_key, or search again |
422 | invalid_booking_token | The supplier_reference was changed or belongs to another key | Send the book response's supplier_reference unchanged |
429 | rate_limited | Rate limit exceeded for your key | Wait at least Retry-After seconds, then retry |
500 | internal_error | Unexpected error | Retry with backoff; for book, re-send the identical request. Report it with the request_id if it persists. |
503 | auth_unavailable | Keys cannot be verified at the moment | Retry with backoff (book: the identical request) |
503 | service_unavailable | The service cannot process the request at the moment. A book refused this way never reached the provider. | Retry with backoff (book: the identical request) |
401 responses carry WWW-Authenticate: ApiKey header="X-API-Key"; 429 responses carry Retry-After. The key
is checked before the body, so an invalid key answers 401 even when the body is also invalid.
A 502, 504 or non-JSON 503 comes from the network in front of the API and has no envelope. Treat it as
"result unknown"; for book, re-send the identical request later (Idempotency & retries).
Validation errors
An invalid body answers 422 validation_error with one entry per problem in error.details:
| Field | Meaning |
|---|---|
loc | Path of the offending field. For searches, the first element is the request type the body was read as: airport, point_to_point, hourly, or invalid. |
msg | Explanation. Rules across fields start with Value error, . |
type | Kind of problem: missing, string_type, greater_than_equal, value_error, extra_forbidden, literal_error, json_invalid, … |
The values you sent are not echoed back. A 422 is a bug in the request: fix it, do not retry.
{
"error": {
"code": "validation_error",
"message": "Invalid request: point_to_point.adults: Input should be greater than or equal to 1",
"provider": null,
"request_id": "0b7e4f7c-2f7d-4d8e-a1d3-5b8f0c9e6a11",
"details": [
{
"loc": ["point_to_point", "adults"],
"msg": "Input should be greater than or equal to 1",
"type": "greater_than_equal"
}
]
}
}
Operation errors in 200 responses
Recheck, book, booking details and cancel answer 200 when the provider declines or fails. The response's error
then holds {code, message, provider}; message often includes the provider's reason (for logs, not customers).
| Operation | error.code | Meaning | What to do |
|---|---|---|---|
| Recheck | recheck_failed | The offer can no longer be booked (expired, sold out, changed) | Search again |
| Recheck | unavailable | The offer is no longer in the provider's availability | Search again |
| Recheck | recheck_error | The recheck could not be completed | Retry once, then search again |
| Recheck | currency_unavailable | The current price cannot be given in your search currency | Search again |
| Book | book_failed | The provider declined (invalid passenger or flight data, expired, sold out). status: failed. | Fix the data or search again; do not retry unchanged |
| Book | book_error | The request never reached the provider. status: failed, nothing was booked. | Retry later with the identical request, or search again |
| Book | book_outcome_unknown | status: unknown: no answer in time after the provider received the request | Re-send the identical request later (details). Never rebook with a new reference. |
| Booking details | booking_details_failed | The provider's lookup failed | Retry later; the booking is not affected |
| Booking details | booking_details_error | The lookup could not be completed | Retry later |
| Cancel | cancel_failed | The provider declined (already cancelled, past pickup) | Check booking details |
| Cancel | cancel_error | The request never reached the provider. status: failed, nothing changed. | Retry the cancel |
| Cancel | cancel_outcome_unknown | status: unknown: no answer in time | Check booking details before cancelling again |
Search errors
A search queries several providers at once. A provider that fails or is skipped adds an entry to errors[]; the
other offers are still returned. offers: [] with errors: [] simply means nothing was found.
code | Meaning | Action |
|---|---|---|
provider_not_enabled | A provider you named in providers is not enabled for your key | Remove it, or ask us |
mode_not_supported | A provider you named does not offer this transfer type, trip type or duration | Remove it for this transfer type |
no_availability | Round trip: offers for one leg but not the other | Show the offers you have; do not retry |
city_not_mapped | The provider does not serve the pickup or drop-off city | None: others may serve it |
lead_time_too_short | The pickup is too soon for this provider (raw.min_lead_hours) | Offer a later time |
timeout | No answer within 30 seconds | Show the other offers |
provider_rejected | The provider refused the request | None |
provider_error | The provider reported a failure | Show the other offers |
search_error | Unexpected failure for this provider | Show the other offers; report if it persists |
currency_unavailable | Offers cannot be priced in your currency right now | Search later or in another currency |
{
"offers": ["..."],
"errors": [
{
"provider": "provider_b",
"code": "timeout",
"message": "No answer from the provider within 30s",
"raw": {"timeout_seconds": 30, "leg": "outbound"}
}
]
}
Logging for support
When you contact us about a request, include the X-Request-Id, the time with time zone, the endpoint, the
HTTP status, the provider, the provider's confirmation number and your internal_reference. Never send us your
API key. See Request IDs.