Error codes
RFC 9457 problem responses with a stable code, and how to handle them.
Every error is application/problem+json (RFC 9457) with a stable,
machine-readable code. Its type links to this page (https://atasumaps.com/docs/errors#<code>).
JSON — output
{
"type": "https://atasumaps.com/docs/errors#outside_coverage",
"title": "Waypoint outside the served area",
"status": 422,
"code": "outside_coverage",
"request_id": "351604bb-ba75-4856-b71c-81cbb187dbae",
"detail": "waypoint 1 is outside the served area (Kazakhstan)",
"errors": [{ "pointer": "/waypoints/1", "code": "outside_coverage" }]
}Handling errors
- Decide by
code, not bytitleordetail(those are English text for developers and may change). Unknown codes can appear in later versions: fall back to the HTTP status. - Show users your own Kazakh / Russian / English text keyed by
code. - Quote
request_idwhen you contact support. errors[].pointerpoints at the field that failed (JSON Pointer into your request).401 token_expiredfrom a tile host: the SDKs refresh the tile token themselves.429 rate_limited: wait forRetry-Afterseconds — see rate limits.503 …_unavailable: retry later with backoff; nothing was changed.- Retrying a command (any
POST/PUT/PATCH/DELETEexcept the route computations) with the sameIdempotency-Keyis always safe: the API returns the first result again.
All codes
| Code | HTTP | Meaning |
|---|---|---|
invalid_request | 400 | Body / query failed validation; see errors |
idempotency_key_required | 400 | Mutating command without Idempotency-Key |
limit_exceeded | 400 | Too many waypoints / points / matrix elements / batch items (context.max) |
future_departure_not_supported | 400 | /v1/eta departure not "now" (± 5 min) |
observation_in_future | 400 | Vote / report observed_at > 2 min in the future |
unauthenticated | 401 | No credentials |
key_invalid | 401 | Unknown or malformed API key |
key_revoked | 401 | Key revoked or expired |
token_invalid | 401 | Bad tile token / bearer signature, audience or issuer |
token_expired | 401 | Tile token or bearer token expired — refresh |
budget_exhausted | 402 | Hard budget cap reached for a product with no degraded answer |
scope_denied | 403 | Key lacks the scope, or the plan does not include the product |
key_restriction_failed | 403 | Origin / package / bundle / egress IP not allowed for this key |
forbidden | 403 | Role or organization membership missing |
user_banned | 403 | Caller is banned from contributing |
mfa_required | 403 | Admin API needs a two-factor session |
self_moderation_forbidden | 403 | Moderators cannot decide their own reports |
feature_disabled | 403 | Feature switched off (e.g. jarmaq rewards before their tests pass) |
not_found | 404 | No such resource, or not visible to the caller |
idempotency_key_reused | 409 | Same Idempotency-Key with a different request body |
version_conflict | 409 | expected_version / base_version is stale; see current_version |
invalid_state | 409 | Not allowed from the current status (e.g. reopen a non-rejected report) |
appeal_already_used | 409 | The reporter already appealed this submission once |
base_version_stale | 409 | Place changed since the edit's baseline; a moderator must rebase |
later_edits_exist | 409 | Revert of an edit that later edits depend on; use compensate |
already_claimed | 409 | Another moderator holds the claim (context.claimed_by, context.claimed_until) |
last_owner | 409 | Would leave the organization without an owner |
already_member | 409 | Invitation for an organization the caller already belongs to |
deletion_pending | 409 | A deletion request is already in progress |
place_removed | 410 | Place was reverted or hidden |
session_expired | 410 | Map session idle for more than 30 minutes — start a new one |
invitation_expired | 410 | Invitation used, revoked or expired |
payload_too_large | 413 | Upload or body too large |
unsupported_media_type | 415 | Upload type not accepted |
outside_coverage | 422 | Coordinates outside the served area (Kazakhstan) |
no_route | 422 | No route between the waypoints for this costing |
no_evidence | 422 | No evidence-backed point for the request (e.g. pickup points for an unknown building) |
unresolvable_waypoint | 422 | A place_id / entrance_id waypoint is unknown or cannot be routed to; errors[].pointer names it |
target_not_editable | 422 | A place edit targets an object outside our crowdsourced layer (OSM) |
too_far_from_report | 422 | Voter more than 1 km from the event |
event_type_disabled | 422 | Event type not enabled (e.g. police awaiting legal approval) |
upgrade_required | 426 | /v1/stream called without a WebSocket upgrade |
rate_limited | 429 | Per-key or per-user rate limit; see Retry-After |
quota_exceeded | 429 | Monthly plan quota of a product used up on a reject plan (free); Retry-After until the next Asia/Almaty month |
internal_error | 500 | Unexpected error; quote request_id |
routing_unavailable | 503 | Routing engine down; see Retry-After |
routing_busy | 503 | Routing engine overloaded right now (request not computed, not metered); retry after Retry-After |
search_unavailable | 503 | Search index down |
budget_unavailable | 503 | Budget service down — paid calls refused by default |
traffic_unavailable | 503 | Traffic proxy's cache / coalescing store down — upstream calls refused (uncoalesced fetches would burn the budget) |
auth_unavailable | 503 | Sign-in keys (Atasuai JWKS) cannot be fetched and none are cached, or sign-in is not configured — retry, do not sign the user out. On the tile and traffic edges: the key revocation list is stale (overlay, reports, traffic tiles; never basemap) |
db_unavailable | 503 | Database (or the map-session / rate-limit store) unreachable |
tiles_unavailable | 503 | Tile edge cannot reach the tile server (Martin) |