subnetInfo_getSubnetsInfo - Bittensor RPC Method
Retrieve SCALE-encoded configuration and metadata for all Bittensor subnets. Essential for subnet discovery, parameter analysis, and network overview dashboards.
Overview
The subnetInfo_getSubnetsInfo method returns SCALE-encoded configuration and metadata for all active subnets on the Bittensor network. Unlike the metagraph methods which return per-neuron topology data, this method returns the subnet-level configuration: owner, emission values, hyperparameters, and registration settings.
This is the primary method for subnet discovery -- building a list of all active subnets with their key properties. Use it to populate subnet selection UIs, build network overview dashboards, or analyze how different subnets are configured.
Parameters
| Position | Name | Type | Required | Description |
|---|---|---|---|---|
| 0 | at | BlockHash | No | Optional block hash to query at a specific block. Pass null for the latest state |
Response
The result is a JSON array of SCALE bytes. When decoded, it returns a vector of subnet info structures. Each subnet entry contains configuration-oriented subnet metadata rather than the full live economic state:
| Field | Type | Description |
|---|---|---|
netuid | u16 | The subnet identifier |
rho | u16 | Rho parameter (global weight, affects consensus convergence rate) |
kappa | u16 | Kappa parameter (consensus temperature, controls weight sharpness) |
difficulty | u64 | Current registration difficulty (for PoW registration) |
immunity_period | u16 | Blocks a new neuron is immune from deregistration after registration |
max_allowed_validators | u16 | Maximum number of validators allowed on this subnet |
min_allowed_weights | u16 | Minimum number of weight entries a validator must set per epoch |
max_weights_limit | u16 | Maximum number of weight entries per validator |
subnetwork_n | u16 | Current number of registered neurons |
max_allowed_uids | u16 | Maximum number of neuron slots allowed in this subnet |
tempo | u16 | Blocks between consensus epochs (e.g., 360 = ~72 minutes at 12s/block) |
blocks_since_last_step | u64 | Blocks since the subnet last advanced its incentive step |
scaling_law_power | u16 | Subnet scaling-law parameter |
network_modality | u16 | Modality identifier used by the subnet runtime |
network_connect | Vec<(u16, u16)> | Deprecated connectivity field; often empty in current runtimes |
emission_values | u64 | Placeholder emission field; use subnetInfo_getDynamicInfo for live subnet economics |
burn | u64 | Current registration burn cost (RAO). Divide by 1e9 for TAO |
owner | AccountId32 | The coldkey that owns this subnet |
SCALE Decoding
The response decodes to Vec<Option<SubnetInfo>> where each element corresponds to a netuid slot. Empty slots (dissolved subnets) are represented as None.
Using @polkadot/api: Register the SubnetInfo type definition from the Bittensor type registry. The decoded result is an array of optional subnet info structs. Iterate and skip None entries for dissolved subnets.
Using bittensor Python SDK: Use sub.get_all_subnets_info() which returns a list of SubnetInfo objects with all fields accessible as properties.
Key decoding notes:
rhoandkappaare consensus hyperparameters. Higherkappa(closer to 65535) means sharper weight consensus; lower values produce smoother distributionstempois in blocks. At ~12 seconds per block, a tempo of 360 blocks means a consensus epoch roughly every 72 minutesdifficultyis relevant only for Proof-of-Work registration. Many subnets use burn-based registration instead (checkburnfield)max_allowed_uidsdefines the maximum subnet capacity. Whensubnetwork_nreaches this limit, new registrations must replace existing neurons- For live pricing, pool state, and subnet economics, use
subnetInfo_getDynamicInforather thansubnetInfo_getSubnetsInfo
Code Examples
Using SubstrateExamples
Decode with Python
import requests
import json
url = 'https://api-bittensor-mainnet.n.dwellir.com/YOUR_API_KEY'
payload = {
'jsonrpc': '2.0',
'method': 'subnetInfo_getSubnetsInfo',
'params': [None],
'id': 1
}
response = requests.post(url, json=payload)
result = response.json()
if result.get('result'):
scale_bytes = result['result']
print(f'All subnets info size: {len(scale_bytes)} bytes')
else:
print('No subnet info returned')
# To decode with bittensor SDK:
# import bittensor as bt
# sub = bt.subtensor(network='finney')
# subnets = sub.get_all_subnets_info()
# for s in subnets:
# print(f"Subnet {s.netuid}: neurons={s.subnetwork_n}/{s.max_n}, "
# f"tempo={s.tempo}, emission={s.emission_value}")Full Python subnet comparison
import bittensor as bt
sub = bt.subtensor(network='finney')
subnets = sub.get_all_subnets_info()
print(f"{'Netuid':>6} {'Neurons':>10} {'Max':>6} {'Tempo':>6} {'Burn (TAO)':>12} "
f"{'Emission/day':>14} {'Immunity':>9} {'Owner':<18}")
print("-" * 95)
total_emission = 0
for s in subnets:
if s is None:
continue
burn_tao = s.burn / 1e9
daily_emission_tao = (s.emission_value / 1e9) * 7200 # ~7200 blocks/day
total_emission += daily_emission_tao
print(f"{s.netuid:>6} {s.subnetwork_n:>6}/{s.max_n:<4} {s.tempo:>6} "
f"{burn_tao:>11,.2f} {daily_emission_tao:>13,.2f} {s.immunity_period:>9} "
f"{str(s.owner)[:16]}..")
print(f"\nTotal subnets: {len([s for s in subnets if s is not None])}")
print(f"Total daily emissions: {total_emission:,.2f} TAO")
# Find subnets with available capacity
open_subnets = [s for s in subnets if s and s.subnetwork_n < s.max_n]
print(f"Subnets with open slots: {len(open_subnets)}")
for s in sorted(open_subnets, key=lambda x: x.burn):
available = s.max_n - s.subnetwork_n
print(f" Subnet {s.netuid}: {available} slots available, burn={s.burn/1e9:.2f} TAO")Decode with JavaScript
import { ApiPromise, WsProvider } from '@polkadot/api';
const provider = new WsProvider('wss://api-bittensor-mainnet.n.dwellir.com/YOUR_API_KEY');
const api = await ApiPromise.create({ provider });
const subnetsInfo = await api.rpc.subnetInfo.getSubnetsInfo();
console.log('Raw data size:', subnetsInfo.toHex().length, 'bytes');
// With Bittensor types registered, iterate subnet configs:
// for (const subnet of subnetsInfo) {
// if (!subnet.isNone) {
// const s = subnet.unwrap();
// console.log(`Subnet ${s.netuid}: ${s.subnetwork_n}/${s.max_n} neurons`);
// }
// }
await api.disconnect();Query with cURL
curl -X POST https://api-bittensor-mainnet.n.dwellir.com/YOUR_API_KEY \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"method": "subnetInfo_getSubnetsInfo",
"params": [null],
"id": 1
}'Error Handling
| Error Scenario | Behavior | Recommended Action |
|---|---|---|
| Node not synced | Returns stale or incomplete subnet data | Check system_health before querying |
| Invalid block hash | Returns JSON-RPC error | Verify the block hash exists on chain |
| Large response timeout | Connection may drop | Increase HTTP timeout to 30+ seconds |
| Method not found | Error -32601 | Ensure node supports Bittensor custom RPCs |
| Rate limit exceeded | HTTP 429 | Cache results; subnet config changes infrequently |
Caching strategy: Subnet configuration changes rarely (only when subnet owners update hyperparameters via governance). Cache this response for 5--15 minutes. The emission_value field changes more frequently but is still relatively stable between tempo epochs.
Common Use Cases
- Subnet discovery — Build a catalog of all active subnets with their key parameters for users to browse and compare.
- Parameter analysis — Compare hyperparameters (tempo, difficulty, immunity period) across subnets to understand how they are configured.
- Network overview — Display total neurons, emission allocations, and growth trends across all subnets.
- Registration planning — Check registration difficulty and burn costs before deciding which subnet to register on. Find subnets with available capacity.
- Governance monitoring — Track subnet ownership and configuration changes over time by querying at different block hashes.
- Emission modeling — Analyze how emissions are distributed across subnets and predict future allocation changes.
- Capacity planning — Identify subnets nearing their
max_nlimit to anticipate registration competition.
Related Methods
subnetInfo_getSubnetInfo— Get configuration info for a single subnetsubnetInfo_getDynamicInfo— Get dynamic info (emissions, registration costs) for a specific subnetsubnetInfo_getAllDynamicInfo— Get dynamic info for all subnetssubnetInfo_getSubnetHyperparams— Get hyperparameters for a specific subnetsubnetInfo_getMetagraph— Get the metagraph for a specific subnetsubnetInfo_getLockCost— Get the TAO lock cost for creating a new subnet
subnetInfo_getSubnetToPrune - JSON-RPC Method
Fetch the next subnet id (netuid) scheduled to prune on Bittensor.
subnetInfo_getSubnetsInfo_v2 - Bittensor RPC Method
Retrieve the V2 SCALE-encoded subnet catalog for every active Bittensor subnet. Use it for subnet discovery, dashboard backends, and comparing live subnet state.