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).
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.
{
"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.
POST /contract_call: submit a signed, anchored contract call. Body limit: 64 KB.
{
"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}/{field}/{arg}: read a contract field (e.g. a map entry).
GET /v2/state_root: the latest per-block state root.
GET /v2/state_root/{height}: the state root at a specific Bitcoin block height.
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:
| RPC | Purpose |
|---|---|
Heartbeat |
Register peer activity |
SubmitPayload |
Push contract payloads to a peer |
PreparePayload |
Consensus prepare for validation |
GetContractIds |
All known contract IDs |
GetContractSummary |
State summary (Merkle root, payload hashes) |
GetContractTxids |
TXIDs for a contract |
GetContractMerkleRoot |
Merkle root over a contract's TXIDs |
GetPayloadByTxid |
Fetch a payload by TXID |
Peers exchange Merkle summaries first and only transfer payloads that differ, so sync cost scales with divergence, not history size.