REST API
Two HTTP services expose the chain:
| Service | Default | Use |
|---|---|---|
| Gateway (Node.js) | http://localhost:3000 | What dApps and the web app call. Proxies the node, adds WebSocket, AI tooling and caching |
| Node RPC (Rust) | http://localhost:9933 | The source of truth. Some operator endpoints exist only here |
Most paths are the same on both. The tables below mark endpoints that exist on only one of them. Examples use $GATEWAY and $NODE_RPC — see Start here.
Conventions
Amounts
- On-chain amounts are integers in uNRO (
1 NRO = 1 000 000 uNRO). - Responses add a formatted
*_humanstring next to each amount (balance_human,value_human,stake_human, …). Display those; do not convert in the client. - In request bodies, send amounts as JSON numbers in uNRO unless the endpoint says otherwise.
Signed operations
Every endpoint that changes state needs a signature. Two kinds:
| Kind | Signed message | nonce |
|---|---|---|
Transaction (POST /api/v1/transactions) | `nc-tx-v2 | from |
| Operation (everything else) | `nc-tx-v2 | actor |
The target is a reserved system address naming the operation; the tables give it in the Signs for column. Each request carries signature (hex), public_key (hex ML-DSA-65) and nonce. See Wallet → Signed operations.
With CHAIN_ENV=mainnet (the default), a missing or invalid signature is refused with 401. With CHAIN_ENV=testnet the node logs a warning instead — for local development only.
Most operations are applied in consensus: the response says "status": "pending" and returns a tx_hash; the effect is visible once that transaction is in a block.
Errors
Errors are JSON: {"error": "<message>"}, sometimes with hint or extra fields. HTTP codes used:
| Code | Meaning |
|---|---|
| 200 | Success — but some older endpoints also return {"error": …} with 200; always check for error |
| 400 | Bad request, failed validation, Sentinel rejection |
| 401 | Missing or invalid signature, key not bound to the address |
| 403 | Forbidden in this mode (faucet on mainnet, write call without consensus on mainnet), deploy refused by VMGuardian |
| 404 | Not found |
| 409 | Name already taken |
| 429 | Rate limited |
| 502 / 503 | Gateway cannot reach the node |
Pagination
List endpoints take limit and offset (some also page). Each endpoint caps limit (typically 100 or 200).
Rate limits and CORS
| Where | Default | Variable |
|---|---|---|
| Node RPC, per IP | 100 requests/s | NEUROCHAIN_RPC_RATE_LIMIT |
| Gateway, per IP | 200 requests/s | GLOBAL_RL_MAX_RPS |
Gateway AI endpoints (/contracts/audit, /contracts/generate, …), per IP | 10 requests/min | AI_RL_MAX_RPM |
Allowed origins: CORS_ALLOWED_ORIGINS on both services (default *).
Network and node
| Method | Path | Notes |
|---|---|---|
| GET | /health | status, height, round, mempool, peers, tps, total_txs, validator_count, bft_quorum, bft_ready |
| GET | /status, /api/v1/status | Node only. Height, validators, shards, network name |
| GET | /api/v1/network/status | Gateway only. Network summary for the explorer |
| GET | /metrics | Prometheus text format — see Run a node |
| GET | /api/v1/shards | Per-shard heights and roots |
| GET | /api/v1/state/root | global_root, shard_roots, height, root_height, n_shards |
| GET | /api/v1/state/snapshot | Node only. Full signed state snapshot for bootstrapping a node |
| GET | /api/v1/checkpoints | Signed checkpoints. offset, limit |
| GET | /peers | Node only. Connected peers |
| GET | /api/v1/gas/estimate | base_fee, gas per operation, total_burned, nft_transfer_fee — see Gas & fees |
| GET | /api/v1/wasm/version | Gateway only. Version manifest of the browser WASM module |
Blocks
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/blocks | limit (≤ 100, default 20), offset, page. Newest first |
| GET | /api/v1/blocks/latest | Gateway only. { "block": … } |
| GET | /api/v1/blocks/:height | One block: height, hash, parent_hash, proposer, tx_root, state_root, tx_count, gas_used, base_fee, fees_burned, shard, round, timestamp |
| GET | /api/v1/blocks/:height/transactions | Transactions in the block |
Transactions
| Method | Path | Signs for | Notes |
|---|---|---|---|
| POST | /api/v1/transactions | the transaction itself | Body below |
| GET | /api/v1/transactions | — | address, hash, type (staking to list staking operations), limit (≤ 200), offset, page |
| GET | /api/v1/transactions/:hash | — | One transaction with status, gas, fee, fee_human, value_human |
| GET | /api/v1/tx/:hash/proof | — | Merkle inclusion proof: leaf_index, proof, tx_root, block_height |
| POST | /api/v1/transactions/:hash/confirm | neuro:system.trust | Confirm a held transfer (owner's main key only) — see Sentinel |
| POST | /api/v1/transactions/:hash/cancel | neuro:system.trust | Cancel a held transfer |
| GET | /api/v1/held/:address | — | Held transfers of an address |
| GET | /api/v1/cross-shard/queue | — | Cross-shard relays. status, limit, offset |
POST /api/v1/transactions body
| Field | Type | Required | Meaning |
|---|---|---|---|
from | string | yes | Sender address |
to | string | yes | Recipient, contract, or neuro:system.deploy |
value | number | yes | uNRO |
nonce | number | yes | Next account nonce |
signature | string | yes | ML-DSA-65 over `nc-tx-v2 |
public_key | string | yes | ML-DSA-65 public key, hex |
gas_price | number | no | uNRO per gas unit; must be ≥ the base fee |
data | string | no | Contract call or deploy as a JSON string (hex also accepted) — see ABI, Deploy |
Response: tx_hash, status: "pending", estimated_block; plus sentinel_score and sentinel_warning when Sentinel flags it, or held details when the policy layer holds it.
Accounts
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/accounts/:address | balance, balance_human, nonce, … |
| GET | /api/v1/accounts/:address/transactions | History. limit, offset |
| GET | /api/v1/accounts/:address/token-transfers | Token (NRC-20) transfers involving the address |
| GET | /api/v1/accounts/:address/totals | Node only. Totals sent and received |
| POST | /api/v1/faucet | Test networks only (CHAIN_ENV=testnet). Body: address, public_key, amount (uNRO, optional) |
| POST | /api/v1/wallet/derive-address | Body: words. Derives the .human address from a phrase — sends the phrase to the server. Off on mainnet; on test networks only with NEUROCHAIN_ALLOW_SERVER_DERIVE=true |
Names and NFTs
| Method | Path | Signs for | Body / notes |
|---|---|---|---|
| POST | /api/v1/addresses/human | neuro:system.name | Node only. name, owner, + signed fields. Registers a custom .human name |
| GET | /api/v1/addresses/human/price | — | Node only. ?name= → price by length |
| POST | /api/v1/nodes/register | neuro:system.node | name, owner, optional node_address (to register .app / .vault), + signed fields |
| GET | /api/v1/nodes | — | Registered nodes |
| GET | /api/v1/nodes/:address | — | One node record |
| PUT/POST | /api/v1/nodes/:address/profile | neuro:system.node | description, website, commission_bps, p2p_endpoint, rpc_endpoint |
| POST | /api/v1/nodes/:address/unjail | neuro:system.node | Re-enter the set after the jail period (owner signs) |
| POST | /api/v1/nft/transfer | the NFT address | nft_address, from (current owner), to, + signed fields. Fee 100 uNRO |
| GET | /api/v1/nft/:address | — | NFT record and transfer history |
| GET | /api/v1/nft/owner/:address | — | NFTs owned by an address |
| POST | /api/v1/agents/register | neuro:system.agent | name, owner, + signed fields. Registers a .agent |
| GET | /api/v1/agents/:address | — | Agent record |
Staking
| Method | Path | Signs for | Body / notes |
|---|---|---|---|
| POST | /api/v1/staking/stake | neuro:system.stake | address, amount, + signed fields |
| POST | /api/v1/staking/unstake | neuro:system.stake | address, + signed fields |
| POST | /api/v1/staking/delegate | the validator address | delegator, validator, amount, + signed fields |
| POST | /api/v1/staking/undelegate | the validator address | delegator, validator, + signed fields |
| GET | /api/v1/staking/info/:address | — | Stake, lock, rewards of an address |
| GET | /api/v1/staking/validators | — | Validators with stake and delegations |
| GET | /api/v1/staking/delegations/:validator | — | Delegations to a validator |
| GET | /api/v1/staking/my-delegations/:address | — | Delegations made by an address |
| GET | /api/v1/staking/rewards/:address | — | Reward history; `source=stake |
| GET | /api/v1/validators | — | Consensus validators with stake, trust_score, blocks_proposed, votes_cast, last_active |
| GET | /api/v1/slashing/history | — | Node only. Slashes. limit |
See Staking & delegation.
Governance
| Method | Path | Signs for | Body / notes |
|---|---|---|---|
| POST | /api/v1/governance/propose | neuro:system.governance | proposer, title, description, kind (text / PARAM_CHANGE), payload, voting_duration, + signed fields |
| POST | /api/v1/governance/:id/vote | neuro:system.governance | voter, accept (bool), + signed fields |
| GET | /api/v1/governance/proposals | — | status, limit (≤ 100), offset |
| GET | /api/v1/governance/:id | — | One proposal with votes |
| GET | /api/v1/governance/params | — | Every parameter with value and description |
See Governance.
Vaults (multi-signature)
| Method | Path | Signs for | Body / notes |
|---|---|---|---|
| GET | /api/v1/vault/:addr/config | — | threshold, members |
| GET | /api/v1/vault/:addr/proposals | — | Payout proposals |
| GET | /api/v1/vault/member/:addr | — | Vaults an address belongs to |
| POST | /api/v1/vault/:addr/proposals | the vault address | proposer, to, amount, description, + signed fields |
| POST | /api/v1/vault/:addr/proposals/:id/sign | the vault address | signer, + signed fields. Pays out when signatures reach the threshold |
| POST | /api/v1/vault/:addr/members | the vault address | member, requester, + signed fields |
| POST | /api/v1/vault/:addr/threshold | the vault address | threshold, requester, + signed fields |
Experimental
Vault operations are currently applied by the node that receives the request, not in consensus. Use a single node for a vault until this moves into consensus.
Contracts
| Method | Path | Signs for | Body / notes |
|---|---|---|---|
| GET | /api/v1/contracts | — | owner, limit, offset |
| GET | /api/v1/contracts/:address | — | Metadata, security_score, owner, code hash |
| GET | /api/v1/contracts/:address/token-info | — | Gateway only. NRC-20 name, symbol, decimals, supply |
| POST | /api/v1/contracts/:address/call | — | function, args, dry_run, gas_limit, caller. Read with dry_run: true; writes refused on mainnet |
| POST | /api/v1/contracts/deploy | neuro:system.deploy | Node only. owner, bytecode_hex or base64_wasm, name, description, template, + signed fields |
| POST | /api/v1/contracts/analyze | — | Node only. bytecode_hex → risk_score, security_score, ml_score, model, violations |
| POST | /api/v1/contracts/attest | — | bytecode_hex → analysis signed with ML-DSA-65: score, bytecode_hash, timestamp, signature, pubkey |
| POST | /api/v1/contracts/audit | — | Gateway only. bytecode_hex → node analysis (source code is not accepted) |
| POST | /api/v1/contracts/reaudit | — | Gateway only. address → re-run analysis of a deployed contract |
| POST | /api/v1/contracts/generate | — | Gateway only. Contract template generation (SmartForge) |
| POST | /api/v1/contracts/certify | neuro:system.cert | Issue a security certificate (VMGuardian operator) |
| POST | /api/v1/contracts/whitelist | neuro:system.whitelist | Node only. bytecode_hash — trusted template bytecode |
| PATCH | /api/v1/contracts/:address/score | neuro:system.score | Node only. security_score |
| GET | /api/v1/certificates | — | owner, limit, offset |
| GET | /api/v1/certificates/:id | — | One certificate |
| GET | /api/v1/certificates/contract/:address | — | Certificate of a contract |
| GET | /api/v1/templates | — | Registered contract templates |
| GET | /api/v1/templates/:id | — | One template with ABI |
| POST | /api/v1/templates/register | neuro:system.templates | author (a .node), name, description, category, bytecode_hex, abi_json, fee_unro, + signed fields |
| POST | /api/v1/templates/deprecate | neuro:system.templates | Node only. template_id, author, delete, + signed fields |
AI and models
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/ai/status | Gateway only. Status of the AI models |
| POST | /api/v1/sentinel/score | Score a transaction shape: value, gas_price, nonce, last_nonce, balance, tx_count_last_10, recipient_tx_count, is_self_transfer → score, anomalous, category |
| GET | /api/v1/oracle/log | AI decision log. model, kind, subject, limit, offset |
| GET | /api/v1/oracle/log/:id | One decision |
| GET | /api/v1/models/registry | On-chain model registry. limit, offset |
| GET | /api/v1/models/registry/:id | One model version |
| POST | /api/v1/models/register | Validators only; signs for neuro:models.registry. from, name, version, weights_hash, architecture, params_count, accuracy, + signed fields |
| GET | /api/v1/ai/export/{blocks,txs,validators,oracle} | Training-data export (JSON Lines) |
| POST | /api/v1/assistant/ask, GET /api/v1/assistant/health | Gateway only. Documentation assistant (off unless ASSISTANT_ENABLED=1) |
Sentinel trust list
| Method | Path | Signs for | Body |
|---|---|---|---|
| POST | /api/v1/trust/add | neuro:system.trust | owner, recipient, + signed fields |
| POST | /api/v1/trust/remove | neuro:system.trust | owner, recipient, + signed fields |
| GET | /api/v1/trust/:owner | — | Trusted recipients, with activation height |
Account abstraction
| Method | Path | Signs for | Body |
|---|---|---|---|
| POST | /api/v1/session/grant | neuro:system.session | account, session_pk, scope, cap, expiry_block, + signed fields |
| POST | /api/v1/session/revoke | neuro:system.session | account, session_pk, + signed fields |
| GET | /api/v1/session/list/:account | — | Session keys of an account |
| POST | /api/v1/sponsor/deposit | neuro:system.sponsor | address, amount, + signed fields |
| POST | /api/v1/sponsor/withdraw | neuro:system.sponsor | address, amount, + signed fields |
| GET | /api/v1/sponsor/:address | — | Sponsor pool balance |
See Account abstraction.
Identity and recovery
These sign their own messages (for example nc-rotate|addr|add|remove|nonce) rather than nc-tx-v2; see Identity.
| Method | Path | Body |
|---|---|---|
| POST | /api/v1/identity/rotate | owner, add, remove, + signed fields |
| POST | /api/v1/identity/recovery/setup | owner, guardians, threshold, timelock, + signed fields |
| POST | /api/v1/identity/recovery/request | target, new_key, + signed fields |
| POST | /api/v1/identity/recovery/approve | target, guardian, + signed fields |
| POST | /api/v1/identity/recovery/reject | target, guardian, + signed fields |
| POST | /api/v1/identity/recovery/withdraw | target, + signed fields |
| POST | /api/v1/identity/recovery/cancel | owner, + signed fields |
| GET | /api/v1/identity/:addr | Keys and version |
| GET | /api/v1/identity/recovery/:addr | Recovery configuration and any open request |
| GET | /api/v1/identity/guardian-of/:addr | Identities this address guards |
Native assets and exchange
| Method | Path | Body / notes |
|---|---|---|
| GET | /api/v1/assets | Issued assets |
| GET | /api/v1/assets/:id | One asset |
| GET | /api/v1/assets/check-symbol | ?symbol= — is the ticker free and valid |
| GET | /api/v1/assets/balances/:addr | Asset balances |
| POST | /api/v1/assets/issue | from, name, symbol, decimals, initial, max_supply, reissuable, reissue_unlock_height, issue_nonce, + signed fields. Fee asset_issue_fee |
| POST | /api/v1/assets/transfer | from, to, asset_id, amount, + signed fields |
| GET | /api/v1/dex/pools, /api/v1/dex/pools/:id | Pools |
| POST | /api/v1/dex/pools | from, asset_x, asset_y, amount_x, amount_y, + signed fields |
| POST | /api/v1/dex/liquidity/add | from, pool_id, max_a, max_b, + signed fields |
| POST | /api/v1/dex/liquidity/remove | from, pool_id, shares, + signed fields |
| GET | /api/v1/dex/quote | Swap quote |
| POST | /api/v1/dex/swap | from, pool_id, asset_in, amount_in, min_out, deadline_height, + signed fields. Cleared in a batch when the next block commits |
| GET | /api/v1/dex/window | Current batch window |
| POST | /api/v1/dex/deposit, /api/v1/dex/withdraw | Move funds between the main balance and the exchange balance |
| GET | /api/v1/dex/balances/:addr, /dex/positions/:addr, /dex/activity/:addr, /dex/transactions | Exchange balances, LP positions, activity |
All asset and exchange operations sign for neuro:system.assets and are applied in consensus.
Test networks only for now
In consensus, these operations also require a second signature over the exact payload (_psig, message nc-asset-op-v1|op|from|fields|nonce) when the node runs with CHAIN_ENV=mainnet. The REST endpoints do not accept that signature yet, so on mainnet every asset and exchange operation is refused; on CHAIN_ENV=testnet they apply without the payload check.
IBC v2 experimental
| Method | Path | Body / notes |
|---|---|---|
| POST | /api/v1/ibc/channel/open | from, channel, port, counterparty_chain, allowed_denoms, + signed fields |
| POST | /api/v1/ibc/channel/pause | from, channel, paused, + signed fields |
| POST | /api/v1/ibc/transfer | from, channel, dest_chain, receiver, denom, amount, + signed fields |
| POST | /api/v1/ibc/recv | from, packet_id, receiver, denom, amount, + signed fields |
| POST | /api/v1/ibc/ack | from, id, + signed fields |
| POST | /api/v1/ibc/redeem | from, channel, dest_chain, receiver, denom, amount, + signed fields |
| POST | /api/v1/ibc/client/update, /api/v1/ibc/attest | Light-client update and attestation (relayer) |
| GET | /api/v1/ibc/channels, /ibc/packets, /ibc/denoms, /ibc/client/:chainId, /ibc/header/latest, /ibc/voucher/:addr, /ibc/pq/test-vector | State and test vectors |
All IBC v2 operations sign for neuro:system.ibc; recv, ack, channel and client operations are limited to IBC operator keys. See IBC v2 & sharding.