Rosetta API
The Rosetta API is a standardized blockchain integration specification developed by Coinbase (the open specification is sometimes referred to as the Mesh API in Coinbase’s developer platform, but remains called “Rosetta” in the broader ecosystem). ICP provides two Rosetta implementations: one for the ICP ledger (with NNS governance support), and one for ICRC-1 compatible tokens such as ckBTC and ckETH.
This guide covers both implementations, focusing on what exchange operators and block explorer developers need to get started: running a node, querying chain data, and constructing transactions.
What is Rosetta?
Section titled “What is Rosetta?”Rosetta defines a uniform HTTP API for blockchain integrations. Clients (exchanges, custody platforms, analytics tools) interact with a Rosetta node rather than directly with chain-specific APIs. This lowers integration cost for operators already supporting other chains.
ICP Rosetta exposes the standard Rosetta endpoints:
- Data API: query balances, blocks, and transactions
- Construction API: create and sign transactions offline, then submit them
- Network API: network status and configuration
Both ICP Rosetta and ICRC Rosetta implement the full Rosetta specification and pass all rosetta-cli tests.
Choosing an implementation
Section titled “Choosing an implementation”| ICP Rosetta | ICRC Rosetta | |
|---|---|---|
| Ledger | ICP ledger (ryjl3-tyaaa-aaaaa-aaaba-cai) | Any ICRC-1 ledger (ckBTC, ckETH, SNS tokens, …) |
| Default port | 8081 | 8082 |
| Docker image | dfinity/rosetta-api | dfinity/ic-icrc-rosetta-api |
| Extra operations | Neuron staking, voting, NNS governance queries | Multi-token support |
| Network identifier | 00000000000000020101 | Canister ID of the target ledger |
If you need to work with ICP and governance neurons, use ICP Rosetta. For ckBTC, ckETH, or any other ICRC-1 token, use ICRC Rosetta.
Running ICP Rosetta
Section titled “Running ICP Rosetta”Docker (recommended)
Section titled “Docker (recommended)”Pull the official image:
docker pull dfinity/rosetta-apiTest environment: uses TESTICP tokens with no real value. Ideal for learning and development.
docker run \ --publish 8081:8081 \ --rm \ dfinity/rosetta-api \ --environment testGet free TESTICP tokens from the faucet. The test ICP ledger canister ID is xafvr-biaaa-aaaai-aql5q-cai.
Production with data persistence: mount /data so the node does not re-sync from scratch on restart:
docker volume create rosetta
docker run \ --volume rosetta:/data \ --publish 8081:8081 \ --detach \ dfinity/rosetta-api:v2.1.7 \ --environment productionUse a specific version tag in production. Check available versions on DockerHub.
Custom canister: connect to a specific test ledger:
docker run \ --publish 8081:8081 \ --rm \ dfinity/rosetta-api \ --environment test \ --canister <ledger-canister-id>Building from source
Section titled “Building from source”Requires Bazel and the IC repository:
git clone https://github.com/dfinity/ic.gitcd ic
bazel run //rs/rosetta-api/icp:ic-rosetta-api -- \ --port 8081 \ --environment production \ --store-location /tmpManaged endpoints
Section titled “Managed endpoints”Validation Cloud offers hosted ICP Rosetta endpoints without local infrastructure setup, including free and paid tiers with SLA guarantees.
Verify the node is running
Section titled “Verify the node is running”Check node status:
curl -H "Content-Type: application/json" \ -d '{"network_identifier": {"blockchain": "Internet Computer", "network": "00000000000000020101"}}' \ -X POST http://localhost:8081/network/statusWait for the log entry You are all caught up to block XX before treating the node as ready.
Check the node version:
curl -H "Content-Type: application/json" \ -d '{"network_identifier": {"blockchain": "Internet Computer", "network": "00000000000000020101"}}' \ -X POST http://localhost:8081/network/options | jq '.version.node_version'Running ICRC Rosetta
Section titled “Running ICRC Rosetta”Docker (recommended)
Section titled “Docker (recommended)”Pull the official image:
docker pull dfinity/ic-icrc-rosetta-apiQuickstart: connects to the TICRC1 test token (3jkp5-oyaaa-aaaaj-azwqa-cai):
docker run \ --publish 8082:8082 \ --rm \ dfinity/ic-icrc-rosetta-api \ --port 8082 \ --multi-tokens 3jkp5-oyaaa-aaaaj-azwqa-cai \ --store-type in-memoryGet free TICRC1 test tokens from the faucet.
Single-token production: connects to ckBTC with data persistence:
docker volume create ic-icrc-rosetta
docker run \ --volume ic-icrc-rosetta:/data \ --publish 8082:8082 \ --detach \ dfinity/ic-icrc-rosetta-api:v1.2.7 \ --port 8082 \ --network-type mainnet \ --multi-tokens mxzaz-hqaaa-aaaar-qaada-cai \ --multi-tokens-store-dir /dataMulti-token deployment: track ckBTC and ckETH simultaneously:
docker run \ --volume ic-icrc-rosetta:/data \ --publish 8082:8082 \ --detach \ dfinity/ic-icrc-rosetta-api:v1.2.7 \ --port 8082 \ --network-type mainnet \ --multi-tokens mxzaz-hqaaa-aaaar-qaada-cai,ss2fx-dyaaa-aaaar-qacoq-cai \ --multi-tokens-store-dir /dataEach tracked token maintains a separate SQLite database named after its canister ID (e.g., mxzaz-hqaaa-aaaar-qaada-cai.db). Logs include a sync{token=...} prefix per token:
INFO sync{token=ckBTC-mxzaz}: Fully synched to block height: 2365800INFO sync{token=ckETH-ss2fx}: Fully synched to block height: 801941Common ICRC-1 canister IDs
Section titled “Common ICRC-1 canister IDs”Mainnet:
| Token | Canister ID |
|---|---|
| ckBTC | mxzaz-hqaaa-aaaar-qaada-cai |
| ckETH | ss2fx-dyaaa-aaaar-qacoq-cai |
Test tokens:
| Token | Canister ID |
|---|---|
| TICRC1 | 3jkp5-oyaaa-aaaaj-azwqa-cai |
| ckTestBTC | mc6ru-gyaaa-aaaar-qaaaq-cai |
| ckTestETH | apia6-jaaaa-aaaar-qabma-cai |
Building from source
Section titled “Building from source”git clone https://github.com/dfinity/ic.gitcd ic
bazel run //rs/rosetta-api/icrc1:ic-icrc-rosetta-bin -- \ --port 8082 \ --multi-tokens 3jkp5-oyaaa-aaaaj-azwqa-cai \ --store-type in-memoryVerify the ICRC Rosetta node
Section titled “Verify the ICRC Rosetta node”curl -H "Content-Type: application/json" \ -d '{ "network_identifier": { "blockchain": "Internet Computer", "network": "mxzaz-hqaaa-aaaar-qaada-cai" } }' \ -X POST http://localhost:8082/network/statusData API
Section titled “Data API”The Data API provides read-only access to chain data. This section covers: network information, account balances (including neuron balances), block fetching, transaction search, and ICP-specific NNS governance queries. All examples below use ICP Rosetta (port 8081, network 00000000000000020101). For ICRC Rosetta, change the port to 8082 and use the ledger’s canister ID as the network identifier.
Fetch network information
Section titled “Fetch network information”Retrieve the network identifier: use this as a health check and to confirm the correct network_identifier for subsequent calls:
curl --location 'localhost:8081/network/list' \ --header 'Content-Type: application/json' \ --data '{"metadata": {}}'Response:
{ "network_identifiers": [ { "blockchain": "Internet Computer", "network": "00000000000000020101" } ]}Query account balance
Section titled “Query account balance”Fetch the balance of an account at the most recent block:
curl --location 'localhost:8081/account/balance' \ --header 'Content-Type: application/json' \ --data '{ "network_identifier": { "blockchain": "Internet Computer", "network": "00000000000000020101" }, "account_identifier": { "address": "8b84c3a3529d02a9decb5b1a27e7c8d886e17e07ea0a538269697ef09c2a27b4" }}'Response:
{ "block_identifier": { "index": 9890652, "hash": "30217e980397e9a8e14793563511e2d3191aa2df6d623866fa71f967e2ce3f08" }, "balances": [ { "value": "62841206500025", "currency": { "symbol": "ICP", "decimals": 8 } } ]}To query a staked neuron’s balance, include the account_type and neuron_index in the metadata:
curl --location 'localhost:8081/account/balance' \ --header 'Content-Type: application/json' \ --data '{ "network_identifier": { "blockchain": "Internet Computer", "network": "00000000000000020101" }, "account_identifier": { "address": "a4ac33c6a25a102756e3aac64fe9d3267dbef25392d031cfb3d2185dba93b4c4" }, "metadata": { "account_type": "neuron", "neuron_index": 0, "public_key": { "hex_bytes": "ba5242d02642aede88a5f9fe82482a9fd0b6dc25f38c729253116c6865384a9d", "curve_type": "edwards25519" } }}'Fetch a block
Section titled “Fetch a block”Provide either the block index, hash, or both. You can look up a block index in the ICP dashboard:
curl --location 'localhost:8081/block' \ --header 'Content-Type: application/json' \ --data '{ "network_identifier": { "blockchain": "Internet Computer", "network": "00000000000000020101" }, "block_identifier": { "index": 9840566 }}'Each ICP ledger block contains exactly one transaction. The response includes the operation type, amounts, and ICP-specific metadata such as memo and created_at_time.
Search transactions
Section titled “Search transactions”Query transactions by account, hash, or operation type:
curl --location 'localhost:8081/search/transactions' \ --header 'Content-Type: application/json' \ --data '{ "network_identifier": { "blockchain": "Internet Computer", "network": "00000000000000020101" }, "account_identifier": { "address": "8b84c3a3529d02a9decb5b1a27e7c8d886e17e07ea0a538269697ef09c2a27b4" }}'The search covers a maximum range of 10,000 blocks. See the full specification for all query parameters.
ICP-specific: NNS governance queries
Section titled “ICP-specific: NNS governance queries”ICP Rosetta exposes NNS governance data through the /call endpoint.
List pending proposals:
curl --location 'localhost:8081/call' \ --header 'Content-Type: application/json' \ --data '{ "network_identifier": { "blockchain": "Internet Computer", "network": "00000000000000020101" }, "method_name": "get_pending_proposals", "parameters": {}}'Get proposal info:
curl --location 'localhost:8081/call' \ --header 'Content-Type: application/json' \ --data '{ "network_identifier": { "blockchain": "Internet Computer", "network": "00000000000000020101" }, "method_name": "get_proposal_info", "parameters": { "proposal_id": 127049 }}'List known neurons:
curl --location 'localhost:8081/call' \ --header 'Content-Type: application/json' \ --data '{ "network_identifier": { "blockchain": "Internet Computer", "network": "00000000000000020101" }, "method_name": "list_known_neurons", "parameters": {}}'These calls require an online Rosetta node with internet access, since they proxy directly to the NNS governance canister (rrkah-fqaaa-aaaaa-aaaaq-cai).
Construction API
Section titled “Construction API”The Construction API enables offline transaction signing: you prepare and sign transactions on an air-gapped machine, then submit the signed payload when online. No private keys are ever sent to the Rosetta node.
The construction flow consists of these endpoints, called in order:
construction/derive: derive an account identifier from a public keyconstruction/preprocess: get parameters needed for metadata fetchconstruction/metadata: fetch transaction-specific metadata (e.g., nonce, fee)construction/payloads: get signable hex payloads for the requested operationsconstruction/combine: combine signatures with the unsigned transactionconstruction/submit: broadcast the signed transaction
Two additional optional endpoints are supported and used by some integrators:
construction/parse: parse a signed or unsigned transaction back into operations, useful for verifying intent before broadcastconstruction/hash: compute the transaction hash from a signed transaction, useful for tracking before submission
Key generation
Section titled “Key generation”ICP Rosetta supports Ed25519 and secp256k1 key types. Generate keys with OpenSSL:
# Ed25519 private key (32-byte public key)openssl genpkey -algorithm ed25519 -out my_ed25519_key.pem
# Extract compressed public key hexopenssl pkey -in my_ed25519_key.pem -pubout -outform DER | tail -c 32 | xxd -p -c 32# secp256k1 private key (33-byte compressed public key)openssl ecparam -name secp256k1 -genkey -noout -out my_secp256k1_key.pem
# Extract compressed public key hex (starts with 02 or 03)openssl ec -in my_secp256k1_key.pem -pubout -conv_form compressed -outform DER | tail -c 33 | xxd -p -c 33ICP operations
Section titled “ICP operations”ICP Rosetta supports these operation types. The full list is returned by the network/options endpoint at runtime:
Token operations:
TRANSACTION: token transferMINT: mint new tokens (minting account only)BURN: burn tokensAPPROVE: approve a spender (ICRC-2)FEE: explicit fee debit (used internally and in transaction representation)
Neuron and governance operations:
STAKE: stake ICP to create a neuronSTART_DISSOLVING/STOP_DISSOLVING: change neuron dissolve stateSET_DISSOLVE_TIMESTAMP: set a neuron’s dissolve deadlineCHANGE_AUTO_STAKE_MATURITY: toggle automatic maturity restakingDISBURSE: disburse matured neuron fundsADD_HOTKEY/REMOVE_HOTKEY: manage neuron hotkeysSPAWN: spawn a new neuron from maturityMERGE_MATURITY/STAKE_MATURITY: handle accumulated maturityREGISTER_VOTE: vote on NNS proposalsFOLLOW: configure neuron followingNEURON_INFO: retrieve neuron metadataLIST_NEURONS: list neurons controlled by a principal
For a complete reference of the construction flow with request/response examples for each operation type, see the ICP Rosetta construction API in the IC repository.
ICRC Rosetta operations
Section titled “ICRC Rosetta operations”ICRC Rosetta supports two categories of construction operations:
TRANSFER: direct token transfer between accounts (ICRC-1). Two operations per request: one debit (TRANSFERwith negative amount) and one credit (TRANSFERwith positive amount).APPROVE+SPENDER: authorize a spender to transfer tokens on your behalf (ICRC-2). TheAPPROVEoperation sets the allowance amount; theSPENDERoperation identifies the authorized principal.
The construction flow is the same as for ICP. The network identifier is the ledger canister ID and the port is 8082. You do not need to include a FEE operation: ICRC Rosetta deducts the fee automatically, though you may include it to make the debit explicit.
Requirements and limitations
Section titled “Requirements and limitations”Transaction timing
Section titled “Transaction timing”For both ICP and ICRC Rosetta, an unsigned transaction must be created and signed within 24 hours before the node receives the signed payload. This is enforced by the ICRC-1 deduplication mechanism. Transactions referencing a created_at_time older than 24 hours are rejected.
Signature schemes
Section titled “Signature schemes”ICP and ICRC Rosetta support:
- Ed25519 (
edwards25519curve type) - secp256k1 (
secp256k1curve type)
Compliance
Section titled “Compliance”Both implementations:
- Fully comply with all standard Rosetta endpoints
- Pass all
rosetta-clitests - Accept any valid Rosetta request
Neither implementation supports UTXO features. No UTXO messages appear in responses.
Example scripts
Section titled “Example scripts”The DFINITY IC repository contains Python example scripts for both implementations:
- ICP Rosetta examples:
rs/rosetta-api/examples/icp/python: balance queries, transfers, block reading, NNS governance interactions - ICRC Rosetta examples:
rs/rosetta-api/examples/icrc1/python: ICRC-1 token operations with aRosettaClientlibrary supporting automatic token discovery
Each directory includes a requirements.txt and a run_tests.sh script for isolated test environments.
Next steps
Section titled “Next steps”- Ledgers: transfer and manage assets directly from canister code
- Digital Asset Standards: formal ICRC standard specifications for fungible assets, NFTs, and their extensions