Errors
Every error has the same shape:
{ "error": { "code": "insufficient_funds", "message": "Your wallet balance is too low for this booking. Top up and try again.", "request_id": "req_8f2c…", "details": { "required": 11368250 } } }
Branch on code, show message to developers (not always to end customers), and quote request_id to support. Every response, successful or not, carries an X-Request-Id header.
| Status | Code | Meaning |
|---|---|---|
| 400 | idempotency_key_required |
Missing Idempotency-Key |
| 401 | invalid_api_key |
Missing, wrong or revoked key (also for suspended live accounts) |
| 402 | insufficient_funds |
Wallet too small. Nothing was booked |
| 403 | wrong_environment, ip_not_allowed, missing_scope |
The key can't do this here |
| 404 | not_found, offer_not_found |
Doesn't exist, expired, or isn't yours |
| 409 | price_required, price_changed, offer_unavailable, airline_rejected, not_cancellable, not_ticketed, request_in_progress |
State conflicts. See details |
| 422 | validation_failed, passenger_mismatch, idempotency_key_reuse |
Bad input. details.fields lists each problem |
| 429 | rate_limited |
Slow down. See Retry-After |
| 503 | airline_unavailable |
The airline didn't answer. Nothing was charged |
| 500 | server_error |
Our fault. Logged. Quote the request id |
On 5xx and network errors, retry with the same idempotency key.