?>
ESC to close

Historical Financial Metrics API

Maintained by Piyush Arora

Last updated:

Retrieve a historical time-series for any single one of 1,257 fundamental metrics — Revenue (Annual), Gross Margin (Quarter), Free Cash Flow (TTM), Price to Earnings, Enterprise Value — without downloading a full financial statement and parsing the line item out of it yourself. Every metric is routed and queried independently against its own source table, so one request can combine up to 5 metrics across up to 5 tickers and return them merged into a single flat array. The API is free to use.

Four transformation modes available:

original Raw Reported Value normalized % Change From Common Start pct_from_high % Below Running Peak pct_from_low % Above Running Trough
GET https://data.businessquant.com/historic?slug={slugs}&ticker={tickers}&api_key={api_key}

Related endpoints: Need the whole statement rather than one metric? Use the Financial Statements API. Screen the entire market on these same fundamentals with the Stock Screener API. Benchmark one company against its industry using the Peers Analysis API. Overlay macro series with the Economic Data API, which supports the same four transformation modes.

1. Request Parameters

Provide an API key, at least one metric slug, and at least one entity filter — ticker, industry, or sector. Omitting all three returns 400. Both slug and ticker are capped at 5 values each, so the widest single request is 5 metrics across 5 tickers. Resolve valid slugs from the metric catalog described in section 4.

Parameter Description
api_key
Required
Your unique API key for authentication.
slug
Required Identifier
Comma separated list of metric slugs. Maximum of 5 per request. Case insensitive. Each slug is resolved to its own source table independently, so metrics drawn from different statements can be combined freely in one call. An unrecognised slug returns 404 naming exactly which slugs failed.
Format: slug=revenue-annual,gross-margin-annual
ticker
Conditional Identifier
Comma separated list of ticker symbols. Maximum of 5 per request. Case insensitive. Supply this, industry, or sector — at least one is required.
Format: ticker=AAPL,MSFT,GOOGL
industry
Conditional
Comma separated list of industry names, matched in title case. Returns the metric series for every company in those industries. No count cap applies. Only effective for statement-derived metrics — see the coverage note below the table.
Format: industry=Consumer Electronics
sector
Conditional
Comma separated list of sector names, matched in title case. Broader than industry and likewise uncapped. Combine with ticker to widen a request rather than replace it.
Format: sector=Technology
mode
Optional
Transformation applied to value before it is returned. One of original (default), normalized, pct_from_high, or pct_from_low. Every ticker and metric pair is transformed independently. An unknown value returns 400 listing the four valid options. See section 3 for exact behaviour.
Format: mode=normalized
frequency
Optional
Restricts results to metrics reported at a given cadence: annual, quarterly, ttm, monthly, or daily. Defaults to original, which applies no filter and honours whatever cadence the slug itself encodes. Note that frequency=quarterly also switches date to a calendar quarter label. A slug that does not match the requested cadence is reported as missing with a 404.
Format: frequency=quarterly
period
Optional
Relative lookback window, expressed as a number followed by d, w, mo, or y. Also accepts ytd and max. Takes precedence over from_date and till_date, which are ignored whenever period is present. Passing max disables pagination and returns the entire history.
Examples: period=6mo  ·  period=10y  ·  period=ytd  ·  period=max
from_date
Optional
Start of an explicit date window, in YYYY-MM-DD format. Applied only when till_date is supplied as well and period is omitted — a lone from_date has no effect.
Format: from_date=2015-01-01
till_date
Optional
End of an explicit date window, in YYYY-MM-DD format. Must be paired with from_date. A malformed date returns 500 rather than 400, so validate the format client side.
Format: till_date=2026-06-30
skip
Optional
Number of rows to skip before returning results. Defaults to 0. Applied per source table, and not applied at all when period=max.
Format: skip=500
limit
Optional
Maximum number of rows to return. Defaults to 10000. Applied per source table rather than to the merged array, so a request spanning two tables can return up to twice the limit. Not applied when period=max.
Format: limit=2000

Coverage note on industry and sector. These two filters resolve against statement-derived fundamentals only. Daily valuation metrics — price, market-capitalization, enterprise-value, price-to-earnings and the other eight listed in section 4 — are not classified by industry or sector, so a request filtering by industry or sector without a ticker skips them entirely, and returns 404 No data found for the given parameters when a daily metric is the only slug requested. Pass ticker when your slug list includes a daily metric.

Example cURL Request (Single Metric)
curl -X GET "https://data.businessquant.com/historic?slug=revenue-annual&ticker=AAPL&period=max&api_key=YOUR_API_KEY"
Example cURL Request (5 Metrics × 5 Tickers)
curl -X GET "https://data.businessquant.com/historic?slug=revenue-annual,gross-margin-annual,free-cash-flow-annual,net-income-annual,operating-margin-annual&ticker=AAPL,MSFT,GOOGL,AMZN,META&period=5y&api_key=YOUR_API_KEY"
Example cURL Request (Metric Catalog)
curl -X GET "https://data.businessquant.com/metadata?table=historic&api_key=YOUR_API_KEY"

2. Sample Response

Three metrics across two tickers, returned by a single call. Note the response shape: a flat array with no metadata envelope. Unlike most endpoints on this portal, every descriptor — company name, industry, sector, datatype — is repeated on every row, which makes the payload trivial to load straight into a dataframe or a chart series without flattening a nested object first. Rows arrive grouped in the slug order you requested, then sorted by report period, with tickers interleaved inside each metric block. Switch to JSON to inspect the raw structure.

Multi-Metric, Multi-Ticker Response

Metrics: 3  •  Tickers: AAPL, MSFT  •  Mode: original  •  30 rows

Rows30
Metrics3
Tickers2
IndustryConsumer Electronics
SectorTechnology
Datatypeint
Ticker Metric Date Value Datatype
AAPL Revenue (Annual) 2021-09-25 365.82B int
MSFT Revenue (Annual) 2022-06-30 198.27B int
AAPL Revenue (Annual) 2022-09-24 394.33B int
MSFT Revenue (Annual) 2023-06-30 211.92B int
AAPL Revenue (Annual) 2023-09-30 383.29B int
MSFT Revenue (Annual) 2024-06-30 245.12B int
AAPL Revenue (Annual) 2024-09-28 391.04B int
MSFT Revenue (Annual) 2025-06-30 281.72B int
AAPL Revenue (Annual) 2025-09-27 416.16B int
MSFT Revenue (Annual) 2026-06-30 331.84B int
AAPL Gross Margin (Annual) 2021-09-25 41.78% %
MSFT Gross Margin (Annual) 2022-06-30 68.40% %
AAPL Gross Margin (Annual) 2022-09-24 43.31% %
MSFT Gross Margin (Annual) 2023-06-30 68.92% %
AAPL Gross Margin (Annual) 2023-09-30 44.13% %
MSFT Gross Margin (Annual) 2024-06-30 69.76% %
AAPL Gross Margin (Annual) 2024-09-28 46.21% %
MSFT Gross Margin (Annual) 2025-06-30 68.82% %
AAPL Gross Margin (Annual) 2025-09-27 46.91% %
MSFT Gross Margin (Annual) 2026-06-30 67.94% %
AAPL Free Cash Flow (Annual) 2021-09-25 92.95B int
MSFT Free Cash Flow (Annual) 2022-06-30 65.15B int
AAPL Free Cash Flow (Annual) 2022-09-24 111.44B int
MSFT Free Cash Flow (Annual) 2023-06-30 59.48B int
AAPL Free Cash Flow (Annual) 2023-09-30 99.58B int
MSFT Free Cash Flow (Annual) 2024-06-30 74.07B int
AAPL Free Cash Flow (Annual) 2024-09-28 108.81B int
MSFT Free Cash Flow (Annual) 2025-06-30 71.61B int
AAPL Free Cash Flow (Annual) 2025-09-27 98.77B int
MSFT Free Cash Flow (Annual) 2026-06-30 66.99B int

3. Response Field Reference

Every row is self-describing. There is no envelope to unwrap and no join to perform — group client side on ticker and metric to split the array back into individual series.

Row Fields

FieldTypeDescription
tickerstringTicker symbol this observation belongs to. Group on this together with metric to reconstruct one series.
companynamestringFull registered company name, for example Apple Inc.
companyname_shortstringAbbreviated display name, for example Apple. Use this for chart legends where width is constrained.
metricstringFull metric name including its cadence, for example Revenue (Annual). This is the resolved name of the slug you requested, not the slug itself.
metric_shortstringAbbreviated metric label, for example Revenue (Yr).
datestringReport period the value describes. Normally YYYY-MM-DD. When frequency=quarterly it switches to a calendar quarter label such as 2024 Q3 — parse accordingly.
valuenumber|nullThe observation, transformed according to mode. Returns null where no value was reported for that period.
industrystringIndustry classification. Returns an empty string for daily valuation metrics, which are not classified.
sectorstringSector classification. Returns an empty string for daily valuation metrics, which are not classified.
datatypestringUnit of value, for example int or %. Any transformation mode other than original forces this to %, since the value is then a percentage rather than a level.

Transformation Modes

ModeWhat value contains
originalThe raw reported value, in the unit named by datatype. This is the default.
normalizedPercentage change against a shared baseline, rounded to two decimals. The baseline is the latest first-observation date across all requested tickers for that metric, so every company is rebased to the same starting point and the series are directly comparable even when one has a longer history. Rows before that shared date are dropped, and every series therefore starts at 0.
pct_from_highPercentage distance below the running maximum observed up to that point, rounded to two decimals. Values are zero or negative. A drawdown view, useful for sizing how far a metric has retreated from its own peak.
pct_from_lowPercentage distance above the running minimum observed up to that point, rounded to two decimals. Values are zero or positive. A recovery view, useful for measuring a rebound off a trough.

4. Finding Valid Metric Slugs

This endpoint needs a slug before it can return anything, and slugs are not worth guessing at. The metadata endpoint returns the full catalog of 1,257 metrics with the slug, code, cadence, display names, and datatype for each. Fetch it once at startup, cache it, and resolve slugs at runtime rather than hard-coding them.

Historic Metric Catalog

Returns every queryable metric with its slug, code, dimension, metric_full, metric_short, and datatype. Cached server side for 24 hours. No cap applies on this endpoint — the 5-slug limit applies only to /historic itself.

GET https://data.businessquant.com/metadata?table=historic&api_key={api_key}

Pass table=historic-detailed&ticker=AAPL instead to get the metrics actually populated for one company, nested under a metadata and data block, rather than the global catalog.

How the 1,257 Metrics Break Down

DimensionMetricsWhat it covers
Quarter428Quarterly statement line items, margins, ratios, and growth rates. Slugs generally carry no suffix, for example revenue or gross-margin.
TTM428Trailing twelve month equivalents. Slugs end in -ttm, for example revenue-growth-1y-ttm.
Annual389Fiscal year figures. Slugs end in -annual, for example revenue-annual.
Daily12Market-driven valuation metrics recomputed every trading day: price, market-capitalization, enterprise-value, dividend-yield, price-to-earnings, price-to-sales, ev-to-ebitda, ev-to-ebit, ev-to-revenue, ev-to-fcf, ev-to-cfo, and market-cap-to-fcf.

Because each slug is routed to its own source table independently, a single request can mix dimensions freely — pairing a daily price series with an -annual fundamental in one call is valid and common. Leave frequency at its default when you do, since setting it would filter out every slug that does not match.

Historical Metrics Request Examples

Copy any request below directly into your application.

1. Full History for One Metric
https://data.businessquant.com/historic?slug=revenue-annual&ticker=AAPL&period=max&api_key=YOUR_API_KEY
2. Three Metrics Across Two Tickers
https://data.businessquant.com/historic?slug=revenue-annual,gross-margin-annual,free-cash-flow-annual&ticker=AAPL,MSFT&period=5y&api_key=YOUR_API_KEY
3. Rebase Five Companies to a Common Baseline
https://data.businessquant.com/historic?slug=revenue-annual&ticker=AAPL,MSFT,GOOGL,AMZN,META&mode=normalized&period=10y&api_key=YOUR_API_KEY
4. Quarterly Cadence With Calendar Quarter Labels
https://data.businessquant.com/historic?slug=revenue&ticker=AAPL&frequency=quarterly&period=3y&api_key=YOUR_API_KEY
5. Drawdown From Running Peak
https://data.businessquant.com/historic?slug=price&ticker=NVDA&mode=pct_from_high&period=5y&api_key=YOUR_API_KEY
6. Every Company in an Industry
https://data.businessquant.com/historic?slug=gross-margin-annual&industry=Consumer Electronics&period=5y&api_key=YOUR_API_KEY

Frequently Asked Questions

Can I request multiple metrics and multiple tickers in the same API call?

Yes. Pass comma separated lists to both slug and ticker, up to 5 values each, giving a maximum of 5 metrics across 5 tickers in one request. Each metric is resolved to its own source table and queried independently, then all results are merged into one flat array. Exceeding either cap returns 400 stating how many values were supplied.

How do I find the slug for a metric?

Call /metadata?table=historic. It returns all 1,257 queryable metrics with slug, code, dimension, display names, and datatype, and is cached for 24 hours. Slugs follow a predictable pattern — quarterly metrics carry no suffix, trailing twelve month metrics end in -ttm, and fiscal year metrics end in -annual — but resolve them from the catalog rather than constructing them by hand, since not every metric exists at every cadence.

Why does the date field return 2024 Q3 instead of a full date?

Because you passed frequency=quarterly. That single parameter changes the output format of date from YYYY-MM-DD to a calendar quarter label such as 2024 Q3, which is convenient for axis labels but will break a strict date parser. Every other frequency returns YYYY-MM-DD. Request a quarterly slug without setting frequency if you need real dates.

How is this different from the Financial Statements API?

The Financial Statements API returns a whole statement for one company and period — the full income statement, balance sheet, or cash flow. This endpoint returns one named line item as a time-series across many periods, and lets you put several such series from several companies side by side in one response. Use that endpoint to read a filing; use this one to chart or model a single number over time.

Why are industry and sector empty on some rows?

The 12 daily valuation metrics — price, market-capitalization, enterprise-value, price-to-earnings and the rest — are stored separately from statement-derived fundamentals and carry no industry or sector classification, so both fields return an empty string. The practical consequence is that filtering by industry or sector without a ticker will not return those metrics at all — and returns 404 if a daily metric is the only slug you asked for. Pass ticker whenever your slug list includes a daily metric.

How does normalized mode make companies with different histories comparable?

It rebases every ticker to a shared starting point rather than to its own first observation. For each metric the API finds the first date on which all requested tickers have data, uses each company's value on that date as its baseline, and expresses everything after it as percentage change. Rows before that shared date are dropped. A company that listed in 2015 and one that listed in 1990 therefore both start at 0 on the same date, so the comparison is fair rather than distorted by unequal history.

Is the Historical Financial Metrics API free to use?

Yes, the Historical Financial Metrics API is free to use. Sign up for an API key to start pulling metric time-series immediately.