Documentation / New API reference / Validators
Get Validators Baskets History
Reference
Last reviewed 2026-10-07
Daily beta-basket history.
Try it
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
hotkey | query | string | Filter to one validator hotkey (SS58 or 0x-hex). | |
timestamp_start | query | integer (int64) | Range start, unix seconds (inclusive). Resolved to the UTC day the instant falls in, since rows are one-per-day. | |
timestamp_end | query | integer (int64) | Range end, unix seconds (inclusive). Resolved to the UTC day the instant falls in, so the whole of that day is included. | |
page | query | integer (int32) | Page number (1-indexed). Default: 1. Bounded window: (page − 1) × limit must be below 1,000,000. Deep OFFSET paging is linear in the offset, so an uncapped page lets one request scan tens of millions of rows; a page past the window is rejected with a 400. Reach deeper history with this endpoint's range filters (block_start/block_end, timestamp_start/timestamp_end) rather than a larger page. | |
limit | query | integer (int32) | Results per page. Default: 50. Max: 200. | |
order_by | query | string | Column to order by. Default: day. One of day, nav_tao, spot_nav_tao, shares, nav_per_share, performance, return_7d, return_30d, staker_return_7d, staker_return_30d. | |
order_dir | query | string | Sort direction. Default: desc. One of asc, desc. |
Responses
200 — Daily beta-basket history
| Field | Type | Required | Description |
|---|---|---|---|
data | array | Yes | |
data[].block_number | integer (int32) | Yes | Block the snapshot was read at. |
data[].day | string | Yes | UTC date of timestamp (YYYY-MM-DD). On the history endpoint it is the row's identity — the day whose closing block this snapshot is. |
data[].deposited_tao | string | Yes | Lifetime realizable TAO deposited into the fund (RAO, u64 as decimal string). |
data[].holdings | array | Yes | Per-subnet holdings, each valued at spot and realizable. |
data[].holdings[].alpha | string | Yes | Alpha held (RAO, u64 as decimal string). |
data[].holdings[].netuid | integer (int32) | Yes | Subnet ID. |
data[].holdings[].realizable_tao | string | Yes | Slippage-aware redemption quote net of fees (RAO, u64 as decimal string). This, not spot_tao, is what nav_tao is the sum of. |
data[].holdings[].spot_tao | string | Yes | Spot mark, price × alpha (RAO, u64 as decimal string). Display only — the chain itself says spot "is exposed for display/analytics only and is never used for share pricing or redemption sizing". |
data[].hotkey | string | Yes | Validator hotkey (SS58). |
data[].nav_per_share | number (double), nullable | Yes | nav_tao / shares. null when the fund has no shares outstanding — no supply means no share price, and 0.0 would read as "worthless". |
data[].nav_tao | string | Yes | Realizable (slippage-aware) NAV — the fund's redemption value, and the basis of every derived figure here (RAO, u64 as decimal string). |
data[].performance | number (double), nullable | Yes | (nav_tao + redeemed_tao) / deposited_tao — the lifetime multiple, 1.0 is break-even. null when nothing was ever deposited. |
data[].rate | number (double) | Yes | SubtensorModule::BasketRate — cumulative fund shares accrued per unit of root stake. Never null: the chain declares the map ValueQuery with a zero default, so an absent key is a real 0. |
data[].redeemed_tao | string | Yes | Lifetime TAO redeemed out of the fund (RAO, u64 as decimal string). |
data[].return_30d | number (double), nullable | Yes | As return_7d, over 30 days. |
data[].return_7d | number (double), nullable | Yes | Capital return on nav_per_share over 7 days — not annualised, and legitimately negative. null until the window has an anchor. |
data[].shares | string | Yes | Outstanding fund shares (u64 as decimal string). |
data[].spot_nav_tao | string | Yes | Spot-marked NAV, Σ price × alpha (RAO, u64 as decimal string) — the headline mark only. |
data[].staker_return_30d | number (double), nullable | Yes | As staker_return_7d, over 30 days. |
data[].staker_return_7d | number (double), nullable | Yes | Staker total return over 7 days, twr / twr_then − 1 — income and mark-to-market together, not annualised, defined only within one fund life. null when either sample is missing or the two are from different lives. |
data[].timestamp | string | Yes | ISO 8601 timestamp with millisecond precision. |
data[].twr | number (double), nullable | Yes | SubtensorModule::BasketTwr — the fund's staker total-return accumulator, 1.0 at each fund life's baseline. null on a runtime before release 450, which introduced it. |
data[].twr_first_block | string, nullable | Yes | BetaBaseline.first_block — the block this fund's current life was stamped at (u64 as decimal string). Two twr samples are comparable only within one life. null pre-450 and for a fund the chain calls provisional (shares outstanding, no baseline stamped) — never 0, which is a block number. |
data[].weights | array | Yes | The validator's root weight vector — its curation strategy, as stored. Empty for every validator while RootWeightSettingEnabled is off. |
data[].weights[].netuid | integer (int32) | Yes | Subnet ID. |
data[].weights[].weight | integer (int32) | Yes | Raw chain weight. |
pagination | object | Yes | Pagination metadata appended to collection responses. next_page / prev_page are explicitly required+nullable in the OpenAPI spec: per docs/api_standards.md we emit null rather than omitting the field, so the SDK should model them as Option/nullable types that are always present in the response. total_items is the exact number of matching rows on every route (issue #992). It used to stop at 1,000,000, which reported a million transfers when finney holds 7,513,252 and a million events when the real figure is 981,179,110; the cap was removed on 29 Sep 2026 and nothing may reintroduce one — crate::pagination::exact_count_sql is the only count form, and no_capped_count_reaches_the_api_surface in data-debug-scripts fails the build if a capped one comes back. total_pages is still bounded, to crate::pagination::max_reachable_page(per_page), because the page parameter is capped to a 1,000,000-row window: deep OFFSET paging reads every skipped row (24.7M rows / 36.6 GiB / 42 s measured on one endpoint, issue #413). So total_pages is exactly the last page this API will serve and next_page / prev_page stay coherent at the window edge, while total_items tells the caller how many rows there really are. History beyond the window is reached with each endpoint's range filters, not a larger page. |
pagination.current_page | integer (int32) | Yes | 1-indexed page that produced the rows in data. |
pagination.next_page | integer (int32), nullable | Yes | Next page number, or null if this is the last page. |
pagination.per_page | integer (int32) | Yes | Number of items requested per page. |
pagination.prev_page | integer (int32), nullable | Yes | Previous page number, or null if this is the first page. |
pagination.total_items | integer (int64) | Yes | Number of items matching the query across all pages. This is the exact count — every matching row, however many there are. It is not bounded by total_pages, so a listing can legitimately report far more items than total_pages × per_page. |
pagination.total_pages | integer (int32) | Yes | Number of pages at the current per_page that this API will serve: ceil(total_items / per_page), capped at ceil(1000000 / per_page) because the page parameter only reaches into the first 1,000,000 rows. When the cap bites, total_items is still the true total and this is the last page a request can ask for; reach deeper history with the endpoint's range filters instead of a larger page. |
400 — Invalid query parameter
| Field | Type | Required | Description |
|---|---|---|---|
message | string | Yes | Plain-english message describing the failure from the caller's perspective. |
status_code | integer (int32) | Yes | HTTP status code (mirrored in the response status line for convenience). |
500 — Internal server error
| Field | Type | Required | Description |
|---|---|---|---|
message | string | Yes | Plain-english message describing the failure from the caller's perspective. |
status_code | integer (int32) | Yes | HTTP status code (mirrored in the response status line for convenience). |
Every request needs an Authorization header holding your API key — see Getting started with the Taostats API.