# Get Subnets Pools

Latest pool snapshot per subnet.

_Source: https://beta.taostats.io/docs/new/subnets/get-subnets-pools_

_Last reviewed: 2026-10-07_

```http
GET https://api.taostats.io/v1/subnets/pools
```

Requires an API key in the `Authorization` header.

Latest pool snapshot per subnet.

## Try it

Try this request in the browser on the HTML version of this page, or use the code samples below.

### Code samples

**cURL**

```bash
curl -H "Authorization: <YOUR_API_KEY>" \
  "https://api.taostats.io/v1/subnets/pools"
```

**JavaScript**

```js
const response = await fetch('https://api.taostats.io/v1/subnets/pools', {
  headers: {
    Authorization: '<YOUR_API_KEY>',
  },
});
const data = await response.json();
```

**Python**

```python
import requests

response = requests.get(
    "https://api.taostats.io/v1/subnets/pools",
    headers={"Authorization": "<YOUR_API_KEY>"},
)
data = response.json()
```

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `netuid` | query | `integer (int32)` |  | Filter by subnet ID. |
| `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: `netuid`. One of `netuid`, `price`, `liquidity`, `market_cap`, `tao_in_pool`, `total_alpha`, `alpha_in_pool`, `alpha_staked`, `root_prop`. |
| `order_dir` | query | `string` |  | Sort direction. Default: `asc`. One of `asc`, `desc`. |

## Responses

### `200` — Latest pool snapshot per subnet

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `data` | `array` | Yes |  |
| `data[].alpha_in_pool` | `string` | Yes | Alpha in pool (RAO, u64 as decimal string). |
| `data[].alpha_staked` | `string` | Yes | Alpha staked (RAO, u64 as decimal string). |
| `data[].block_number` | `integer (int32)` | Yes | Block height. |
| `data[].liquidity` | `string` | Yes | Liquidity (decimal string). |
| `data[].market_cap` | `string` | Yes | Market cap (decimal string). |
| `data[].netuid` | `integer (int32)` | Yes | Subnet ID. |
| `data[].price` | `string` | Yes | Current price (decimal string). |
| `data[].root_prop` | `string` | Yes | Root proportion (decimal string). |
| `data[].startup_mode` | `boolean` | Yes | Whether the subnet is in startup mode. |
| `data[].subnet_emission_enabled` | `boolean, nullable` | Yes | Whether the chain is running this subnet's pool-side emission (`SubtensorModule::SubnetEmissionEnabled`). `false` means the chain treats the subnet's `alpha_in`, `tao_in` and `excess_tao` chain buys as zero. `null` means **this block's row does not record it**, not "enabled", and it means that for either of two reasons. The block is below spec 411 (8,283,784), where the chain has no such switch at all and so there is nothing to record. Or the row was written before this column existed and the backfill has not reached it — and the backfill only covers spec 411 upward, because below that there is no value to fill in. From spec 411 up, a row this indexer writes always carries a value: an absent key is the storage item's own `true` default. **This field couples the API's rollout to the indexer's.** These routes select `?fields` expanded from `SubnetPoolRow`, so this binary names this column on every query, and the column only exists once `subnet-pools-v1`'s `ensure_tables` has added it. Roll the indexer first; an API rolled ahead of it returns 500 here until the indexer catches up. See `docs/deployment.md`, "A column added to an indexer's row". Carried on `/v1/subnets/pools` and `/v1/subnets/pools/history` alike, because it is a column of `subnet_pool_v1` rather than a latest-only enrichment like `subnet_protocol_alpha`. |
| `data[].subnet_protocol_alpha` | `string, nullable` | Yes | `SubtensorModule::SubnetProtocolAlpha(netuid)` — the alpha the coinbase bought back with this subnet's excess TAO and holds on the protocol's behalf (RAO, u64 as decimal string). `null` means **unknown**, never zero: from spec 413 the storage item is `ValueQuery`, so a subnet the chain has never written reads a real `0`. Only `/v1/subnets/pools` carries it — the value is indexed on `subnet_pool_latest_v1` alone, so `/v1/subnets/pools/history` always serves `null`. |
| `data[].symbol` | `string` | Yes | Subnet token symbol. |
| `data[].tao_in_pool` | `string` | Yes | TAO reserves in the subnet's pool (RAO, u64 as decimal string). |
| `data[].timestamp` | `string` | Yes | ISO 8601 timestamp with millisecond precision. |
| `data[].total_alpha` | `string` | Yes | Total alpha in subnet (RAO, u64 as decimal string). |
| `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](https://beta.taostats.io/docs/start-here/getting-started-with-taostats-api).
