Errors and limits
How the Soundwaves API reports errors, and the rate and query limits it enforces.
Errors
Errors follow the GraphQL spec: a response has an errors array, and each error carries a machine-readable extensions.code. Branch on the code, not the message.
{
"errors": [
{
"message": "Insufficient permissions",
"extensions": { "code": "FORBIDDEN" }
}
],
"data": null
}| Code | Meaning |
|---|---|
UNAUTHENTICATED | No valid credential was sent, or it has expired. |
FORBIDDEN | The credential is valid but lacks a permission or add-on the field needs. |
STEP_UP_REJECTED | The action needs you to re-confirm your identity first. |
BAD_USER_INPUT | An argument was invalid. The message says which. |
VALIDATION_ERROR | The input failed a business rule. |
SITE_CONTEXT_REQUIRED | A public query couldn’t tell which site it was for. |
RATE_LIMITED | Too many requests. Wait extensions.retryAfterSeconds and retry. |
SERVICE_UNAVAILABLE | A dependency is temporarily unavailable. Retry with backoff. |
Internal error details are never returned. If you hit something unexpected, email us the time and operation and we’ll look it up.
Rate limits
Each credential gets its own allowance, on top of a per-IP limit:
| Limit | |
|---|---|
| Queries | 100 per minute per credential |
| Mutations | 20 per minute per credential |
| All requests | 100 per minute per IP |
Rate-limited requests return HTTP 429 with a Retry-After header and a RATE_LIMITED error.
Query limits
To keep the API fast for everyone, very large or deeply nested queries are rejected before they run. Keep queries focused: request the fields you need, page through lists, and avoid repeating the same field under many aliases.