| 400 Bad Request | Request shape / values rejected before any business logic | Missing required field, wrong type, malformed JSON | Inspect error.message; for the SDK, also catch ValidationError |
| 401 Unauthorized | Auth header missing, malformed, or revoked | Forgot Authorization / X-API-Key header; key rotated; OAuth token expired and refresh failed | Verify credentials. If you’re on MCP and pasting a CLI OAuth token, see OAuth, wrong issuer |
| 403 Forbidden | Authenticated but not allowed | Endpoint requires a higher tier; account inactive | Check the dashboard for account status; reach out if surprised |
| 404 Not Found | Resource doesn’t exist OR (on guest endpoints) credentials don’t match | trip_id typo; booking_ref + last_name pair doesn’t resolve | Verify the ID. On get_booking and refund/exchange guest paths, “not found” is intentionally indistinguishable from “wrong last_name”, don’t leak existence |
| 409 Conflict | State doesn’t allow the operation | Trying to add an item to a fulfilled trip; double-checkout on a quoted trip | Re-fetch state with getTrip before retrying |
| 422 Unprocessable Entity | Validated and authorized, but the upstream rejected | Provider says no inventory; price changed beyond tolerance | Re-run discovery / live pricing; the offer is stale |
| 429 Too Many Requests | Rate limit | Free tier is 1,000 requests / 30 days per API key | Wait, or email dev@gojinko.com for a quota bump |
| 500 Internal Server Error | We blew up | Bug, missing env var, a downstream provider’s outage we didn’t degrade gracefully | Capture the X-Request-ID from your response headers and report, see below |
| 502 / 503 / 504 | Upstream provider failure | TravelFusion / Sabre / Nuitée timed out or returned a bad response | Retry once after a small delay; if it persists, the provider is down |