View .mdDownload all for AI

Errors

Errors use standard HTTP status codes and an RFC 9457 application/problem+json body:

{
  "type": "https://quickota.com/developers/errors/flights.price_changed",
  "title": "Price changed",
  "status": 409,
  "code": "flights.price_changed",
  "detail": "The airline repriced the fare above the accepted tolerance between search and booking. Nothing was booked.",
  "suggestion": "Price the offer again (or search again), show the new price to your customer and book only after they accept it.",
  "retryable": false,
  "requestId": "req_7f3a2c9e41d0b8a6c5e21f90",
  "context": { "offerTotal": { "amount": "180.00", "currency": "USD" } }
}
Field Use it for
code Branch your code on this. Stable, never renamed.
status The HTTP status, repeated.
title, detail Human-readable; wording may change. Safe to log, not to parse.
suggestion What to do next.
retryable true when the same request may succeed later without changes.
requestId Quote it to support — we can find the exact request.
errors For request.validation_failed: field → messages, e.g. "passengers[0].birthDate": ["…"].
context Extra data for some codes (shortfall amounts, current status, allowed actions).
type Link to this code's documentation page.

Handling errors — a checklist

  1. 4xx with retryable: false — fix the request or the flow. Retrying the same call will fail the same way.
  2. 429 — wait Retry-After seconds. See Rate limits.
  3. 5xx or retryable: true — retry with exponential backoff (e.g. 1 s, 2 s, 4 s … max 5 tries). For writes, send the same Idempotency-Key so a retry can never book or ticket twice. See Idempotency.
  4. Timeout with no response on issue — do not call issue with a new key. GET the booking: if it is issuing or ticketed, the first call worked. See Managing booking states.
  5. Log requestId for every error.

We never put supplier names, stack traces or internal messages in errors; support can see them from the requestId.

Machine-readable catalog

  • https://quickota.com/developers/errors.json — every code with status, title, description, resolution and retryable.
  • https://quickota.com/developers/errors/{code} — one page per code.

The full list follows.

All error codes

auth.*

Code HTTP When it happens What to do Retry
auth.endpoint_not_allowed 403 API keys can only call documented public endpoints under the public base URL. Check the path against the API reference. no
auth.insufficient_scope 403 The key does not carry the scope this endpoint needs (for example flights:book to create bookings). Edit the key in the panel and add the scope named in context.requiredScope, or use a key that has it. no
auth.invalid_key 401 The key is malformed, was mistyped, or never existed. Copy the key again from the panel. A key is shown only once when it is created — if it is lost, create a new one and revoke the old one. no
auth.ip_not_allowed 403 The key has an IP allow-list and the request came from an address that is not on it. Call from an allowed server, or add this server's public IP (or CIDR range) to the key's allow-list in the panel. no
auth.key_expired 401 The key had an expiry date and it has passed. Create a new key (or rotate the expired one) in the panel. no
auth.key_revoked 401 The key was revoked by your agency or by platform support, or it was replaced by a rotation whose grace period ended. Use the current key from the panel, or create a new one. no
auth.missing_key 401 The request has no Authorization: Bearer <key> header, or it carries a panel login token instead of an API key. The public API only accepts API keys. Create a key in your panel under Developers → API keys and send it as Authorization: Bearer tam_live_…. no

account.*

Code HTTP When it happens What to do Retry
account.agency_inactive 403 Your agency account is deactivated on the platform. Contact platform support. no
account.api_suspended 403 API access for your agency was suspended — usually because usage limits or the look-to-book ratio were breached, or on request of platform support. Contact platform support. Your panel stays available; only API access is paused. no
account.insufficient_balance 402 The wallet balance does not cover the amount due. context carries required, available and shortfall. The booking hold is kept until it expires. Top up the wallet (panel → Finance) and call the same endpoint again before the hold expires. Check GET /account/balance before issuing to avoid this. no
account.module_not_installed 403 Your agency has not activated the module this endpoint belongs to, or the Developer API module itself. Activate the module from your panel's module store, or contact your account manager. no
account.wallet_currency_mismatch 409 The booking currency differs from your wallet currency. Search with currency set to your wallet currency (see GET /account/balance). no
account.wallet_unavailable 503 The payment could not be taken from your wallet for a reason other than balance (wallet missing or temporarily unavailable). Nothing was charged. Retry later; contact support if it persists. yes

request.*

Code HTTP When it happens What to do Retry
request.conflict 409 Another request changed the same resource at the same moment. Fetch the resource again and retry if the action is still needed. yes
request.invalid_state_transition 409 The action does not apply to the resource's current status (for example issuing a booking that is already cancelled). context.currentStatus and context.allowedActions describe what is possible now. Fetch the resource and follow its nextActions. no
request.malformed_json 400 The body is not valid JSON or does not match the expected shape. Send Content-Type: application/json with a body matching the API reference. no
request.not_found 404 The id does not exist, or it belongs to another agency. Check the id, and that it was created with a key of the same agency. no
request.validation_failed 422 One or more fields are missing or invalid. errors maps each field path to its messages. Fix the listed fields and send the request again. no

idempotency.*

Code HTTP When it happens What to do Retry
idempotency.in_progress 409 The first request with this key has not finished yet. Wait a few seconds and retry with the same key — you will receive the original result. yes
idempotency.key_required 400 This endpoint creates something that must never happen twice (a booking, a ticket), so it requires an Idempotency-Key header. Send a unique value (a UUID is ideal) in Idempotency-Key. Reuse the same value when you retry the same operation. no
idempotency.key_reused 422 The key was already used for a request with a different method, path or body. Generate a new key for every new operation; reuse a key only to retry exactly the same request. no

rate_limit.*

Code HTTP When it happens What to do Retry
rate_limit.exceeded 429 Too many requests in a short time for this key. X-RateLimit-* headers show the limit and when it resets. Wait for the number of seconds in Retry-After, then retry. Spread calls out and cache search results. yes

quota.*

Code HTTP When it happens What to do Retry
quota.look_to_book_exceeded 429 Your agency searches far more than it books. Searching is paused until the ratio recovers; booking endpoints keep working. Reduce repeated or automated searches (cache results, avoid price scraping) and convert more searches into tickets. Contact support if you believe this is wrong. yes
quota.searches_daily_exceeded 429 Your agency used all searches allowed for today. Wait until the quota resets (00:00 UTC) or ask your account manager for a higher quota. Cache results instead of repeating identical searches. yes
quota.searches_monthly_exceeded 429 Your agency used all searches allowed for this month. Wait until the next month or ask your account manager for a higher quota. yes

flights.*

Code HTTP When it happens What to do Retry
flights.booking_not_serviceable 409 Post-booking requests need a ticketed booking that has not been fully cancelled or flown. Check the booking's status and nextActions. no
flights.cancellation_not_allowed 409 The fare rules do not allow cancelling or refunding at this time. Check the fare rules. A no-show refund of taxes may still be possible through a post-booking request. no
flights.duplicate_booking 409 An identical booking already exists (same offer or same request). Look the existing booking up with GET /flights/bookings?agencyReference=… before booking again. no
flights.exchange_rate_unavailable 503 No exchange rate is configured between the fare currency and your wallet currency, so the fare cannot be priced safely. Search in your wallet currency, or contact support to configure the rate. no
flights.fare_not_available 409 The seats at this fare were sold between search and booking. Search again and pick another flight or fare. no
flights.hold_expired 409 The seats were released because the booking was not issued before deadlines.holdExpiresAt. The booking is now cancelled. Search and hold again, then issue before the hold expires. no
flights.hold_not_supported 409 The airline issues this fare the moment it is booked (typical of low-cost carriers), so it cannot be held and paid later. The price check shows it as hasFlightHold: false. Nothing was booked. Pick a fare with hasFlightHold: true, or book this one through the agency panel, which books and pays in one step. no
flights.invalid_search 422 The search criteria are incomplete or impossible: missing airports, a date in the past or more than a year ahead, no adult, more infants than adults, more than 9 seated passengers, or more than 6 legs. Fix the fields listed in errors and search again. no
flights.itinerary_not_bookable 409 The airline refused the itinerary (schedule changed, flight closed or cancelled). Search again. no
flights.offer_already_booked 409 Each offer can be held once. This one already produced a booking (see context.bookingId). A retry of the same hold should reuse the same Idempotency-Key, which returns the original booking instead of this error. Use the existing booking, or search again for a new offer. no
flights.offer_expired 410 The offer's validity window (expiresAt) has passed, or the airline no longer recognises it. Fares change constantly, so offers are short-lived. Search again. Price (POST /flights/offers/{offerId}/price) and hold soon after searching. no
flights.offer_not_found 404 The offerId is unknown. Offers belong to the agency that searched them and are kept for at most 30 minutes. Search again and use an offerId from the new results. no
flights.passenger_data_invalid 422 A passenger is invalid: no adult on the booking, a child or infant without birth date, a passenger type that does not match the age, a missing or expired passport on an international trip (a national ID is accepted on domestic trips only), or a placeholder name such as TEST. Names must be in Latin letters exactly as on the travel document. Correct the passenger listed in detail and hold again with a new Idempotency-Key. no
flights.price_changed 409 The airline repriced the fare above the accepted tolerance between search and booking. Nothing was booked. Price the offer again (or search again), show the new price to your customer and book only after they accept it. no
flights.quote_expired 409 The post-booking quote was not accepted before its expiresAt. Wait for a new quote (support may re-quote) or create a new request. no
flights.schedule_change_not_supported 409 The airline for this booking does not accept schedule-change replies through the API. Contact support to handle this schedule change. no
flights.servicing_request_open 409 This booking already has an open post-booking request for these passengers. Follow the open request (openServicingRequests on the booking) to its end, or withdraw it first. no
flights.supplier_timeout 504 The airline's reservation system was too slow. For a hold, nothing was booked unless the booking appears in GET /flights/bookings?agencyReference=…. Retry with the same Idempotency-Key after a few seconds. yes
flights.supplier_unavailable 503 The airline connection is temporarily unavailable or refused the request for a reason on its side. Retry later, or search again for other options. yes
flights.ticket_not_issued 409 The e-ticket document exists only once the booking is ticketed. Wait for the booking to become ticketed, then download the ticket. no
flights.ticketing_pending 409 The airline is still issuing the tickets. This is normal for some airlines and can take up to several minutes. Do not call issue again. Wait for the flight.booking.ticketed webhook, or poll GET /flights/bookings/{id} every pollAfterSeconds. yes
flights.use_post_booking_request 409 A ticketed booking cannot be cancelled directly: the airline's refund or void conditions apply and must be quoted first. Create a post-booking request (POST /flights/bookings/{id}/post-booking-requests) of type refund or void, wait for its quote, then accept it. no

webhooks.*

Code HTTP When it happens What to do Retry
webhooks.endpoint_not_found 404 The webhook endpoint id does not exist in this environment. List your endpoints with GET /webhook-endpoints. no
webhooks.url_not_allowed 422 Webhook URLs must be public https:// addresses. Private, loopback and internal network addresses are refused. Use a publicly reachable HTTPS URL. no

server.*

Code HTTP When it happens What to do Retry
server.internal_error 500 Something failed on our side. Nothing about your request is wrong. Retry later. If it persists, contact support and quote the requestId. yes
server.maintenance 503 The API is in maintenance or overloaded. Retry after the number of seconds in Retry-After. yes