GET /api/metrics/distribution Metric Distribution
How one metric is spread across all assets, and how that spread changes over time — for example, how many assets score 5 against how many score 0, month by month.
For each step in the date range, every asset’s value of metric is summarised into one row of statistics (mean, median, p25, p75, p90) and, for scores and other bucketed metrics, a histogram (buckets).
Designed for “how is this metric distributed across the population, and how is that distribution drifting?” — not for per-symbol time series (use /api/metrics/:symbol for that).
Request
# ByteTrend Weekly CAPR distribution, monthly steps, all of 2025
curl "https://api.bytetree.io/api/metrics/distribution?metric=byteTrendCapr200w&from=2025-01-01&frequency=monthly"
# trendAge200w across active stocks, weekly
curl "https://api.bytetree.io/api/metrics/distribution?metric=trendAge200w&from=2026-01-01&type=stock&status=active"
# Continuous metric (Sharpe) for a single sector, weekly
curl "https://api.bytetree.io/api/metrics/distribution?metric=sharpe52w&from=2025-06-01§or=Technology"
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
metric | string | Yes | Metric key. Allow-listed (40 entries — byteTrend{Local,Capr}{200w,30d}, trendAge200w, plus 35 continuous metrics). Send any unrecognised value to receive a 400 with the full allow-list echoed |
from | string | Yes | Inclusive ISO YYYY-MM-DD start date |
to | string | No | Inclusive ISO YYYY-MM-DD end date. Defaults to today |
frequency | string | No | Step granularity: daily, weekly, monthly. Default weekly |
type | string | No | Asset-type filter — stock, crypto, etf, index, commodity. fx is rejected (no synthesised distribution surface) |
status | string | No | Asset status — active, pending, inactive |
sector | string | No | Sector filter (case-insensitive) |
q | string | No | Free-text symbol/name search across the asset population |
universe | string | No | Universe slug (e.g. bytetrend, bytefolio) — see Universes. Membership filter: the population becomes that universe’s members. Unknown slugs and macro return 400 — see Group filters |
dimension | string | No | One of the five global dimensions: region, sector, industry, type, or country. Paired with group; independent of universe |
group | string | No | Group label within dimension, exact match. Paired with dimension |
format | string | No | Response format: json (default), csv, or toon |
Group filters
universe restricts the population to that universe’s members — the assets whose universes[] includes the slug. Without it, the population is the whole registry.
dimension + group narrow the population by the asset’s resolved value in one of the five global dimensions. The pair is independent of universe — it works on the whole registry or within a universe — and both-or-neither: one without the other is a 400, as is an unknown dimension. type, status, sector and q compose with all of these.
# ByteTrend members only
curl "https://api.bytetree.io/api/metrics/distribution?metric=byteTrendLocal200w&from=2026-01-01&universe=bytetrend"
# Technology sector across the whole registry
curl "https://api.bytetree.io/api/metrics/distribution?metric=byteTrendLocal200w&from=2026-01-01&dimension=sector&group=Technology"
?universe=macro is a 400 — the macro dataset is a computed aggregation at /api/macro, not a universe. Filter by nothing to cover the whole registry.
Response
| Field | Type | Description |
|---|---|---|
generatedAt | string | ISO timestamp captured when the server ran the aggregation |
metric | string | Echo of the resolved metric key |
frequency | string | Echo of the requested frequency |
count | number | Number of timestep rows in data |
data | object[] | One row per timestep |
data[].date | string | ISO YYYY-MM-DD of this timestep |
data[].n | number | Number of assets contributing to this row |
data[].stats | object | Always present — mean, median, p25, p75, p90. Percentiles are approximate |
data[].buckets | object or absent | Histogram, present only for bucketed metrics — see below |
Bucket-vs-percentile branching
The shape of buckets depends on the metric:
- Discrete-score metrics (the four ByteTrend variants —
byteTrendLocal200w,byteTrendCapr200w,byteTrendLocal30d,byteTrendCapr30d) —bucket-discrete. Keys are the integer scores"0","1","2","3","4","5"; values are the count of assets at that score. All six keys are emitted even when the count is zero. trendAge200w—bucket-range. Keys are the lower bound of each bin:"0"(0–4 days),"5"(5–29),"30"(30–89),"90"(90–364),"365"(365–1824),"1825"(1825+). Semantic age bins.- Continuous metrics (returns, Sharpe, dollar volume, market cap, MA deviations, etc.) —
bucketsis absent. Usestatsfor the shape.
{
"generatedAt": "2026-05-07T19:34:35.517Z",
"metric": "byteTrendCapr200w",
"frequency": "monthly",
"count": 17,
"data": [
{
"date": "2025-01-01",
"n": 5075,
"stats": { "mean": 2.60, "median": 3, "p25": 1, "p75": 5, "p90": 5 },
"buckets": { "0": 1170, "1": 633, "2": 689, "3": 562, "4": 602, "5": 1419 }
}
]
}
Bounds
- Projected-rows cap. If the requested
(from, to, frequency)expansion would exceed 5000 timestep rows the server returns400with a hint to narrow the range or coarsen the frequency. The cap protects the engine and the consumer — wider windows are still cheap atmonthly. type=fxis rejected with400. FX has its own dedicated surface; cross-asset-class distributions don’t make conceptual sense here.
Notes
- Requires an API key.
- The asset population for each timestep is the set of assets that have a value for the metric on that date.
nreflects coverage and will vary as new symbols accumulate enough history (e.g. forbyteTrend*200w,nrises as symbols pass their 200-week eligibility threshold). - Backs the public ByteTree MCP’s
get_metric_distributiontool.