Errors
The error response shape and the HTTP status codes the gateway returns, so you can handle failures predictably.
When a request fails, the gateway answers with a standard HTTP status code and a small JSON body. Handle the status code and branch on code. Log the text.
The error shape
Every error the gateway writes has the same fields:
Error
{
"error": "missing X-Revenexx-Tenant",
"code": "bad_request",
"message": "missing X-Revenexx-Tenant"
}
| Field | What it is |
|---|---|
error | The human-readable reason. Log it and show it to developers. Don't match on its wording. |
code | A machine-readable token, such as bad_request, not_authenticated, forbidden, not_found, method_not_allowed, dispatch_failed or unavailable. Branch on this. |
message | The same text as error, kept for older clients. Read error instead. |
Apps answer with the same error and code fields, and the gateway passes an app's error through unchanged. To tell a gateway refusal from an app's answer, look for the X-Capability-App response header. Debug a failed request walks through it.
Status codes
| Status | Meaning | What to do |
|---|---|---|
400 Bad Request | The request was malformed: a missing X-Revenexx-Tenant, or a body that failed the route's request schema. | Fix the request; don't retry unchanged. |
401 Unauthorized | Missing or invalid credential. | Check the API key or token; re-authenticate. |
403 Forbidden | Authenticated, but not allowed: the key belongs to another tenant, the key's scopes don't cover this route, or the user isn't a member of the tenant. | Check the tenant slug, then the scopes; don't retry as-is. |
404 Not Found | No capability matches that path for this tenant. | Check the path, and that the app providing it is installed on this tenant. |
405 Method Not Allowed | The path exists, but not for this method. | Use a method from the Allow header. |
413 Payload Too Large | An upload to a platform service route was too large. | Send a smaller body, or split it. |
429 Too Many Requests | The tenant's rate limit was exceeded. | Honor Retry-After, then back off. |
502 Bad Gateway | The app serving the route could not be reached or did not answer in time. The gateway never sends 504; a timeout is a 502 too. | Reads are safe to retry with backoff. For writes, see Retries & idempotency. |
500 Internal Server Error | The gateway itself failed on this request. | Retry reads with backoff; if it persists, get help with the request details. |
503 Service Unavailable | A platform component the route depends on is unavailable. | Check status.revenexx.com, then retry later. |
The gateway never writes 409, 422 or 504 itself. When you see one, it came from the App or platform service that serves the route, and its meaning is part of that route's contract in the API Explorer.
Send your own
X-Request-ID and log it. A refusal from the gateway itself does not echo one back, so the ID you sent is the one you can quote in a support request.Reading it in code
Handle errors
const res = await fetch(url, { headers })
if (!res.ok) {
// A gateway refusal carries no x-request-id; log the one you sent as well.
const requestId = res.headers.get('x-request-id')
const { error, code } = await res.json().catch(() => ({}))
throw new Error(`revenexx ${res.status} ${code ?? ''} (${requestId}): ${error ?? 'request failed'}`)
}