Skip to main content

Errors

A refused request answers with an HTTP status and an RFC 9457 problem (Content-Type: application/problem+json). Branch on the status first, then on code. Never parse title or detail: they are for people.

From a service​

Most errors come from the service behind the operation:

{
"type": "https://errors.zaitrack.app/ZTK74001",
"title": "Not Found",
"status": 404,
"code": "ZTK74001",
"detail": "not found"
}
  • code is ZTK and digits. Each service has its own range, and a code keeps its meaning once published.
  • detail says what was wrong, for example vehicleId (required) and driverId must be UUIDs. A few services put the message in title and send no detail.
StatusMeans
400The body or a parameter is invalid: fix the request.
401The gateway gave the service no organisation (a gateway or configuration fault: report it).
404No such resource in your organisation. Another organisation's resource is also 404.
409The resource's state forbids the action (a device already bound, a job already dispatched).
412If-Match names a version that is no longer current: read again.
422The body names something that does not exist or is not yours (a device or driver id).
500A fault on our side: retry later and report the X-Zaitrack-Request-Id.

From the gateway​

The gateway answers before the service when a credential, scope, idempotency key or region is wrong. Its problems have a type under https://api.zaitrack.app/errors/, a dotted code and the request_id:

{
"type": "https://api.zaitrack.app/errors/scope-missing",
"title": "Required scope missing",
"status": 403,
"code": "auth.token.scope_missing",
"detail": "Missing scopes: vehicles:write",
"request_id": "…"
}
StatuscodeMeans
401auth.api_key.invalidThe key is malformed, unknown, revoked or expired.
403auth.api_key.ip_not_allowedThe key has an IP allowlist and your address is not on it.
403auth.tenant_missingThe credential is not bound to an organisation.
403auth.token.scope_missingThe credential lacks the operation's scope; detail names it.
403step_up_requiredThe operation needs a recent MFA step-up (device commands).
400idempotency.requiredThe operation needs an Idempotency-Key.
409idempotency.body_mismatchThe key was used before with a different body.
409idempotency.in_flightA request with this key is still running.
421misdirected_requestYour organisation is in another region: follow Location. See Regions.
503auth.api_key.unavailable, idempotency.unavailableA dependency of the gateway is down: retry with backoff.

Two answers are not problems:

  • An invalid or expired OAuth access token gets 401 with a WWW-Authenticate: Bearer header.
  • A request over a rate limit gets 429 with {"error_msg": "rate limit exceeded"}. See Rate limits.