Error Catalog
Every error response is { error, code, field?, meta? }. Switch on code — it is stable across releases; error is a human-readable string that may change wording without notice.
| Code | HTTP status | Meaning | What to do |
|---|---|---|---|
| SESSION_EXPIRED | 401 | refresh token exhausted | Re-authenticate — refresh or recreate your API key. |
| AUTH_REQUIRED | 401 | no token or invalid token | Re-authenticate — refresh or recreate your API key. |
| PERMISSION_DENIED | 403 | RBAC | Check the key's scopes (moduleScopes/orgScope) or your plan tier. |
| PLAN_TIER_LOCKED | 403 | not in this plan tier | Check the key's scopes (moduleScopes/orgScope) or your plan tier. |
| FEATURE_NOT_ENABLED | 403 | feature toggle off | Check the key's scopes (moduleScopes/orgScope) or your plan tier. |
| ADDON_REQUIRED | 403 | add-on missing | Check the key's scopes (moduleScopes/orgScope) or your plan tier. |
| USAGE_LIMIT_EXCEEDED | 403 | user hit a plan usage limit | Check the key's scopes (moduleScopes/orgScope) or your plan tier. |
| VALIDATION_FAILED | 400 | schema/range error | Fix the request payload/shape and retry. |
| CONFLICT | 409 | generic collision | Re-fetch current state and retry, or use a fresh Idempotency-Key. |
| TEMPLATE_HAS_INSTANCES | 409 | template has runs (from 206eef2a) | Re-fetch current state and retry, or use a fresh Idempotency-Key. |
| RATE_LIMITED | 429 | Rate limited | Back off and retry after the Retry-After header (or meta.retryAfterMs). |
| WAF_BLOCKED | 403 | Apache ErrorDocument: ModSec block | Check the key's scopes (moduleScopes/orgScope) or your plan tier. |
| WAF_MALFORMED_REQUEST | 400 | Apache ErrorDocument: ModSec parse fail | Fix the request payload/shape and retry. |
| UPSTREAM_UNAVAILABLE | 503 | Upstream unavailable | Retry with exponential backoff — this is a transient upstream issue. |
| UNKNOWN_ERROR | 4xx/5xx | legacy error response had no code | See the response body for details before retrying. |
| INSUFFICIENT_SCOPE | 403 | key's moduleScopes don't cover this route | Check the key's scopes (moduleScopes/orgScope) or your plan tier. |
| VESSEL_OUT_OF_SCOPE | 403 | key's orgScope doesn't include this vesselId | Check the key's scopes (moduleScopes/orgScope) or your plan tier. |
| INVALID_CURSOR | 400 | malformed/undecodable ?cursor= value | Fix the request payload/shape and retry. |
| VALIDATION_ERROR | 400/404/405/406/413/415 | request doesn't match openapi/v1.yaml | Fix the request payload/shape and retry. |
