> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dev.gojinko.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors & troubleshooting

> HTTP status codes, error envelope, and what to do when things go sideways.

Every Jinko endpoint returns errors as JSON in a consistent envelope:

```json theme={null}
{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "departure_date must be in the future",
    "details": { "field": "departure_date" }
  }
}
```

The SDK converts these to `ApiError` (or its subclasses `AuthError` / `ValidationError`), see [SDK error handling](/connect/sdk#error-handling).

## Status code reference

| Status                        | When                                                                   | Common causes                                                                                    | What to do                                                                                                                                                    |
| ----------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **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](/authentication/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](mailto: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                                                                                          |

## Reporting issues

Every response includes an `X-Request-ID` header (also visible in SDK logs as `X-Request-ID`). Capture it and include in any bug report, we use it to find the exact request server-side in Datadog.

```bash theme={null}
curl -i ... | grep -i x-request-id
```

```typescript theme={null}
try {
  await client.findFlight(...)
} catch (err) {
  if (err instanceof ApiError) {
    console.error('Request ID:', err.requestId)  // include this when reporting
  }
}
```

Email: [dev@gojinko.com](mailto:dev@gojinko.com).

## Common gotchas

### "I get 401 on the MCP endpoint with a token that worked yesterday"

If the token came from `jinko auth login`, it's a CLI OAuth token (issuer = Jinko Auth user pool). MCP expects either an API key or an MCP-OAuth JWT (issuer = AuthKit). They look similar but trip the issuer check. Use `jnk_*` for programmatic MCP access.

### "Trip says 'fulfilled' but I never got a confirmation"

Confirmation emails go via Resend. If the user's email is correct on the trip's `contact` and the booking status is `completed`, check spam. If the status is stuck on `fulfilling` for more than \~6 hours, the upstream provider is slow, common on TravelFusion when the airline is laggy.

### "trip\_item\_token rejected with 'expired'"

`trip_item_token`s have a TTL (\~30 minutes for flights, shorter for some hotel rates). If the user takes a long time on traveler entry, re-run live pricing (`flight_search` / `hotel_search`) before adding to a trip.
