Docs

neuronInfo_getNeuron - Bittensor RPC Method

Retrieve SCALE-encoded detailed information for a specific neuron by UID within a Bittensor subnet. Essential for miner/validator monitoring and performance tracking.

Overview

The neuronInfo_getNeuron method returns SCALE-encoded detailed information for a specific neuron identified by its UID within a Bittensor subnet. Every participant in a subnet -- whether a validator or a miner -- is a "neuron" with a unique UID assigned at registration time.

This method returns comprehensive data about a single neuron: its identity (hotkey/coldkey), stake, performance scores (trust, consensus, incentive, dividends), emission earnings, axon endpoint, and weight/bond information. It is the most detailed single-neuron query available.

Use this method when you need to inspect a specific neuron's state -- for example, after looking up a UID in the metagraph and wanting the full detail view.

Parameters

PositionNameTypeRequiredDescription
0netuidu16YesThe subnet identifier
1uidu16YesThe neuron's unique identifier within the subnet
2atBlockHashNoOptional 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, the neuron info contains:

FieldTypeDescription
hotkeyAccountId32The neuron's hotkey address (identifies the neuron on-chain)
coldkeyAccountId32The neuron's coldkey (owner) address
uidu16Neuron UID within the subnet
netuidu16The subnet identifier
activeboolWhether the neuron is currently active
stakeVec<(AccountId32, Compact<u64>)>Stake entries associated with the neuron on the queried subnet
ranku16Neuron's rank score (0--65535 scaled)
emissionu64Emissions earned per tempo (RAO). Divide by 1e9 for TAO
incentiveu16Incentive score (0--65535 scaled). Higher = better-performing miner
consensusu16Consensus score (0--65535 scaled). Reflects agreement among validators
trustu16Trust score (0--65535 scaled). Measures how much other neurons trust this one
validator_trustu16Validator-specific trust score (how much other validators trust this one)
dividendsu16Dividend score (0--65535 scaled). Higher = more validator reward share
last_updateu64Last block this neuron set weights
validator_permitboolWhether this neuron has a validator permit
weightsVec<(u16, u16)>Weight assignments to other neurons (target_uid, weight)
bondsVec<(u16, u16)>Bond assignments (target_uid, bond_amount)
axon_infoAxonInfoNetwork endpoint (IP, port, protocol version)
prometheus_infoPrometheusInfoPrometheus metrics endpoint (IP, port)
pruning_scoreu16Score used to determine deregistration priority (lower = more likely to be pruned)

SCALE Decoding

The response decodes to a NeuronInfo struct using Bittensor's custom type registry.

Using @polkadot/api: Register the following types:

  • NeuronInfo: The main neuron struct with all fields listed above
  • AxonInfo: Contains version (u32), ip (u128), port (u16), ip_type (u8), protocol (u8), placeholder1 (u8), placeholder2 (u8)
  • PrometheusInfo: Contains version (u32), ip (u128), port (u16), ip_type (u8)

Using bittensor Python SDK: Use sub.neuron_for_uid(uid=N, netuid=M) which returns a NeuronInfo namedtuple with all fields decoded and converted to human-readable formats.

Key decoding notes:

  • All u16 score fields are scaled 0--65535. Divide by 65535 for float values (0.0--1.0)
  • The stake field is a vector of staking entries. Sum the decoded amounts if you need a total stake figure.
  • emission is in RAO per tempo. To get TAO per day: (emission / 1e9) * (7200 / tempo) where tempo is the subnet's block interval
  • IP addresses in axon_info and prometheus_info are stored as u128. For IPv4, convert the 4 least significant bytes
  • weights is a sparse vector: only non-zero weight assignments are included

Code Examples

Using SubstrateExamples

Decode with Python

Python
import requests
import json

url = 'https://api-bittensor-mainnet.n.dwellir.com/YOUR_API_KEY'

# Fetch neuron info for UID 0 in subnet 1
payload = {
    'jsonrpc': '2.0',
    'method': 'neuronInfo_getNeuron',
    'params': [1, 0, None],
    'id': 1
}

response = requests.post(url, json=payload)
result = response.json()

if result.get('result'):
    scale_bytes = result['result']
    print(f'Neuron info SCALE data size: {len(scale_bytes)} bytes')
else:
    print('No neuron found at this UID')

# To decode with bittensor SDK:
# import bittensor as bt
# sub = bt.subtensor(network='finney')
# neuron = sub.neuron_for_uid(uid=0, netuid=1)
# print(f"Hotkey: {neuron.hotkey}")
# print(f"Stake: {neuron.stake:.4f} TAO")
# print(f"Trust: {neuron.trust:.4f}")
# print(f"Incentive: {neuron.incentive:.4f}")
# print(f"Emission: {neuron.emission:.4f} TAO/tempo")

Full Python neuron analysis

Python
import bittensor as bt
import socket
import struct

sub = bt.subtensor(network='finney')

# Detailed neuron inspection
netuid = 1
uid = 0
neuron = sub.neuron_for_uid(uid=uid, netuid=netuid)

print(f"=== Neuron UID {uid} on Subnet {netuid} ===")
print(f"Hotkey:  {neuron.hotkey}")
print(f"Coldkey: {neuron.coldkey}")
print(f"Active:  {neuron.active}")

# Role identification
role = "Validator" if neuron.validator_permit else "Miner"
print(f"Role:    {role}")

# Performance scores
print(f"\n--- Performance ---")
print(f"Trust:           {neuron.trust:.4f}")
print(f"Consensus:       {neuron.consensus:.4f}")
print(f"Incentive:       {neuron.incentive:.4f}")
print(f"Dividends:       {neuron.dividends:.4f}")
print(f"Rank:            {neuron.rank:.4f}")
print(f"Validator Trust: {neuron.validator_trust:.4f}")
print(f"Pruning Score:   {neuron.pruning_score:.4f}")

# Stake breakdown
print(f"\n--- Stake ---")
total_stake = sum(amount.tao for _, amount in neuron.stake)
print(f"Total stake: {total_stake:,.2f} TAO ({len(neuron.stake)} stake entries)")
for coldkey, amount in sorted(neuron.stake, key=lambda x: x[1], reverse=True)[:5]:
    pct = (amount.tao / total_stake * 100) if total_stake > 0 else 0
    print(f"  {coldkey[:18]}.. : {amount.tao:>12,.2f} TAO ({pct:.1f}%)")

# Emissions
print(f"\n--- Emissions ---")
print(f"Emission per tempo: {neuron.emission:.6f} TAO")

# Weight analysis (for validators)
if neuron.validator_permit and neuron.weights:
    print(f"\n--- Weights (top 10) ---")
    sorted_weights = sorted(neuron.weights, key=lambda x: x[1], reverse=True)
    for target_uid, weight in sorted_weights[:10]:
        print(f"  -> UID {target_uid}: weight={weight / 65535:.4f}")

# Network endpoint
if neuron.axon_info.ip != 0:
    ip_bytes = neuron.axon_info.ip.to_bytes(16, 'big')
    ip_str = socket.inet_ntoa(ip_bytes[-4:])
    print(f"\n--- Axon Endpoint ---")
    print(f"IP: {ip_str}:{neuron.axon_info.port}")
    print(f"Version: {neuron.axon_info.version}")

# Last activity
current_block = sub.block
blocks_since_update = current_block - neuron.last_update
minutes_since = blocks_since_update * 12 / 60
print(f"\n--- Activity ---")
print(f"Last weight update: block {neuron.last_update} ({blocks_since_update} blocks / ~{minutes_since:.0f} min ago)")

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 });

// Fetch neuron info for UID 0 in subnet 1
const neuronInfo = await api.rpc.neuronInfo.getNeuron(1, 0);
console.log('Raw data size:', neuronInfo.toHex().length, 'bytes');

// With Bittensor types registered:
// console.log('Hotkey:', neuronInfo.hotkey.toHuman());
// console.log('Active:', neuronInfo.active.toString());
// console.log('Emission:', neuronInfo.emission.toString());
// console.log('Validator permit:', neuronInfo.validator_permit.toString());

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": "neuronInfo_getNeuron",
    "params": [1, 0, null],
    "id": 1
  }'

Historical performance tracking

Python
import requests

url = 'https://api-bittensor-mainnet.n.dwellir.com/YOUR_API_KEY'

# Query neuron state at multiple past blocks to track performance
netuid = 1
uid = 42
block_hashes = ['0xabc...', '0xdef...', '0x123...']  # Past block hashes

for i, block_hash in enumerate(block_hashes):
    payload = {
        'jsonrpc': '2.0',
        'method': 'neuronInfo_getNeuron',
        'params': [netuid, uid, block_hash],
        'id': i + 1
    }
    response = requests.post(url, json=payload)
    result = response.json()
    if result.get('result'):
        print(f"Block {block_hash[:10]}...: {len(result['result']) // 2} bytes")
    # Decode each snapshot to track score changes over time

Error Handling

Error ScenarioBehaviorRecommended Action
Invalid netuidReturns null or errorVerify subnet exists via subnetInfo_getSubnetsInfo
UID out of rangeReturns null, an empty payload, or a placeholder neuron depending on runtime toolingCheck subnet size via subnetInfo_getMetagraph before querying
Deregistered neuronDecodes to a low-signal or placeholder neuron payload depending on runtime toolingCross-check the UID against the current metagraph before treating the record as active
Invalid block hashReturns JSON-RPC errorVerify block hash exists
Node not syncedMay return stale neuron dataCheck system_health
Rate limit exceededHTTP 429Cache neuron data; refresh once per tempo

Common Use Cases

  • Miner monitoring — Track a miner's incentive score, rank, emission earnings, and active status over time.
  • Validator monitoring — Monitor a validator's trust, consensus scores, and weight-setting frequency.
  • Performance tracking — Compare a neuron's scores across blocks to detect performance trends or anomalies.
  • Axon discovery — Look up a neuron's network endpoint (IP/port) for direct communication.
  • Staking decisions — Inspect a neuron's stake distribution, validator permit status, and trust before delegating.
  • Explorer views — Build neuron detail pages showing all attributes for a specific participant.
  • Pruning risk assessment — Monitor the pruning score to anticipate potential deregistration.
  • Weight auditing — Inspect a validator's weight assignments to verify they are evaluating miners correctly.