# 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).

> Part of the SQRL documentation, section "Protocol".
> Rendered page: https://docs.sqrl.tech/protocol/nodes/api-reference

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:

| 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.
