Errors and rate limits
This page describes how the API reports errors, which HTTP status codes to expect, and how to handle rate limits and correlation IDs for debugging.
Error response shape
User-facing errors return a JSON body with a stable shape:
{
"key": "api-errors.ticketNotFound",
"params": { "ticketId": "..." },
"fallbackMessage": "Ticket not found."
}
- key — Localization key (e.g. for
api-errorsnamespace). Use it for client-side translation. - params — Optional object for interpolation (e.g. IDs).
- fallbackMessage — Human-readable message in the API’s default locale. Safe to show if you don’t translate by key.
Correlation ID
The API may include an x-correlation-id response header on all responses (including errors). Use it when contacting support or debugging; the server echoes the value you send in the request or generates one if omitted.
HTTP status codes
| Code | Meaning |
|---|---|
| 200 | OK (e.g. GET, PATCH, or POST that returns data). |
| 201 | Created (e.g. POST ticket, template). |
| 204 | No content (e.g. DELETE success). |
| 400 | Bad request — invalid body, missing or invalid params. |
| 401 | Unauthorized — missing or invalid Bearer token. |
| 403 | Forbidden — token valid but not allowed (e.g. wrong workspace or insufficient role). |
| 404 | Not found — resource does not exist or not in this workspace. |
| 429 | Too many requests — rate limit exceeded. See below. |
| 5xx | Server error — retry with backoff. |
Rate limits
- Global — 500 requests per 15 minutes per IP (approximate). When exceeded, the API responds with 429 and the same error shape (
key,params,fallbackMessage). A Retry-After header may be set (seconds). - Attachments — Per-workspace upload and download limits may apply (e.g. per hour). 429 with an appropriate error key when exceeded.
- Per-endpoint limits — Not specified; the above global and attachment limits are the main ones documented.
Rate limits
Always handle 429 by backing off and respecting the Retry-After header when present.