Skip to content
/api/v1/xbrl/timeseries

Standardized canonical financial metrics as an annual / quarterly / TTM time-series, with per-value provenance.

Standardized canonical financial metrics as an annual / quarterly / TTM time-series, with per-value provenance. Earnings-per-share metrics prefer their matching individual US-GAAP fact, then us-gaap:EarningsPerShareBasicAndDiluted. Structural fallback rejects the opposite US-GAAP or IFRS earnings-per-share type.

10 tokensSince v3.88.0

Why use this

Serve the 49 income-statement / balance-sheet / cash-flow primitives (and, with `ratios=true`, the full computed-ratio catalog) selected by the standardization ladder — each value carrying the concept it came from, the selection tier + confidence, the arithmetic-referee calc-validation status, and its source accession.

Common use case

Charting a company's revenue / net-income / free-cash-flow history from the engine's OWN parse (not the flat companyfacts summary); backtesting on a point-in-time (`as_of`) or as-originally-filed (`basis=original`) view; auditing WHY a metric took its value via `provenance=full`.

The standardized canonical-metric time-series the engine derives, via its own standardization ladder, from each filing's raw XBRL. Returns the 62 primitives (add the full computed-ratio catalog with ratios=true) as an A / Q / TTM series. Every base-metric value is selected by mapped-concept -> structure-anchor -> arithmetic-referee, and (with provenance=summary|full) reports its source concept, selection tier, confidence and calc-validation status so a consumer can audit or gate on quality. Ratio cells instead carry a status (value | nm | hole) with a machine-readable reason_code, method_labels and a per-metric formula_version, so a blank ratio is never ambiguous and no method choice is silent. Add template=true to get the same standardized values assembled into full footing statement templates (income, balance, cash-flow, comprehensive-income) — canonical line items in presentation order, with footing receipts that check the totals add up, including the end-to-end cash-flow identity (operating + investing + financing + effect of exchange rates = net change in cash) for a filer that tags the full section set. basis=latest|original and as_of=<date> give amendment-aware and point-in-time (backtest-safe) views; by default the series spans ALL available periods (omit years, or pass years=all, for the full ~2009 XBRL era), and an explicit years=N narrows to the last N fiscal years ([1, 25]). Values are served AS-REPORTED in the filer's native currency (data.reporting_currency; foreign private issuers file in non-USD — Toyota JPY, SAP EUR), with each summary/full cell also carrying its own unit — no FX conversion is applied, so a foreign value is never mislabelled as USD. Selector is ticker | cik. Coverage is wide — every US filer is served presence-based — while historical depth loads incrementally: a ticker that matches no US filer returns 404 UNKNOWN_TICKER, and a real filer with nothing standardized yet returns HTTP 200 with an empty rows array and meta.covered:false (the standardized /api/v1/financials/* surface is the fallback), not a 404.

Earnings per share. For eps_basic and eps_diluted, the corresponding individual US-GAAP fact takes priority. If it is unavailable, an eligible historical us-gaap:EarningsPerShareBasicAndDiluted fact can supply either or both metrics; both retain that combined source concept and its reported per-share value. Structural fallback rejects an explicitly basic-only US-GAAP or IFRS fact for diluted earnings per share, and vice versa. If that opposite kind is the only evidence, the requested metric remains missing. Existing period, currency and consolidation checks still apply; quarter and trailing-twelve-month calculation methods are unchanged. This supports already-filed combined facts, whose tag was deprecated in the 2022 taxonomy (FASB FAQ 2.14).

Calculation evidence. Fourth-quarter, trailing-twelve-month, growth and ratio calculations are checked against the source evidence for the inputs they actually use. An earlier source-tag conflict does not by itself withhold a later calculation whose own inputs pass those checks. Calculations with conflicting or insufficient input evidence remain unavailable; similar amounts or a tag-name change do not establish equivalence. basis=original and basis=latest select versions of company-reported figures, not versions of FinRadar software. Both use the same current calculation rules.

Parameters

NameInRequiredDefaultAllowedDescriptionExample
tickerqueryoptionalSelector — provide exactly ONE of `ticker` | `cik`. Ticker in canonical hyphen form (case-insensitive). A ticker that matches no US filer -> 404 `UNKNOWN_TICKER` (the `/api/v1/financials/*` surface is the fallback); a real filer with no standardized data yet returns HTTP 200 with an empty `rows` array and `meta.covered:false` (historical depth loads incrementally), not a 404.MSFT
cikqueryoptionalSelector: issuer CIK, zero-padded or bare (both match — compared with leading zeros stripped). Must be numeric (else 400 INVALID_PARAM).789019
metricsqueryoptionalComma-separated canonical metric keys to return (e.g. `revenue`, `net_income`, `total_assets`). Omit for all 64 standardized primitives. Unknown keys are ignored. The set includes eleven newer primitives: `pretax_income` (profit before income taxes, as reported), `accounts_payable` (amounts owed to suppliers for goods and services already received), `stock_based_compensation` (the value of stock and option awards granted to employees, as expensed by the company), `weighted_average_shares_basic` and `weighted_average_shares_diluted` (the average number of shares in circulation over the period — basic, and diluted counting stock options and convertibles as if exercised), `preferred_equity` (the stated value of preferred shares on the balance sheet), `preferred_dividends` (dividends owed to preferred shareholders before earnings belong to common shareholders), `minority_interest` (the part of a consolidated subsidiary's equity owned by outside shareholders), `intangibles_ex_goodwill` (intangible assets like patents, licenses and trademarks — excluding goodwill), `operating_lease_liability` (what the company still owes on its office, store and equipment leases), and `stock_issuance` (cash the company raised by selling new shares); plus the four cash-flow section totals that make the cash-flow statement foot: `investing_cashflow` (net cash from investing activities — buying and selling long-term assets and investments; can be negative), `financing_cashflow` (net cash from financing activities — borrowing, repaying debt, issuing or buying back shares, and paying dividends; can be negative), `effect_of_fx_on_cash` (the change in cash caused purely by exchange-rate movements on foreign-currency cash; can be negative, and often absent for companies holding only US-dollar cash), and `net_change_in_cash` (the overall increase or decrease in cash for the period — the cash-flow statement bottom line; can be negative); plus the pretax-income build-up `interest_income` (interest earned on cash, deposits and investments), `nonoperating_income_expense` (net income and expense outside normal operations, before tax; can be negative), `equity_method_earnings` (the company's share of profit or loss from businesses it partly owns but does not control; can be negative), `discontinued_operations` (profit or loss from business lines being sold or wound down, shown separately from continuing operations; can be negative) and `net_income_to_common` (profit left for common shareholders after preferred dividends; can be negative); and the equity-section detail `common_stock_par` (the nominal par value of issued common shares), `additional_paid_in_capital` (money raised from selling shares above their par value), `treasury_stock` (the cost of the company's own shares it has bought back and holds — reported as filed) and `accumulated_oci` (cumulative gains and losses such as currency, pensions and hedges kept in equity, outside retained earnings; can be negative); and the cash-flow beginning/ending cash `cash_at_end_of_period` (cash and cash equivalents at the END of the period as reported on the cash-flow statement — a point-in-time value that reconciles to the balance-sheet cash line for the same date) and `cash_at_beginning_of_period` (cash at the BEGINNING of the period — a point-in-time value equal to the prior period's ending cash; the net change in cash is the flow that bridges beginning to ending). A company that does not report one of these serves an absence, never a guessed or back-solved number.revenue,net_income,pretax_income
ratiosqueryoptionalfalse`true`/`1`/`yes` additionally returns the full computed-ratio catalog from `xbrl.ratio_values`: margins, returns (ROE / ROA / ROIC / ROCE), the leverage family (incl. debt-to-capital, liabilities-to-equity, net-debt-to-EBITDA), liquidity + working-capital ratios, the turnover/efficiency family (DSO / DIO / operating-cycle / fixed-asset turnover), capex intensity, retention, per-share figures, same-quarter-year-over-year / sequential growth, and the **valuation family**: `market_cap`, `ev` (enterprise value), the price multiples `pe_ratio` / `price_to_sales` / `price_to_book` / `price_to_tangible_book` / `price_to_fcf`, the enterprise-value multiples `ev_to_ebitda` / `ev_to_sales` / `ev_to_fcf` / `ev_to_ebit`, and the yields `earnings_yield` / `fcf_yield` / `dividend_yield` / `shareholder_yield`. The valuation ratios combine the standardized financials with a market price; the price itself is not returned as a field — each valuation cell's receipt shows the derived `market_cap` and `ev` (our aggregates) and records that a market price was used without exposing the per-share price. When a company reports its financials in one currency and the market price is in another, the cross is not computed (`status='hole'`, `reason_code='currency_mixed'`) rather than silently mixing currencies. Each ratio cell carries a `status` (`value` | `nm` | `hole`) and, when not `value`, a machine-readable `reason_code` (a blank is `nm` for a meaningless denominator or `hole` for a missing input / mixed currency — never a guessed number), plus `method_labels` (which method choices were made, so no fallback is silent) and a per-metric `formula_version`. Default `false` (primitives only).true
periodqueryoptionalA`A` (annual, default), `Q` (quarterly), or `TTM` (trailing-twelve-month rolling). NOTE: annual is `A` on this engine surface, NOT the legacy `/api/v1/financials/*` `Y`. QUARTERLY BASIS: every quarterly cell is a DISCRETE three-month figure. Income-statement and balance-sheet quarters are served as filed. Cash-flow-statement quarters (`operating_cashflow`, `investing_cashflow`, `financing_cashflow`, `capex`, `dividends_paid`, `stock_repurchase`, `stock_issuance`, `acquisition_payments`, `depreciation_amortization`, `stock_based_compensation`, `interest_paid`, `interest_received`, `taxes_paid`, `net_change_in_cash`, `effect_of_fx_on_cash`) are filed CUMULATIVELY year-to-date on a 10-Q, so their Q2 and Q3 cells are derived from the filer's own cumulative statements (Q2 = six-month figure minus Q1; Q3 = nine-month figure minus Q1 and Q2) and carry `source: cf_compat_standardized` with a `CALCULATED:Q2_discrete=Q2_cumulative-Q1` / `CALCULATED:Q3_discrete=Q3_cumulative-Q1-Q2` concept marker; Q1 and FY are as filed. Where the discrete quarter cannot be derived (the filer's Q1 is not on file) the cell is ABSENT — a year-to-date figure is never served as a quarter.TTM
yearsqueryoptionalall available periodsYears of history. DEFAULT = all available periods: omit `years` (or pass `years=all`) and you receive the company's FULL history the engine has, with NO fiscal-year floor (back to the ~2009 start of XBRL for early filers); `meta.years` echoes `"all"`. Pass an integer to narrow to the last N fiscal years, clamped to [1, 25]. With `period=Q` an integer `years` returns up to `years x 4` rows. A long series is paged (see `limit`/`cursor`), never silently truncated.25
provenancequeryoptionalnone`none` (default) returns each value as a bare number (a flat pivot like the legacy `/financials/metrics`) — read `data.reporting_currency` for the currency, since a bare number carries no unit. `summary` wraps each value as `{value, concept, tier, method, calc_status, confidence, accession, source, unit}` — `unit` is the AS-REPORTED currency (ISO-4217, e.g. `USD` / `JPY` / `EUR`) or `shares` (ratios are `null`), so a foreign filer's value is never misread as USD. `full` additionally adds `decimals` / `source_filing_id` / `filed_at`; source and calculated base cells also include `relationship_provenance` when structured source evidence is available. Its versioned `source_lineage` retains signed raw-fact expressions, accession/fact/context identities, source and reporting windows, consolidation/statement scope, dimensions, units/currency/decimals, resolver version and transformation history. Raw accounting identity stays separate from method/display labels. The shared comparison returns only `equivalent`, `conflict` or `insufficient`; legacy marker-only and unknown evidence are insufficient. With `ratios=true`, full ratio inputs also retain their structured result history. Any other value -> 400 INVALID_PARAM.full
basisqueryoptionallatest`latest` (default) = the most recently filed value for each (metric, period), including amendments and later comparative restatements. `original` = the value from the first filing whose PRIMARY period it was (pre-restatement). Applies to the derived Q4/TTM and ratio cells too (they are re-derived from the chosen-basis sourced values), not only the sourced base metrics. Any other value -> 400 INVALID_PARAM.original
as_ofqueryoptionalPoint-in-time replay: return the values visible as-of this date (only filings with `filed_at <= as_of`; latest wins) — backtest-safe. Applies to EVERY cell: the sourced FY/Q1/Q2/Q3 base metrics, the derived Q4/TTM base metrics, and (with `ratios=true`) the whole computed-ratio catalog are all elected/re-derived at the fundamentals-in-force at this date, so a point-in-time view is consistent across cells. The valuation family (`market_cap`/`ev`/price multiples/yields) is the one exception — it needs an as-of market price this path does not yet source, so under `as_of` those cells serve `status='hole'` (`reason_code='hole_asof_price_unavailable'`) rather than a backdated latest price. `YYYY-MM-DD`; malformed -> 400 INVALID_PARAM.2024-01-31
currencyqueryoptionalthe filer's reporting currencyWhich AS-FILED currency to serve for a filer that reported in more than one. DEFAULT (omit it) = the company's own reporting currency — the complete, continuous series, echoed in `data.reporting_currency` and in each `unit`. A foreign private issuer whose reporting currency is not the dollar may also file a supplemental USD *convenience translation*; Reg S-X 17 CFR 210.3-20(b) permits one only for "the most recent fiscal year and any subsequent interim period presented", struck at "the exchange rate as of the most recent balance sheet included in the filing". Pass `currency=USD` to serve those as-filed dollar figures instead — but expect them ONLY for the years the filer actually translated, each struck at its own balance-sheet-date rate, so a multi-year dollar series assembled this way is NOT rate-comparable across years. NOTHING is converted: a currency the filer never reported returns no monetary cells rather than a number computed from an FX rate we chose. Share counts are unchanged. Dimensionless ratios retain the canonical calculation and its original input currencies when the monetary display currency changes; they are not independently recalculated from the displayed translation. Latest ratios retain their stored calculation; original/as_of ratios retain the requested filing-version calculation and never borrow latest results. Monetary calculated fields (including per-share and per-employee amounts, market capitalization and enterprise value) remain currency-dependent. Use provenance=full to inspect the actual ratio inputs. Existing missing-input, source-history and measurement-window checks still apply. 3-letter ISO-4217; anything else -> 400 INVALID_PARAM.USD
adjustedqueryoptionalfalse`true`/`1`/`yes` returns the eight PER-SHARE metrics SPLIT-ADJUSTED so a historical per-share series is comparable across a stock split. It applies ONLY to `eps_basic`, `eps_diluted`, `book_value_per_share`, `cash_per_share`, `revenue_per_share`, `fcf_per_share`, `ocf_per_share` and `dividend_per_share`; every other metric (dollar amounts, share counts, ratios) is byte-identical. Each adjusted per-share cell is divided by the cumulative split factor (the product of split ratios with ex-date AFTER the cell's `period_end` and on/before the reference date) and gains `split_factor` and `unadjusted_value` (the pre-adjustment standardized or derived value stays visible). The reference date is `as_of` when set (a split after `as_of` is NOT applied — point-in-time safe), else today. No split adjustment is the default. Default `false`.true
calendarqueryoptionalfalse`true`/`1`/`yes` adds a `calendar` block to each row so filers with different fiscal-year-ends line up on one calendar axis. A QUARTERLY row maps to the calendar quarter its ~3-month span overlaps the MOST (not the quarter of the end month): a fiscal quarter ending 2017-01-31 maps to `2016-Q4`, not `2017-Q1`. An ANNUAL or TTM row maps to a calendar YEAR only — `calendar_quarter` is `null` and `calendar_label` is the year: a September-fiscal-year filer's FY ending 2024-09-28 is `2024`, and a January-fiscal-year filer's FY ending 2025-01-31 is `2024` (11 of its 12 months fall in 2024). This RE-LABELS only; values are the as-reported figures and are never re-binned or prorated to calendar boundaries. Default `false`.true
templatequeryoptionalfalse`true`/`1`/`yes` adds a `template` block to each row: the standardized values assembled into the full FOOTING statement templates (`income`, `balance`, `cashflow`, `comprehensive_income`). Each statement carries `lines` — the canonical line items in presentation order, each with its place in the statement hierarchy (`level` indentation depth, `parent` = the subtotal it rolls up into, and `is_subtotal` = `true` for a footed subtotal/total row), so the statement renders indented with bold totals; a line the filer did not report OR that is not standardized yet serves `status='absent'` with a `null` value (an honest gap, never a guessed number) — `subtotals` (footing receipts: e.g. `gross_profit = revenue − cost_of_revenue` and `total_assets = total_liabilities + total_equity`, checked with the same decimals-aware arithmetic referee used across the engine; each receipt's `status` is `consistent` / `inconsistent` / `unchecked`, and an `inconsistent` subtotal FLAGS the residual — it never blocks the response), `other_*` reconciling buckets (bucket value = the filer-reported section total − the classified lines, so the template foots to the filer's own total; `foots_to_filed_total` is `false` only when the section total itself is absent, in which case the bucket is `unchecked` and never invents a total), and a rolled-up `footing_status`. The line values are the SAME cells as the flat `metrics` bag — the template never re-computes or diverges from them; `level`/`parent`/`is_subtotal` are presentation-only. Default `false`.true
period_offsetqueryoptionalRelative period addressing: select a SINGLE period relative to the latest reported instead of the whole series. `0` = the latest period, `-1` = one period back, `-4` = four periods back, and so on. It indexes into the `as_of`-elected, newest-first rows, so it composes with `as_of`. A POSITIVE value addresses a future/estimate period, which is not carried -> 400 INVALID_PARAM. An offset beyond the start of the available window -> 404 NOT_FOUND. Must be an integer (else 400 INVALID_PARAM). Omit for the full series.-1
limitqueryoptional5000Page size in PERIOD-ROWS (one row per fiscal period). Clamped to [1, 5000]; omit for the default page cap. When the assembled series is longer than the page, the response returns the newest `limit` rows plus `meta.pagination.has_more=true` and a `meta.pagination.next_cursor` to resume — the series is NEVER silently truncated (a series within the cap returns `has_more=false` and `next_cursor=null`, i.e. the same rows as before, just made explicit). A non-integer value -> 400 INVALID_PARAM. Almost every company fits one page (25 years x 4 quarters ~= 100 rows), so a typical request needs no paging.500
cursorqueryoptionalOpaque pagination cursor to fetch the NEXT page: pass the `meta.pagination.next_cursor` value from the previous response VERBATIM. It resumes strictly after the last row of the previous page (no overlap, no gap). Omit for the first page. A malformed cursor -> 400 INVALID_PARAM (a corrupt cursor is rejected, never silently treated as page 1).dHMxOnsiZnkiOjIwMTUsImZwIjoiRlkifQ==

Response schema

FieldTypeNullableDescription
meta.paginationobjectnoPeriod-row pagination carrier `{limit, has_more, next_cursor, page_row_count, series_row_count}`. `limit` = the page size applied; `has_more` = whether more period-rows remain past this page; `next_cursor` = the opaque cursor to fetch the next page (pass it back verbatim in `cursor`), or `null` on the final page; `page_row_count` = rows on THIS page; `series_row_count` = total rows in the full series before this page was sliced. A series within the page cap returns `has_more=false`/`next_cursor=null` — additive and backward-compatible (the same rows as before, with the paging fields made explicit); a longer series is returned honestly as resumable pages instead of a silent truncation.
data.company_namestringyesThe company's display name, embedded beside `data.ticker`/`data.cik` so a client can label the series without a second lookup (mirrors the SEC companyfacts `entityName`). Resolved from the always-updated company catalog by the resolved CIK; present with `null` when the catalog has no name for the company (never a fabricated value). Additive — every existing field is unchanged.
data.reporting_currencystringyesThe filer's AS-REPORTED reporting currency (ISO-4217, e.g. `USD`, `JPY` for Toyota, `EUR` for SAP), surfaced at EVERY provenance level — including `none`, whose bare-number cells cannot carry their own unit. Values are served natively with NO FX conversion. `null` when no monetary metric is in the response (e.g. only shares/ratios requested) — the engine never guesses `USD` for a foreign filer. Per-cell `unit` (at `summary`/`full`) stays authoritative for any metric that differs (shares, ratios) or a rare mid-history currency change.
data.rows[]arraynoOne entry per reporting period (newest-to-oldest across ALL available periods by default, or within the requested `years` window when `years` is an integer). Each carries `fiscal_year`, `fiscal_period` (`FY` | `Q1`..`Q4` | `TTM`), `period_end` (ISO), and `metrics`. `fiscal_year` is the fiscal year as the company names it in its own filings, reconciled per company across its filings: each quarter carries the year of the fiscal year it sits in (the year of the company's own annual report for that fiscal year; for the year in progress, the previous annual report's year + 1), and the label is never derived from the period-end date or from a registrant year-end record — one company names a fiscal year ending 2026-01-31 "2026" while another names a fiscal year ending 2026-02-01 "2025", and both are served as the company names them. `fiscal_period` is the quarter's position inside the company's own declared fiscal year (`Q1`..`Q3` from the filing's declared year-to-date span; `Q4`/`TTM` derived). Period dates are the key: join on `period_end` (as-filed points also carry `start_date`/`end_date`); pass `calendar=true` for the calendar-aligned label. ONE ROW = ONE MEASUREMENT WINDOW: every value in a row covers the span ending at that row's `period_end`, which is the row's TERMINAL window. A metric whose own window differs is served as an explicit absence carrying `window_end` (below) rather than carried onto the row — a figure covering a different span produces a wrong ratio, not merely a stale one.
data.rows[].metricsobjectnoKeyed by canonical metric name. With `provenance=none` each value is a bare number; with `summary` each is an object `{value, concept, tier, method, calc_status, confidence, accession, source, unit}`; `full` additionally adds `decimals`, `source_filing_id`, `filed_at`, and, when available, `relationship_provenance`.
data.rows[].metrics.<metric>.window_endstringyesPresent ONLY on a cell withheld for window integrity. A trailing-twelve-month series for ONE metric can freeze while its siblings advance — this happens when a filer changes the accounting tag it reports that line under, because the engine refuses to add and subtract quarters across two different tags. The frozen figure is then NOT the same twelve months as the rest of the row, so it is served as an absence (`value: null`) with `status='absent'` and `reason_code='stale_window'`; `window_end` (ISO) is the window that figure actually covers, so a client can fetch it at the period where it applies. A ratio that consumed such a metric is served `status='hole'`, `reason_code='mixed_window'`, `window_end: null` (it never had ONE window). At `provenance=none` a withheld cell is a bare `null`, like every other absence on that surface. Absent from every coherent row.
data.ratiosbooleannoEchoes the `ratios` request flag. When `true`, `data.rows[].metrics` additionally carries the computed-ratio cells from `xbrl.ratio_values`.
data.adjustedbooleannoEchoes the `adjusted` request flag. When `true`, the eight per-share metrics are split-adjusted and carry `split_factor` + `unadjusted_value` (see `meta.adjusted_reference_date` for the split cutoff date). When `false` (default), no split arithmetic is applied; values retain the standardization engine's stored or derived output.
data.calendarbooleannoEchoes the `calendar` request flag. When `true`, each `data.rows[]` entry carries a `calendar` block — a quarterly row to its overlapping calendar quarter, an annual/TTM row to a calendar year only.
data.templatebooleannoEchoes the `template` request flag. When `true`, each `data.rows[]` entry carries a `template` block with the full footing statement templates. When `false` (default) no template block is present.
data.rows[].templateobjectyesPresent only with `template=true`: `{income, balance, cashflow, comprehensive_income}`. Each statement is `{lines, subtotals, other, footing_status}`. `lines[]` are the canonical line items `{key, label, status, value, level, parent, is_subtotal}` in presentation order (`status='value'` with the standardized cell, or `status='absent'` with `value=null` for a line the filer did not report or that is not standardized yet). Every line also carries its place in the statement hierarchy: `level` (0/1/2 indentation depth — a section subtotal or total is level 0, a detail line that rolls up is level 1), `parent` (the `key` of the subtotal/total this line rolls up into, or `null` for a top-level line — a section total, or a memo / per-share line), and `is_subtotal` (`true` for a footed subtotal/total row — gross profit, the section totals, total assets / liabilities / equity, the cash-flow section totals — so a client can render the statement indented with bold totals; the `subtotals[]` footing targets are a subset of the `is_subtotal` lines). `subtotals[]` are footing receipts `{target, status, reported, recomputed, residual}` where `status` is `consistent`/`inconsistent`/`unchecked` (an inconsistent subtotal surfaces its `residual`, never blocks). `other[]` are the reconciling buckets `{bucket, value, status, foots_to_filed_total, section_total_key}` (bucket = section total − classified lines). `footing_status` rolls the statement up. The line values are the SAME cells as `data.rows[].metrics`; `level`/`parent`/`is_subtotal` are presentation-only and never change a value.
data.rows[].metrics.<per_share>.split_factornumberyesPresent only with `adjusted=true` on the eight per-share metrics: the cumulative split ratio applied (product of split ratios with ex-date after `period_end` and on/before the reference date). `1.0` means no split occurred in the window (value unchanged). The served `value` is `unadjusted_value / split_factor`.
data.rows[].metrics.<per_share>.unadjusted_valuenumberyesPresent only with `adjusted=true` on the eight per-share metrics: the pre-adjustment standardized or derived per-share value, kept visible alongside the adjusted `value`.
data.rows[].calendarobjectyesPresent only with `calendar=true`: `{calendar_year, calendar_quarter, calendar_label}`. For a QUARTERLY row this is the calendar quarter of greatest overlap, e.g. `{2016, 4, "2016-Q4"}` for a quarter ending 2017-01-31. For an ANNUAL or TTM row `calendar_quarter` is `null` and `calendar_label` is the year, e.g. `{2024, null, "2024"}` for a fiscal year ending 2024-09-28. A re-label of the stored date; values are not re-binned or prorated.
data.rows[].metrics.<ratio>.statusstringnoRatio cells (`ratios=true`, at `provenance=summary`/`full`): `value` (a real number in `value`), `nm` (Not Meaningful — `value` is null and `reason_code` says why: a zero/negative denominator, a non-positive growth base, or a cash-generative firm with no burn/runway), or `hole` (`value` is null because a required input is missing or the inputs disagree on currency). A blank ratio is therefore never ambiguous — `status`+`reason_code` say whether it is meaningless-but-computable vs input-missing.
data.rows[].metrics.<ratio>.reason_codestringyesRatio cells: null when `status='value'`; otherwise one of `nm_zero_denominator`, `nm_negative_denominator`, `nm_negative_growth_base`, `nm_not_burning` (a cash-generative firm — non-negative operating cash flow — so `cash_runway`/`monthly_burn_rate` have no burn and no finite runway), `currency_mixed`, `hole_missing_input_<metric>`, `hole_source_lineage_conflict` or `hole_source_lineage_insufficient` (conflicting or unprovable accounting source history), `hole_asof_price_unavailable` (a valuation cell under `as_of` — no as-of market price is sourced on the read-time path, so the cell holes honestly rather than backdating the latest price), or `mixed_window` (an input to this ratio covers a different measurement window than the row — see `window_end` — so computing it would divide across two spans). Machine-readable, stable.
data.rows[].metrics.<ratio>.method_labelsobjectnoRatio cells: the method choices behind the value, so no fallback is silent — e.g. `avg_basis` (`avg2` vs `ending` when the prior period is missing), `tax_basis` (`effective` vs `proxy`), `share_basis` (`period_end` vs `wavg_diluted`), `lease_leg` (`operating_only` / `finance_plus_operating` / `absent_debt_concept`) and `lease_verdict_source`.
data.rows[].metrics.<ratio>.formula_versionnumbernoRatio cells: the definition-ledger version that produced the value. A formula change bumps this per-metric so a served value's provenance is unambiguous.
data.rows[].metrics.<metric>.unitstringyesAs-reported unit of the value, present at `provenance=summary` and `full`: an ISO-4217 currency (`USD` / `JPY` / `EUR`) for monetary metrics, `shares` for share counts, or `null` for the dimensionless ratios. It is the true filer-reported unit (carried from `std_values` / the compat chain), NOT a hardcoded `USD` — so a foreign private issuer's JPY/EUR value is never mislabelled.
data.rows[].metrics.<metric>.relationship_provenanceobjectyesPresent only at `provenance=full` when available. The versioned `source_lineage` contains direct raw-fact leaves or signed source-expression trees, resolver version, original expanded taxonomy names, filing accession and fact/context identities, reporting and source windows, entity/consolidation and statement scope, dimensions, units/currency, decimals, and transformation history. Period arithmetic compares this evidence as equivalent, conflict, or insufficient; display and method labels are not accounting identities. Legacy marker-only rows are insufficient evidence. Formula receipts retain consulted source trees and formula versions; unsupported expressions do not establish accounting equivalence. Ratio input/result receipts carry the same evidence inside their full-provenance inputs list. Summary and bare-value responses omit these trees.
data.rows[].metrics.<metric>.calc_statusstringyesThe arithmetic referee's verdict on the value's calc chain: `consistent` (foots within decimals-derived tolerance), `inconsistent` (the filer's own calc linkbase disagrees — surfaced, not hidden), or `unchecked` (no covering calc arc). `method` is `mapped` (tier-1 concept) | `inferred` (tier-2 structure) | `calculated:<formula>` (e.g. `Q4=FY-Q1-Q2-Q3`, TTM).
data.rows[].metrics.<metric>.confidencenumberyesSelection confidence 0.6-1.0 (1.0 = tier-1 + consistent). Below 0.6 the value is withheld to the review queue rather than published — the engine prefers a hole to a wrong number.
data.rows[].metrics.<metric>.sourcestringyesWhich standardized store served the value: `std_values` (sourced FY/Q1/Q2/Q3 base metrics, full provenance), `cf_compat_standardized` (Q4/TTM of the concept-mapped base metrics, reduced provenance), or `ratio_values` (the ratio catalog AND the calc-only base metrics `ebitda`/`free_cashflow`, reduced provenance). `tier`, `calc_status`, `confidence` and `accession` are null for the two reduced-provenance sources.

Sample response

·
  • "request_id": null
  • "timestamp": "2026-09-13T00:00:00Z"
  • "status": "success"
  • "data":
    • "ticker": "MSFT"
    • "cik": "0000789019"
    • "company_name": "MICROSOFT CORP"
    • "period": "A"
    • "basis": "latest"
    • "provenance": "summary"
    • "reporting_currency": "USD"
    • "ratios": false
    • "rows":
    }
  • "meta":
    • "covered": true
    • "phase": "wide"
    • "metric_count": 2
    • "row_count": 1
    • "years": "all"
    • "as_of": null
    • "pagination":
    }
}

Errors

StatusLabelDescription
200OKRequest succeeded.
400Bad RequestInvalid query, body, or path parameter.
401UnauthorizedMissing or invalid Authorization header / api_Token.
402Payment RequiredInsufficient token balance for this call. Top up
429Too Many RequestsRate limit exceeded for your tier (see /pricing for tier limits). Tier limits
500Server ErrorUnexpected server-side failure. Retry with backoff; report if persistent.

Code samples

curl "https://api.finradar.ai/api/v1/xbrl/timeseries?api_Token=YOUR_API_KEY&ticker=MSFT&cik=789019&metrics=revenue%2Cnet_income%2Cpretax_income&ratios=true&period=TTM&years=25&provenance=full&basis=original&as_of=2024-01-31&currency=USD&adjusted=true&calendar=true&template=true&period_offset=-1&limit=500&cursor=dHMxOnsiZnkiOjIwMTUsImZwIjoiRlkifQ%3D%3D" \
  -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).