Every error is an RFC 9457 Problem Details body (application/problem+json), the Problem schema every endpoint shares. Branch on code (a closed enum), never on the human title or detail. trace_id equals the x-trace-id response header; quote it when reporting an issue.
Codes
The list is closed, so a value your client does not recognise means the client is older than the API: fall back to the HTTP status.
code |
Status | Means | What to do |
|---|---|---|---|
validation_failed |
400 | A parameter or body field was rejected before any work happened. | Read detail, which names the field and the fix. Do not retry the same request unchanged. |
invalid_token |
401 | No bearer token, or one that is expired or not accepted. | Get a fresh access token and retry once. With the CLI, wego login. |
insufficient_scope |
403 | The token is valid but lacks a scope this operation needs. | Re-authorize asking for the required scope, then retry. |
not_found |
404 | On a search-scoped id, usually an expired id rather than a wrong one: every searchId, trip id, fare id and rate id is opaque, context-bound and short-lived. On a hotelId, which does not expire, it means the hotel is unknown. |
For a search-scoped id, create a new search and rethread the ids from it; retrying the same id never recovers. For a hotelId, check the id: searching again will not help. |
rates_require_hotel_search |
409 | getHotelRates was given a searchId from a city or geo search. Only a search created with hotelId prices a hotel’s full room list; a city search holds a sample of it, and re-reading never deepens that sample. |
Create a search with hotelId plus the same dates and occupancy, then read its rates. With the CLI, wego hotels rooms <hotelId> <checkIn> <checkOut>. |
rate_limited |
429 | You exceeded a quota. | Wait Retry-After seconds; it takes precedence over the reset in RateLimit. Creating a search is the costly step, so thread one searchId through results rather than re-creating. |
bad_gateway |
502 | A travel provider answered with something the API could not use. | Retry once. If it persists, quote trace_id. |
upstream_unavailable |
503 | A travel provider is temporarily unreachable. | Honor Retry-After and retry. |
upstream_rate_limited |
503 | A travel provider’s own rate limit rejected the call. That quota is shared across callers, so you can hit it without having sent much yourself. | Wait the full Retry-After (60 seconds). If the retry gets the same error, wait the new Retry-After again: the provider also enforces a longer window, so one wait is not always enough. Pace search creation rather than bursting. |
internal_error |
500 | A fault on the API side. | Retry once, then quote trace_id if it persists. |
status repeats the HTTP status and title is fixed per code, so neither carries information code does not. Only detail varies per occurrence, and it is written for a human reader.