RPC
One read-only JSON-RPC URL for Bittensor — health-aware load balancing, failover, and abuse controls. Plus the pool roster, endpoint catalog, and proxy usage analytics. No API key.
Last updated
Proxy
POST a single JSON-RPC object to /rpc/v1/{network}. Supported networks: finney (mainnet) and test (testnet). WebSocket upgrade is not available on this HTTP path — use wss.metagraph.sh or a public WSS endpoint.
POST https://api.metagraph.sh/rpc/v1/{network}finney→https://api.metagraph.sh/rpc/v1/finneytest→https://api.metagraph.sh/rpc/v1/test
curl -s 'https://api.metagraph.sh/rpc/v1/finney' \
-X POST -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"chain_getHeader","params":[]}'Catalog & analytics
Static registry projections and live proxy telemetry. Live explorer UI for pools and traffic lives on Endpoints.
| Method | Path | Summary | Notes |
|---|---|---|---|
| POST | /rpc/v1/{network} | Read-only JSON-RPC reverse proxy | Network segment is finney (mainnet) or test (testnet). Single JSON-RPC object only — no batches, no HTTP WebSocket upgrade. |
| GET | /api/v1/rpc/pools | Proxy pool roster + live eligibility | Serves rpc/pools.json with probe-derived health overlaid from KV so dead upstreams show as ineligible. |
| GET | /api/v1/rpc/endpoints | Base-layer Subtensor RPC/WSS registry | Filterable catalog (kind, layer, status, provider, pool_eligible, latency). Pair with the live table on Endpoints. |
| GET | /api/v1/rpc/usage | Proxy usage analytics | Request volume, latency p50/p95, failover/error/cache rates, per-endpoint and per-network distribution. ?window=7d|30d. |
Allowlisted methods
Only safe read methods pass. Mutating and heavy prefixes are denied. State-query methods need param validation and a separate rate budget.
Denied prefixes get rejected outright
author_, state_call, sudo_, payment_, and contracts_ calls never reach the upstream node
— the proxy rejects them before dispatch, not after.
Safe methods
chain_getBlock · chain_getBlockHash · chain_getFinalizedHead · chain_getHeader · rpc_methods · state_getRuntimeVersion · system_chain · system_health · system_name · system_properties · system_version
State-query (extra rate budget)
state_getStorage · state_getKeysPaged
Denied prefixes
author_* · state_call* · sudo_* · payment_* · contracts_*
Gated fullnode access
An account-gated tier for real fullnode RPC access — not just the read-only proxy above. Requires a wallet-signed login; no invite code, self-serve. Grants the same safe read methods as the public proxy, plus author_submitExtrinsic (real transaction broadcast), at a materially higher rate limit than the keyless tier. Every key starts on the default (free) tier; a higher tier is granted directly to your account, not by a code you present.
1. Request a challenge
curl -s https://api.metagraph.sh/api/v1/auth/wallet/challenge \
-X POST -H 'content-type: application/json' \
-d '{"ss58":"YOUR_SS58_ADDRESS"}'Returns a message to sign and how long it stays valid.
2. Sign the message with your wallet
Sign the returned message as raw bytes with your own wallet signer (e.g. @polkadot/extension-dapp's signRaw({ address, data: message, type: "bytes" })). The signing key material never reaches this API — only the resulting signature does.
3. Verify and get a session
curl -s https://api.metagraph.sh/api/v1/auth/wallet/verify \
-X POST -H 'content-type: application/json' \
-d '{"ss58":"YOUR_SS58_ADDRESS","signature":"YOUR_HEX_SIGNATURE"}'Returns a session_token — scoped only to key management (create/list/revoke your own keys), not itself the RPC credential.
4. Mint your key
curl -s https://api.metagraph.sh/api/v1/keys \
-X POST \
-H "authorization: Bearer YOUR_SESSION_TOKEN"Returns the full mg_... key exactly once — store it yourself; it's never shown again, along with a key_id. Revoke anytime with DELETE /api/v1/keys/{key_id}, presenting the same session.
5. Call the gated proxy
curl -s 'https://api.metagraph.sh/rpc/v1/fullnode?authorization=YOUR_KEY' \
-X POST -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"chain_getHeader","params":[]}'The key travels as an ?authorization= query parameter, not a header — matching the convention several hosted-RPC providers already use, so existing WSS-shaped client code needs minimal changes to point here.
| What | Value | Notes |
|---|---|---|
| Endpoint | POST /rpc/v1/fullnode | Isolated from the public /rpc/v1/{network} pool — no shared failover state. |
| Method scope | Safe read methods + author_submitExtrinsic | Every other author_/sudo_/payment_/contracts_/state_call call is denied. |
| Key delivery | ?authorization= query parameter | Not an Authorization header. |
Limits
Hard caps on every proxied POST. Matching constants live in workers/config.mjs and workers/request-handlers/rpc-proxy.mjs.
| Limit | Value | Notes |
|---|---|---|
| Rate limit | 100 / 60s | Per-client IP on POST /rpc/v1/* (429 + retry-after). Shared binding policy with GraphQL. |
| State-query rate | 20 / 60s | Additional budget for state_getStorage / state_getKeysPaged — does not starve ordinary chain/system reads. |
| Max POST body | 64 KiB | HTTP request body size cap for the read-only proxy. |
| Max state-query response | 256 KiB | Decoded upstream body cap for state-query methods after fetch. |
state_getKeysPaged page | 250 | Caller-supplied count is clamped server-side (not rejected). |
| Failover attempts | 3 | Per request across the health-ordered pool before surfacing upstream failure. |
Subnet metagraph & validators
GET /api/v1/subnets/{netuid}/metagraph, /validators, /neurons/{uid}, and the global /api/v1/validators surface — trust, incentive, consensus, dividends, and nominators explained. No API key.
Search & AI
GET /api/v1/search, /search/semantic, and POST /api/v1/ask — keyword search, vector search, and grounded question-answering over the registry. 503s cleanly when AI isn't enabled. No API key.