Docs

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

PositionNameTypeRequiredDescription
0atBlockHashNoOptional 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:

FieldTypeDescription
netuidu16The subnet identifier
rhou16Rho parameter (global weight, affects consensus convergence rate)
kappau16Kappa parameter (consensus temperature, controls weight sharpness)
difficultyu64Current registration difficulty (for PoW registration)
immunity_periodu16Blocks a new neuron is immune from deregistration after registration
max_allowed_validatorsu16Maximum number of validators allowed on this subnet
min_allowed_weightsu16Minimum number of weight entries a validator must set per epoch
max_weights_limitu16Maximum number of weight entries per validator
subnetwork_nu16Current number of registered neurons
max_allowed_uidsu16Maximum number of neuron slots allowed in this subnet
tempou16Blocks between consensus epochs (e.g., 360 = ~72 minutes at 12s/block)
blocks_since_last_stepu64Blocks since the subnet last advanced its incentive step
scaling_law_poweru16Subnet scaling-law parameter
network_modalityu16Modality identifier used by the subnet runtime
network_connectVec<(u16, u16)>Deprecated connectivity field; often empty in current runtimes
emission_valuesu64Placeholder emission field; use subnetInfo_getDynamicInfo for live subnet economics
burnu64Current registration burn cost (RAO). Divide by 1e9 for TAO
ownerAccountId32The 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:

  • rho and kappa are consensus hyperparameters. Higher kappa (closer to 65535) means sharper weight consensus; lower values produce smoother distributions
  • tempo is in blocks. At ~12 seconds per block, a tempo of 360 blocks means a consensus epoch roughly every 72 minutes
  • difficulty is relevant only for Proof-of-Work registration. Many subnets use burn-based registration instead (check burn field)
  • max_allowed_uids defines the maximum subnet capacity. When subnetwork_n reaches this limit, new registrations must replace existing neurons
  • For live pricing, pool state, and subnet economics, use subnetInfo_getDynamicInfo rather than subnetInfo_getSubnetsInfo

Code Examples

Using SubstrateExamples

Decode with Python

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

Python
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

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

Bash
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 ScenarioBehaviorRecommended Action
Node not syncedReturns stale or incomplete subnet dataCheck system_health before querying
Invalid block hashReturns JSON-RPC errorVerify the block hash exists on chain
Large response timeoutConnection may dropIncrease HTTP timeout to 30+ seconds
Method not foundError -32601Ensure node supports Bittensor custom RPCs
Rate limit exceededHTTP 429Cache 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_n limit to anticipate registration competition.