Response format, errors & rate limits
Response format, errors & rate limits
These conventions hold across every endpoint.
The response envelope
Successful responses are wrapped in a consistent envelope:
{
"code": 200,
"message": "success",
"data": { }
}
code: the HTTP status code, mirrored in the body.message: a short human-readable status.data: the payload (an object, ornull).
Lists
List endpoints return the page in results, alongside the total and the window you asked for:
{
"code": 200,
"message": "success",
"data": {
"results": [ ],
"count": 128,
"limit": 10,
"offset": 0
}
}
Errors
Errors use the same envelope, reduced to code and message:
{
"code": 400,
"message": "Invalid request body"
}
Build error handling around code and message.
Common status codes: 400 invalid request · 401 authentication failed (check you’re using Authorization: API_KEY, not Bearer) · 403 insufficient permissions or API access not enabled · 404 not found · 409 already exists · 429 rate limited · 500 server error.
Pagination
List endpoints page with query parameters:
?limit=<n>&offset=<n>
limit caps the page size (default 10, maximum 100); offset skips ahead. Use the count in the list envelope to know when you’ve read everything.
Rate limits
- Global: 60 requests per second per IP across the API.
- Sign-in endpoints: a few requests per minute per IP. These aren’t part of the
/api/v1API you call with a key.
Poll on a sensible interval (see Analysis lifecycle & polling) rather than tight-looping, and back off on 429.
Metering & quotas
Beyond rate limits, search and research consume investigation units metered against your account. Uploading and analyzing a file costs none.
When you’ve spent your monthly budget, the search call is refused with a 429, the same status as a rate limit. Read the message to tell them apart: a rate limit clears on its own and is worth retrying, an exhausted unit budget is not. How units are counted and when the budget resets is covered in Investigation units & quotas.