Errors & Rate Limits
Error format
All errors return a JSON body:
json
{
"message": "Human-readable description",
"code": "MACHINE_READABLE_CODE"
}Authentication errors include an additional authenticated field:
json
{
"message": "Invalid API key",
"code": "INVALID_API_KEY_EXCEPTION",
"authenticated": false
}HTTP status codes
| Status | Meaning |
|---|---|
400 Bad Request | Missing required fields, invalid values, or constraint violations |
401 Unauthorized | Missing or invalid API key |
403 Forbidden | Authenticated, but not permitted to perform this action |
404 Not Found | Resource does not exist or is not reachable with your current permissions |
429 Too Many Requests | Rate limit exceeded |
500 Internal Server Error | Unexpected server error |
Rate limits
Each endpoint is assigned a tier that determines its rate limit. Counters are per-route and shared across all API keys owned by the same account.
| Tier | Limit | Window | Block duration |
|---|---|---|---|
| Tier 1 | 5 requests | 5 minutes | 30 minutes |
| Tier 2 | 5 requests | 1 minute | 10 minutes |
| Tier 3 | 20 requests | 1 minute | 10 minutes |
| Tier 4 | 60 requests | 1 minute | 10 minutes |
Every response includes these headers:
| Header | Description |
|---|---|
x-ratelimit-limit | Maximum requests per minute |
x-ratelimit-remaining | Requests remaining in the current window |
x-ratelimit-reset | Timestamp when the window resets |
When blocked, only x-ratelimit-reset is returned alongside the 429 status.