Node API reference

The node serves two interfaces: a REST API for clients and frontends (default port 8080), and a gRPC service for node-to-node sync and gossip (default port 50051).

Updated 08 Nov 20262 min read
warning:

This surface reflects the current implementation. Treat it as current, not a frozen public API.

#REST API

#Contracts and calls

POST /deploy_contract: register a compiled contract, referencing its anchoring Bitcoin transaction.

json
{
  "txid": "<bitcoin-txid-with-your-commitment>",
  "bytecode": "<hex bytecode>",
  "abi": [ ... ],
  "function_offsets": { "init": 0, "transfer": 42 },
  "function_offset_to_locals": { "0": 2, "42": 4 },
  "constants": [ ... ],
  "metadata": { }
}

All fields after txid come from sclc compile --json. metadata is optional; omitted means full defaults. A deployed contract is immutable: the node refuses a second registration under the same contract ID.

POST /deploy_contract/preflight: validate an artifact and return the deploy commitment it produces, without registering anything. Compare it byte for byte with the commitment you are about to anchor.

POST /contract_call: submit a signed, anchored contract call. Body limit: 64 KB.

json
{
  "txid": "<bitcoin-txid-of-the-anchoring-tx>",
  "contract_id": "<contract-id>",
  "payload": "<base64 Borsh-encoded CallEnvelope>"
}

GET /contract_call/{txid}/status: execution status of a submitted call.

GET /contracts: list all known contract IDs.

#State

GET /v2/{contract_id}/{ignored}/{field}: read one field of a stored contract row. The middle segment is not used.

GET /contract_owners/{contract_id}: the outpoints that currently hold a UTXO-bound token's balances. Add ?include_pending=true to include calls not yet confirmed.

GET /fuel/{contract_id}: the contract's fuel standing: tier, stake and consumption.

GET /v2/state_root: the latest per-block state root.

GET /v2/state_root/{height}: the state root at a specific Bitcoin block height.

#Lightning channels

POST /register_channel: bind an SCL asset to a Lightning channel's funding outpoint.

GET /channels: every registered channel.

GET /channel/{txid}/{vout}: one registered channel, or null when none is registered at that outpoint.

#Events

GET /events/{contract_id}: events emitted by a contract. Optional query parameters: event_name, from_block, to_block.

Each event includes its name, decoded parameters, the emitting call's Bitcoin txid, and the confirmation block height.

#Node

GET /health: liveness check, returns 200 OK.

GET /node_status: node state summary.

#Private (require Authorization: Bearer <api_token>)

GET /calls/{contract_id}: paginated confirmed-call log. Query parameters: limit, offset.

POST /admin/clear_halt: clear a consensus halt (operator only).

#gRPC service

Defined in proto/scl.proto; used for peer sync and gossip:

RPCPurpose
HeartbeatRegister peer activity
SubmitPayloadPush contract payloads to a peer
PreparePayloadConsensus prepare for validation
GetContractIdsAll known contract IDs
GetContractSummaryState summary (Merkle root, payload hashes)
GetContractTxidsTXIDs for a contract
GetContractMerkleRootMerkle root over a contract's TXIDs
GetPayloadByTxidFetch a payload by TXID

Peers exchange Merkle summaries first and only transfer payloads that differ, so sync cost scales with divergence, not history size.

Was this page helpful?