Documentation / New API reference / Subnets
Get Subnets Stake Events
Reference
Last reviewed 2026-10-07
DTAO-era alpha stake/unstake events.
Try it
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
coldkey | query | string | Filter by coldkey (SS58 or 0x-hex). | |
hotkey | query | string | Filter by hotkey (SS58 or 0x-hex). | |
action | query | string | Filter by action. Default: all. One of stake, unstake, all. | |
is_transfer | query | boolean | Filter by transfer flag. | |
transfer_address | query | string | Filter by transfer counterparty address (SS58 or 0x-hex). | |
trades_only | query | boolean | true keeps only the rows the indexer's TRADE_ONLY_PREDICATE counts as trades, the same definition the pool volume figures and the CoinGecko and CoinMarketCap feeds use: it drops stake transfers, hotkey-swap legs and, from block 6,067,944, within-subnet move legs. Where that definition is wrong (#1403), this follows it. false or absent applies no filter. | |
netuid | query | integer (int32) | Filter by subnet ID. | |
extrinsic_id | query | string | Filter by extrinsic ID. | |
amount_min | query | integer (int64) | Minimum TAO amount (RAO, inclusive). | |
amount_max | query | integer (int64) | Maximum TAO amount (RAO, inclusive). | |
block_number | query | integer (int32) | Filter by a specific block. | |
block_start | query | integer (int32) | Block range start (inclusive). | |
block_end | query | integer (int32) | Block range end (inclusive). | |
timestamp_start | query | integer (int64) | Timestamp range start, Unix seconds (inclusive). | |
timestamp_end | query | integer (int64) | Timestamp range end, Unix seconds (inclusive). | |
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: timestamp. One of timestamp. | |
order_dir | query | string | Sort direction. Default: desc. One of asc, desc. |
Responses
200 — Paginated list of dTAO stake/unstake events
| Field | Type | Required | Description |
|---|---|---|---|
data | array | Yes | |
data[].action | string | Yes | stake or unstake. |
data[].alpha | string, nullable | Yes | Alpha amount (RAO, u64 as decimal string). |
data[].alpha_price_in_tao | string, nullable | Yes | The trade's average execution price in TAO — its own TAO leg divided by its own alpha leg, not the subnet pool's spot price. See docs/api_spec.md, "An event's price is an execution price" (#984). |
data[].alpha_price_in_usd | string, nullable | Yes | The execution price above, in USD at the price in force at the event, to two decimal places. null when no price covers the row. Two decimal places is savage on a cheap alpha — anything under half a cent reads as "0.00" — but that is what the OLD API serves and parity is the point. |
data[].amount | string | Yes | TAO amount (RAO, u64 as decimal string). |
data[].block_number | integer (int32) | Yes | Block height. |
data[].coldkey | string | Yes | Coldkey (SS58). |
data[].extrinsic_id | string, nullable | Yes | Extrinsic ID. |
data[].fee | string, nullable | Yes | Stake fee (RAO, u64 as decimal string). |
data[].hotkey | string | Yes | Hotkey (SS58). |
data[].hotkey_name | string, nullable | Yes | The hotkey's current identity name; null when its owner has none. |
data[].id | string | Yes | Event ID ({block}-{event_index} style, unique). |
data[].is_transfer | boolean | Yes | true when this event is a leg of a stake transfer, false otherwise. Never null (#1381), unlike the OLD API, which serves null for a non-transfer. |
data[].netuid | integer (int32), nullable | Yes | Subnet ID. |
data[].registration_collateral | boolean | Yes | true when this stake event is the miner registration collateral leg of a burned registration (spec 435+), not a discretionary delegation. The alpha is real staked balance, so the row is kept and flagged rather than dropped; filter on this to exclude it from delegation views. Always false before spec 435. |
data[].slippage | string, nullable | Yes | Signed slippage percentage (decimal string). |
data[].timestamp | string | Yes | ISO 8601 timestamp with millisecond precision. |
data[].transfer_address | string, nullable | Yes | Transfer counterparty address (SS58). |
data[].usd | string, nullable | Yes | USD value of the TAO leg at the price in force at the event, to two decimal places. null when no price covers the row. |
data[].validator_swap | boolean | Yes | true when this row is one leg of a within-subnet move between validators (move_stake/swap_stake with the same origin and destination subnet). From block 6,067,944 the chain settles such a move without touching the pool, so the leg is neither a buy nor a sell; below it the move went through the pool and the leg is a real trade (#911). To list trades, use trades_only=true rather than this flag alone. |
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.