Skip to main content
The API uses conventional HTTP status codes. What varies is the shape of the error body: most routes use the standard FocusAlpha envelope, while the SEC data routes use a flat shape for compatibility with financialdatasets.ai SDKs. Handle both and you have covered the whole API.

The standard envelope

Most routes — /v1/retrieve, /v1/documents/*, /v1/companies/*, /v1/screen, news, events, market data, regional datasets, directories — return errors as:
error is the HTTP reason phrase, message is the human-readable explanation, and requestId echoes your X-Request-ID header (see below).

The SEC data envelope

The SEC data routes — /v1/filings*, /v1/financials*, /v1/financial-metrics, /v1/company/facts*, /v1/institutional-holdings, /v1/insider-trades, and /v1/_status — return a flat two-field body instead:
The canonical messages per status on these routes: When the API has something more specific to say — a validation detail, a dataset-named plan refusal — the message carries it; otherwise you get the canonical string.

Status codes

A 503 may carry a Retry-After header with a whole number of seconds. When it is present, wait at least that long before retrying — it is the server telling you exactly when capacity returns. Retrying sooner does not fail, but it will keep getting 503s.
Failed requests are not billed: a credit charged for a request that then errors is automatically refunded.

Request IDs

Every response echoes a request ID. Send your own via the X-Request-ID header and it is used as-is; omit it and one is generated for you. On standard-envelope routes the ID also appears in the error body as error.requestId.
Log the request ID with every failure, and include it when you write to support@focusalpha.ai — it lets us find the exact request in our logs immediately.

Validation behavior

The API validates every query parameter and body field, with type coercion (query strings become numbers and booleans where the parameter expects them). One behavior differs between the two route groups, and it is worth knowing before you debug:
  • Most routes are strict: a query parameter the endpoint does not recognize is rejected with 400. A typo like ?tikcer=AAPL fails loudly.
  • The SEC data routes are relaxed: unknown parameters are silently ignored, again for compatibility with existing financialdatasets.ai SDKs. A typo there does not error — it is dropped, and you get results as if you had never sent it.
On the SEC data routes, a misspelled filter silently widens your query instead of failing. If a filtered request returns more than you expected, check your parameter names first.

Rate limits

Which endpoints throttle, and why the SEC data routes signal it with 402.

Pagination

Cursor rules — including the exact 400 a malformed cursor produces.