Errors
Status codes returned by the Data API and what they mean.
The Data API separates two kinds of failure:
- HTTP errors (4xx / 5xx): the request could not be served — a missing key, a lapsed plan, a rate limit, a malformed body, a server fault.
- Tool-level misses (HTTP 200): the request was valid and ran, but there
is nothing to return, or a data source behind it failed. The body carries
an
errorfield instead of data.
HTTP error body
HTTP errors return this envelope:
{
"error": "Missing API key. Send 'Authorization: Bearer clf_…'.",
"status_code": 401,
"path": "/api/v1/data/filings/search",
"correlation_id": "6f1c2b0e-8a4d-4c3e-9b7a-2d5e1f0a9c11"
}correlation_id is also sent as the X-Correlation-Id response header.
Quote it when you contact support. If you send an X-Request-Id header, we
use your value as the correlation id instead of generating one.
422 validation errors add two fields: detail, a single string joining
every problem, and details, the same problems as a list:
{
"error": "Validation error",
"status_code": 422,
"path": "/api/v1/data/companies/compare",
"detail": "body -> companies: Field required (type: missing)",
"details": ["body -> companies: Field required (type: missing)"],
"correlation_id": "6f1c2b0e-8a4d-4c3e-9b7a-2d5e1f0a9c11"
}A few responses are produced before the request reaches the API and carry
only {"detail": "…"}: unknown paths and wrong methods (404, 405),
bodies over 2 MB (413), blocked client addresses (403) and the
server-side timeout (504). Handle a body that has detail but no error.
Status codes
| Code | Meaning | What to do |
|---|---|---|
200 OK | Request succeeded. Body may still be a tool-level miss. | Check for error before treating the body as data. |
400 Bad Request | Idempotency-Key header longer than 200 characters. | Shorten the key. Do not retry unchanged. |
401 Unauthorized | Missing, unknown, revoked or expired API key. | Send Authorization: Bearer clf_…. Rotate a leaked key. |
402 Payment Required | The key's owner has no active plan or trial that includes API access. | Renew or upgrade the subscription; the key starts working again. |
403 Forbidden | Request blocked before reaching the API ({"detail": "Access denied."}). | Contact support with your client IP. |
404 Not Found | Path does not exist (typo, wrong version). | Check the API reference. |
413 Payload Too Large | Request body over 2 MB. | Send a smaller body. |
422 Unprocessable Entity | Body or query failed validation, or an Idempotency-Key was reused with a different body. | Read detail; fix the request, or use a fresh idempotency key. |
429 Too Many Requests | Rate limit or monthly quota exceeded. | Honour Retry-After; see Rate limits. |
500 Internal Server Error | Unexpected server fault. The message is always Internal server error. | Retry with backoff. Quote correlation_id if it persists. |
503 Service Unavailable | Planned maintenance. Body: {"error": "Service Unavailable", "detail": "…", "maintenance": true, "retryable": true}. | Retry after the Retry-After interval. |
504 Gateway Timeout | The request ran longer than the server allows. | Retry with backoff, narrow the query. |
Tool-level misses
Every endpoint reports a miss as HTTP 200 with an error string in the
body, usually paired with a machine-readable failure_kind. Extra fields
that explain the miss (the input you sent, a hint, suggested alternatives)
may sit alongside. Two shapes differ slightly:
/filings/{page_id}/snapshotreports a page it cannot resolve as"available": falsewith areason, not aserror.- A quarterly
/statementrequest for a Nordic company returns"error": "quarterly_line_items_not_available"with anexplanationand nofailure_kind.
{
"error": "No analytical profile generated yet for this company",
"failure_kind": "not_found",
"company": "UnknownCo",
"resolved_name": null,
"cik": null,
"ticker": null,
"locale": "en",
"alternatives": ["…"],
"hint": "…"
}Branch on failure_kind when it is present, not on the error text.
Common values:
failure_kind | Meaning | Retry? |
|---|---|---|
not_found | The query ran; there is no data for this company, period or filter. | No |
validation_error | The arguments passed HTTP validation but the combination cannot be served. | No — fix the request |
upstream_unavailable | A data source behind the endpoint was unavailable. | Yes, with backoff |
missing_dependency | A server-side component the endpoint needs was not available. | Yes, with backoff |
search_upstream | The full-text search backend returned an error. | Yes, with backoff |
invocation_error | An internal step failed while building the answer. | Yes, with backoff |
Treat any value not listed here like invocation_error. A miss is still a
served request and counts against your monthly quota.
Idempotency and retries
All Data API endpoints are read-only. Every successful response is a
function of the request parameters at the moment of the call, so retries
are safe. Use exponential backoff for 429 and 5xx codes so you do not
amplify a temporary upstream outage. On POST endpoints, send an
Idempotency-Key header to replay the original response for a retry
without spending quota.
"No data" vs. "error"
This separation lets clients tell the request was fine but there is
nothing to return (200 + error + failure_kind) apart from the request
itself was rejected (4xx / 5xx + the error envelope).