Channel node API
The owner's API of a payment channel node (docs/CHANNELD.md). Every /v1 route requires Authorization: Bearer <ARREKTA_CHANNELD_API_TOKEN>; /healthz and /metrics (Prometheus) do not. Amounts are decimal strings in base units. Errors are RFC 9457 problem documents. Keep this API private: it moves money.
Default base URL http://127.0.0.1:9737. SDKs: createChanneldClient (TypeScript), ChanneldClient (Python). Design: Channel node.
| Method | Path | Summary |
|---|---|---|
| GET | /v1/info | Node identity, network, tip and counts |
| GET | /v1/wallet | On-chain wallet addresses and balances |
| GET | /v1/peers | Connected peers |
| POST | /v1/peers | Connect to a channel node |
| GET | /v1/channels | All channels, newest first |
| POST | /v1/channels | Open a channel |
| GET | /v1/channels/{id} | One channel |
| POST | /v1/channels/{id}/close | Close a channel |
| POST | /v1/channels/{id}/splice | Splice a channel in or out |
| GET | /v1/invoices | Invoices we issued |
| POST | /v1/invoices | Create an invoice |
| POST | /v1/invoices/decode | Decode and verify a arrektapay: invoice |
| GET | /v1/invoices/{hash} | Invoice status |
| GET | /v1/payments | Payments we sent |
| POST | /v1/payments | Pay an invoice |
| GET | /v1/payments/{hash} | Payment status and attempts |
| POST | /v1/routes | Preview the route and fee for an invoice |
| GET | /v1/graph | Public channels and nodes |
| GET | /v1/tower | Watchtower server and client status |
| GET | /public/v1/graph | Public channel graph: totals, nodes, open channels, and the 20 most recent closed ones (closed, closed_count) (no token; ARREKTA_CHANNELD_PUBLIC_GRAPH=true) |
| GET | /public/v1/channels/{id} | One public channel (by its funding-output id): status open, or closed with its closing transaction and the later spends of its outputs |
| GET | /public/v1/nodes/{id} | One public node, its open channels (channel_list) and its closed ones (closed_list) |
Endpoints
GET /v1/info
Node identity, network, tip and counts.
curl -s -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/v1/infoResponse 200: NodeInfo
GET /v1/wallet
On-chain wallet addresses and balances. Fund the receive address to open channels and to pay close and sweep fees.
curl -s -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/v1/walletResponse 200: Wallet
GET /v1/peers
Connected peers.
curl -s -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/v1/peersResponse 200: object
POST /v1/peers
Connect to a channel node. Dials address over the post-quantum transport; node_id, when given, must match the peer's proven identity.
curl -s -X POST -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/v1/peers -H 'content-type: application/json' -d '{…}'Request body
| Field | Type | Required | Notes |
|---|---|---|---|
address | string | yes | host:port |
node_id | string | no |
Response 200: object
GET /v1/channels
All channels, newest first.
curl -s -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/v1/channelsResponse 200: object
POST /v1/channels
Open a channel. Funds the channel from the wallet and returns once the peer has signed our first commitment and the funding transaction is broadcast. The channel becomes active after min_depth confirmations.
curl -s -X POST -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/v1/channels -H 'content-type: application/json' -d '{…}'Request body
| Field | Type | Required | Notes |
|---|---|---|---|
node_id | string | yes | |
capacity | string | yes | base units as a decimal string |
asset | string | no | |
public | boolean | no | default true |
request_funding | string | no | dual funding: ask the peer to contribute this much (it may put in less, or nothing) |
Response 201: Channel
GET /v1/channels/{id}
One channel.
curl -s -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/v1/channels/<id>Response 200: Channel
POST /v1/channels/{id}/close
Close a channel. Cooperative by default: no new HTLCs, then a zero-fee close confirmed by CPFP once pending HTLCs settle. force broadcasts our latest commitment; our balance then waits to_self_delay blocks.
curl -s -X POST -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/v1/channels/<id>/close -H 'content-type: application/json' -d '{…}'Request body
| Field | Type | Required | Notes |
|---|---|---|---|
force | boolean | no | default false |
Response 200: Channel
POST /v1/channels/{id}/splice
Splice a channel in or out. Changes the capacity without closing: a positive amount adds coins from the node's wallet, a negative one pays out to address (default: the node's wallet). ARRK channels only. The channel must be quiet (no HTLCs); it pauses payments until the splice transaction is min_depth deep and both sides lock it.
curl -s -X POST -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/v1/channels/<id>/splice -H 'content-type: application/json' -d '{…}'Request body
| Field | Type | Required | Notes |
|---|---|---|---|
amount | string | yes | signed base units |
address | string | no |
Response 200: Channel
GET /v1/invoices
Invoices we issued.
curl -s -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/v1/invoicesResponse 200: object
POST /v1/invoices
Create an invoice. Route hints for our private channels are added automatically.
curl -s -X POST -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/v1/invoices -H 'content-type: application/json' -d '{…}'Request body
| Field | Type | Required | Notes |
|---|---|---|---|
amount | string | no | base units as a decimal string |
asset | string | no | |
description | string | no | |
expiry_secs | integer | no |
Response 201: Invoice
POST /v1/invoices/decode
Decode and verify a arrektapay: invoice.
curl -s -X POST -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/v1/invoices/decode -H 'content-type: application/json' -d '{…}'Request body
| Field | Type | Required | Notes |
|---|---|---|---|
invoice | string | yes |
Response 200: DecodedInvoice
GET /v1/invoices/{hash}
Invoice status.
curl -s -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/v1/invoices/<hash>Response 200: Invoice
GET /v1/payments
Payments we sent.
curl -s -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/v1/paymentsResponse 200: object
POST /v1/payments
Pay an invoice. Finds a route, sends, and retries around failures until it succeeds, fails for good, or timeout_secs passes. On timeout the payment may still complete: poll /v1/payments/{hash}. preimage is the proof of payment.
curl -s -X POST -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/v1/payments -H 'content-type: application/json' -d '{…}'Request body
| Field | Type | Required | Notes |
|---|---|---|---|
invoice | string | yes | |
amount | string | no | base units as a decimal string |
max_fee | string | no | base units as a decimal string |
timeout_secs | integer | no |
Response 200: Payment
GET /v1/payments/{hash}
Payment status and attempts.
curl -s -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/v1/payments/<hash>Response 200: Payment
POST /v1/routes
Preview the route and fee for an invoice.
curl -s -X POST -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/v1/routes -H 'content-type: application/json' -d '{…}'Request body
| Field | Type | Required | Notes |
|---|---|---|---|
invoice | string | yes | |
amount | string | no | base units as a decimal string |
max_fee | string | no | base units as a decimal string |
Response 200: Route
GET /v1/graph
Public channels and nodes.
curl -s -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/v1/graphResponse 200: object
GET /v1/tower
Watchtower server and client status.
curl -s -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/v1/towerResponse 200: object
GET /public/v1/graph
Public channel graph: totals, nodes, open channels, and the 20 most recent closed ones (closed, closed_count) (no token; ARREKTA_CHANNELD_PUBLIC_GRAPH=true). What gossip already announces, for explorers. CORS allows any origin.
curl -s -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/public/v1/graphResponse 200: object
GET /public/v1/channels/{id}
One public channel (by its funding-output id): status open, or closed with its closing transaction and the later spends of its outputs.
curl -s -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/public/v1/channels/<id>Response 200: object
GET /public/v1/nodes/{id}
One public node, its open channels (channel_list) and its closed ones (closed_list).
curl -s -H "authorization: Bearer $TOKEN" http://127.0.0.1:9737/public/v1/nodes/<id>Response 200: object
Schemas
Problem
RFC 9457 problem details.
| Field | Type | Required | Notes |
|---|---|---|---|
type | string | yes | |
title | string | yes | |
status | integer | yes | |
code | string | yes | stable machine-readable code |
detail | string | no |
NodeInfo
| Field | Type | Required | Notes |
|---|---|---|---|
node_id | string | yes | |
identity_key | string | no | ML-DSA public key, hex |
alias | string | no | |
network | string | yes | |
tip | integer | yes | |
p2p_port | integer | null | no | |
announce_address | string | null | no | |
features | integer | no | |
peers | integer | no | |
channels | object | no | |
graph | object | no | |
fee_per_kb | integer | no | |
version | string | no | |
uptime_seconds | integer | no |
Wallet
| Field | Type | Required | Notes |
|---|---|---|---|
address | string | no | |
change_address | string | no | |
balances | object[] | no | |
reserved | integer | no |
Peer
| Field | Type | Required | Notes |
|---|---|---|---|
node_id | string | yes | |
address | string | null | no | |
inbound | boolean | no | |
features | integer | no | |
connected_at | integer | no | |
alias | string | null | no |
Htlc
| Field | Type | Required | Notes |
|---|---|---|---|
id | integer | no | |
direction | string | no | one of in, out |
amount | string | no | base units as a decimal string |
payment_hash | string | no | |
expiry | integer | no | |
blocks_left | integer | no |
Channel
| Field | Type | Required | Notes |
|---|---|---|---|
channel_id | string | yes | |
peer | string | no | |
role | string | no | one of opener, acceptor |
status | string | yes | one of funding, active, shutting_down, closing, closed, data_loss |
asset | string | no | |
capacity | string | yes | base units as a decimal string |
local_balance | string | yes | base units as a decimal string |
remote_balance | string | no | base units as a decimal string |
spendable | string | no | base units as a decimal string |
reserve | string | no | base units as a decimal string |
commitment_number | integer | no | |
htlcs | Htlc[] | no | |
funding | string | no | txid:vout |
funding_height | integer | null | no | |
to_self_delay | integer | no | |
public | boolean | no | |
close | object | null | no | |
error | string | null | no | |
created | integer | no | |
funding_address | string | null | no | |
acceptor_funding | string | no | base units as a decimal string |
splice | object | null | no |
Invoice
| Field | Type | Required | Notes |
|---|---|---|---|
hash | string | yes | |
invoice | string | yes | arrektapay:… |
amount | string | null | no | |
asset | string | no | |
description | string | no | |
status | string | yes | one of open, settled, expired |
received | string | no | base units as a decimal string |
created | integer | no | |
expires_at | integer | no | |
settled_at | integer | null | no | |
min_final_expiry | integer | no | |
preimage | string | no | present only once settled |
DecodedInvoice
| Field | Type | Required | Notes |
|---|---|---|---|
payment_hash | string | no | |
asset | string | no | |
amount | string | null | no | |
description | string | no | |
created | integer | no | |
expires_at | integer | no | |
min_final_expiry | integer | no | |
payee | string | no | |
network_magic | string | no | |
route_hints | object[] | no |
Attempt
| Field | Type | Required | Notes |
|---|---|---|---|
route | object[] | no | |
status | string | no | |
failure | string | null | no | |
failed_hop | integer | null | no |
Payment
| Field | Type | Required | Notes |
|---|---|---|---|
hash | string | yes | |
status | string | yes | one of pending, succeeded, failed |
amount | string | yes | base units as a decimal string |
asset | string | no | |
fee | string | no | base units as a decimal string |
preimage | string | null | no | |
payee | string | no | |
invoice | string | no | |
attempts | Attempt[] | no | |
created | integer | no | |
completed | integer | null | no | |
error | string | null | no |
Route
| Field | Type | Required | Notes |
|---|---|---|---|
amount | string | no | base units as a decimal string |
fee | string | no | base units as a decimal string |
hops | object[] | no |