/api/v1/xbrl/filing/{accession}/statementsRebuild one filing's face financial statements from its own raw XBRL — as filed, with structure.
Rebuild one filing's face financial statements from its own raw XBRL — as filed, with structure.
Why use this
Common use case
Rebuilds a single filing's face statements from its own raw XBRL — the presentation structure the SEC's flat companyfacts summary discards. Returns the assembled finradar_v1 artifact: each statement is a columns[] x rows[] matrix — the period columns and the ordered concept rows with depth, preferred_label_role, abstract, and a values[] array aligned to the columns. For full per-fact fidelity (each fact with its decimals/unitRef and dimensions) use GET /api/v1/xbrl/facts. Bound the response with the repeatable statement= filter. A filing not yet in the engine returns 404 NOT_COVERED (distinct from NOT_FOUND); a present-but-not-yet-assembled filing returns 404 NOT_FOUND. List a filing's statements first with GET /api/v1/xbrl/filing/{accession}/index.
Parameters
| Name | In | Required | Default | Allowed | Description | Example |
|---|---|---|---|---|---|---|
| accession | path | required | — | — | SEC accession number of the 10-K / 10-Q. Dashed (`0000950170-25-100235`) or 18-digit no-dash form both resolve; anything else -> 400 INVALID_PARAM (rejected before any query). A filing not yet in the engine (historical depth loads incrementally) -> 404 NOT_COVERED; a filing that IS present but whose statements are not yet assembled -> 404 NOT_FOUND. | 0000950170-25-100235 |
| statement | query | optional | — | — | Optional, repeatable — restrict to one or more statements (case-insensitive). Match by the statement's own slot (`StatementsOfIncome`, `BalanceSheets`, `StatementsOfCashFlows`, `StatementsOfComprehensiveIncome`, `StatementsOfShareholdersEquity`) OR by a short canonical alias: `income`, `balance`, `cashflow`, `comprehensive`, `equity`. An exact slot match always wins first, so a filing that literally names a slot after an alias is never shadowed. A value that matches no statement in this filing (after slot + alias) -> 400 INVALID_PARAM whose `details.available_statements` lists this filing's real slot names (a bad VALUE of a known param — unknown query-param NAMES are still ignored, not rejected). Omit for every assembled statement. | StatementsOfIncome |
| consolidated_only | query | optional | true | — | `true` (default) serves the consolidated face columns the filer laid out. `false` adds the dimensioned columns - segment/geography and footnote breakouts of the same period - which are mostly empty for face rows (Apple 10-Q 0000320193-26-000013: 52 columns / 8% populated with `false`, vs 6 by default). Same name and meaning as GET /api/v1/xbrl/facts. Echoed at `meta.consolidated_only`. | false |
Response schema
| Field | Type | Nullable | Description |
|---|---|---|---|
| data.kind | string | no | Artifact kind — `finradar_v1` for the current engine's assembled face-statement payload. |
| data.statements[] | array | no | One entry per assembled statement, in statement order. Each carries `slot` (the normalized statement key — what you pass to `statement=`), `role_uri`, `definition`, `columns[]`, and `rows[]`. Filter with `statement=`. |
| data.statements[].columns[] | array | no | The statement's reporting periods, left-to-right. Each: `context_seq`, `period_type` (`D` duration | `I` instant | `F` forever), `start_date`/`end_date` (ISO), and `dims` ({axis: member} for a dimensioned column, else null). `rows[].values[]` line up position-by-position with this array. |
| data.statements[].rows[] | array | no | Ordered statement lines (as filed). Each: `concept` (qname), `label` (the company's own human line label), `depth` (indentation), `preferred_label_role` (the presentation preferred-label role, or null), `abstract` (heading rows carry no values), and `values[]` — one string-or-null per column in `columns[]`. |
| data.statements[].rows[].label | string | no | The company's own human-readable line label as it appears on the filed statement (e.g. `Cash and cash equivalents`, `Total current assets`) — resolved from the filing's XBRL label linkbase: the filing's label override, else the line's preferred-label-role text, else the standard label. Never blank: if no label text is stored for the concept it falls back to the `concept` qname. The tag name always remains in `concept`; `label` is the display string. |
| data.statements[].rows[].values[] | array | no | As-filed values as STRINGS (full filed precision preserved), aligned to `columns[]`; null where the concept has no fact in that period column. Abstract heading rows are all-null. |
| meta | object | no | Response metadata — carries `accession`, `cik`, `form_type`, `engine_version`, `generated_at`, and `statement_count`. |
Sample response
- "status": "success"
- "data":
- "kind": "finradar_v1"
- "statements":
- "meta":
- "accession": "0000950170-25-100235"
- "cik": "0000789019"
- "form_type": "10-K"
- "view": "full"
- "engine_version": 1
- "generated_at": "2026-07-06T04:12:00Z"
- "statement_count": 1
Errors
| Status | Label | Description |
|---|---|---|
| 200 | OK | Request succeeded. |
| 400 | Bad Request | Invalid query, body, or path parameter. |
| 401 | Unauthorized | Missing or invalid Authorization header / api_Token. |
| 402 | Payment Required | Insufficient token balance for this call. Top up |
| 429 | Too Many Requests | Rate limit exceeded for your tier (see /pricing for tier limits). Tier limits |
| 500 | Server Error | Unexpected server-side failure. Retry with backoff; report if persistent. |
Code samples
curl "https://api.finradar.ai/api/v1/xbrl/filing/0000950170-25-100235/statements?api_Token=YOUR_API_KEY&statement=StatementsOfIncome&consolidated_only=false" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Generate an API key in /account/credentials to run live queries (literal YOUR_API_KEY placeholder shown until then).