REST API Reference
The Lexe SDK sidecar exposes the following REST API endpoints:
GET /v2/health
GET /v2/node/node_info
POST /v2/node/create_invoice
POST /v2/node/pay_invoice
GET /v2/node/payment
Conventions
Payments are uniquely identified by their index value string. Fetch the status
of a payment using the GET /v2/node/payment?index=<index> endpoint.
amount values are fixed-precision decimal values denominated in satoshis
(1 BTC = 100,000,000 satoshis) and serialized as strings. The representation
supports up-to millisatoshi precision (1 satoshi = 1,000 millisatoshis).
All timestamps indicate the number of milliseconds since the UNIX epoch.
Prefer longer request timeouts (e.g. 15 seconds) since your node may need time to startup and sync if it hasn't received any requests in a while.
GET /v2/health
Get the health status of the Lexe SDK sidecar. Returns HTTP 200 once the sidecar is running and ready to accept requests.
Response:
status:"ok"if configuration is OK, otherwise a warning or error message.
Examples:
GET /v2/node/node_info
Fetch information about the node and wallet balance.
Request:
Empty.
Response:
version: The node's current semver version, e.g.0.6.9.measurement: The hex-encoded SGX 'measurement' of the current node. The measurement is the hash of the enclave binary.user_pk: The hex-encoded ed25519 user public key used to identify a Lexe user. The user keypair is derived from the root seed.-
node_pk: The hex-encoded secp256k1 Lightning node public key; thenode_id. -
balance: The sum of ourlightning_balanceand ouronchain_balance, in sats. -
lightning_balance: Total Lightning balance in sats, summed over all of our channels. lightning_sendable_balance: An estimated upper bound, in sats, on how much of our Lightning balance we can send to most recipients on the Lightning Network, accounting for Lightning limits such as our channel reserve, pending HTLCs, fees, etc. You should usually be able to spend this amount.-
lightning_max_sendable_balance: A hard upper bound on how much of our Lightning balance can be spent right now, in sats. This is always >=lightning_sendable_balance. Generally it is only possible to spend exactly this amount if the recipient is a Lexe user. -
onchain_balance: Total on-chain balance in sats, including unconfirmed funds. -
onchain_trusted_balance: Trusted on-chain balance in sats, including only confirmed funds and unconfirmed outputs originating from our own wallet. -
num_channels: The total number of Lightning channels. num_usable_channels: The number of channels which are currently usable, i.e.channel_readymessages have been exchanged and the channel peer is online. Is always less than or equal tonum_channels.
Examples:
$ curl http://localhost:5393/v2/node/node_info | jq .
{
"version": "0.7.10",
"measurement": "f7415694ca3262f8b479d915a1799f896902a8697c469f69d9a86eb8c9f1089f",
"user_pk": "b484a4890b47358ee68684bcd502d2eefa1bc66cc0f8ac2e5f06384676be74eb",
"node_pk": "0203e73be064cc91d5e3c96d8e2f2f124f3196e07e9916b51307b6ff5419b59f6e",
"balance": "134736",
"lightning_balance": "75282",
"lightning_sendable_balance": "57505.107",
"lightning_max_sendable_balance": "57203.107",
"onchain_balance": "59454",
"onchain_trusted_balance": "59454",
"num_channels": 5,
"num_usable_channels": 5
}
POST /v2/node/create_invoice
Create a new BOLT11 Lightning invoice to receive Bitcoin over the Lightning network.
Request:
The request body should be a JSON object with the following fields:
expiration_secs: Int: The number of seconds until the invoice expires.amount: String(optional): The amount to request in satoshis, as a string. If not specified, the payer will decide the amount.description: String(optional): The payment description that will be presented to the payer.
Response:
The response includes the encoded invoice string, which should be presented to
the payer to complete the payment.
The index is a unique identifier for the invoice, which can be used to track
the payment status via GET /v2/node/payment.
index: Identifier for this inbound invoice payment.invoice: The string-encoded BOLT 11 invoice.description: The description encoded in the invoice, if one was provided.amount: The amount encoded in the invoice, if there was one. Returningnullmeans we created an amountless invoice.created_at: The invoice creation time, in milliseconds since the UNIX epoch.expires_at: The invoice expiration time, in milliseconds since the UNIX epoch.payment_hash: The hex-encoded payment hash of the invoice.payment_secret: The payment secret of the invoice.
Examples:
$ curl -X POST http://localhost:5393/v2/node/create_invoice \
--header "content-type: application/json" \
--data '{ "expiration_secs": 3600 }' \
| jq .
{
"index": "0000001744926519917-ln_9be5e4e3a0356cc4a7a1dce5a4af39e2896b7eb7b007ec6ca8c2f8434f21a63a",
"invoice": "lnbc1p5qzaehdqqpp5n0j7fcaqx4kvffapmnj6fteeu2ykkl4hkqr7cm9gctuyxnep5caqcqpcsp5slzxgxrsu3jq8xq7rp2gx3ge0thlt3446jpp8kqs87pve60679ls9qyysgqxqrrssnp4q0vzagw8x7r9eyalw35t0u6syql8rtqf9tejep0z6xrwkqrua5advrzjqv22wafr68wtchd4vzq7mj7zf2uzpv67xsaxcemfzak7wp7p0r29wzmk4uqqj5sqqyqqqqqqqqqqhwqqfq89vuhjlg2tt56sv9pdt8t5cvdgfaaf6nxqtt0av74ragpql7l2d42euknlw06fcgp8xhe93xe7c802z3hrnysfsjgavmwfts7zdvj2cqka3672",
"description": null,
"amount": null,
"created_at": 1744926519000,
"expires_at": 1744930119000,
"payment_hash": "9be5e4e3a0356cc4a7a1dce5a4af39e2896b7eb7b007ec6ca8c2f8434f21a63a",
"payment_secret": "87c4641870e46403981e18548345197aeff5c6b5d48213d8103f82cce9faf17f"
}
$ curl -X POST http://localhost:5393/v2/node/create_invoice \
--header "content-type: application/json" \
--data '{ "expiration_secs": 3600, "amount": "1000", "description": "Lunch" }' \
| jq .
{
"index": "0000001744926580307-ln_12c8ec9465cff06b756b9f20dbdfd9d4b03b3c153bd39a5401c61a0241bd1e96",
"invoice": "lnbc10u1p5qzam5dqgf36kucmgpp5ztywe9r9elcxkattnusdhh7e6jcrk0q480fe54qpccdqysdar6tqcqpcsp5f3nvkgufsxxnsfa4wnyzgjk3sjpxcwsp8zw4ck0mstcyrgpyu8ls9qyysgqxqrrssnp4q0vzagw8x7r9eyalw35t0u6syql8rtqf9tejep0z6xrwkqrua5advrzjqv22wafr68wtchd4vzq7mj7zf2uzpv67xsaxcemfzak7wp7p0r29wzmk4uqqj5sqqyqqqqqqqqqqhwqqfqdtsc32py445jyfcdwcnf25kwwh0ezvw0890xlpfjxtm4a9pcuyjpvd54alrze0tzxzl4cgm82q3deh7w66zsukuccrgzq59vpp28lvgp4jesmt",
"description": "Lunch",
"amount": "1000",
"created_at": 1744926580000,
"expires_at": 1744930180000,
"payment_hash": "12c8ec9465cff06b756b9f20dbdfd9d4b03b3c153bd39a5401c61a0241bd1e96",
"payment_secret": "4c66cb2389818d3827b574c8244ad184826c3a01389d5c59fb82f041a024e1ff"
}
POST /v2/node/pay_invoice
Pay a BOLT11 Lightning invoice.
Request:
The request body should be a JSON object with the following fields:
invoice: String: The encoded invoice string to pay.fallback_amount: String(optional): For invoices without an amount specified, you must specify a fallback amount to pay.note: String(optional): A personal note to attach to the payment. The receiver will not see this note.
Response:
The response includes the index of the payment, which can be used to track the
payment status via GET /v2/node/payment.
index: Identifier for this outbound invoice payment.created_at: When we tried to pay this invoice, in milliseconds since the UNIX epoch.
Examples:
$ curl -X POST http://localhost:5393/v2/node/pay_invoice \
--header "content-type: application/json" \
--data '{ "invoice": "lnbc100n1p5qz7z2dq58skjqnr90pjjq4r9wd6qpp5u8uw073l8dp7ked0ujyhegwxx6yxx6aq5ganqyt3pepnk5dm87dqcqpcsp5nrs44f3upgxysnylrrpyrxs96mgazjjstuykyew74zv0najzkdeq9qyysgqxqyz5vqnp4q0w73a6xytxxrhuuvqnqjckemyhv6avveuftl64zzm5878vq3zr4jrzjqv22wafr68wtchd4vzq7mj7zf2uzpv67xsaxcemfzak7wp7p0r29wz5ecsqq2pgqqcqqqqqqqqqqhwqqfqrpeeq5xdys8vcfcark45w992h6j5nhajc62wet0q25ggxjwhtcfn8c3qx30fqzq8mqxfdtks57zw25zp0z2kl9yrfwkkthxclawxpfcqtdcpfu" }' \
| jq .
{
"index": "0000001744926842458-ln_e1f8e7fa3f3b43eb65afe4897ca1c63688636ba0a23b3011710e433b51bb3f9a",
"created_at": 1744926842458
}
GET /v2/node/payment
Use this endpoint to query the status of a payment or invoice. Payments will transition
through the following status states: "pending" -> "completed" or "pending" -> "failed".
Once a payment is finalized (either completed or failed), you do not need to query
the payment any more.
Request:
The request should include the index of the payment query as a query string
parameter.
Response:
The response includes the payment details. If the payment is not found, the endpoint returns HTTP 404.
index: Identifier for this payment.rail: The technical payment mechanism:"onchain","invoice","offer","spontaneous".kind: The application-level payment kind, e.g."onchain","invoice","offer","spontaneous","waived_channel_fee","waived_liquidity_fee".direction: The payment direction:"inbound","outbound", or"info".txid: (Onchain payments only) The txid of the on-chain payment.replacement: (Onchain payments only) The hex-encoded txid of the transaction that spent the outputs spent by this on-chain payment, if one exists.status: The status of this payment:"pending","completed","failed".status_msg: The payment status as a human-readable message. These strings are customized per payment type, e.g. "invoice generated", "timed out".finalized_at: If this payment is finalized, meaning it is "completed" or "failed", this is the time it was finalized, in milliseconds since the UNIX epoch.
Examples:
$ curl 'http://localhost:5393/v2/node/payment?index=0000001744926519917-ln_9be5e4e3a0356cc4a7a1dce5a4af39e2896b7eb7b007ec6ca8c2f8434f21a63a' \
| jq .
{
"index": "0000001744926519917-ln_9be5e4e3a0356cc4a7a1dce5a4af39e2896b7eb7b007ec6ca8c2f8434f21a63a",
"rail": "invoice",
"kind": "invoice",
"direction": "inbound",
"txid": null,
"replacement": null,
"amount": null,
"fees": "0",
"status": "pending",
"status_msg": "invoice generated",
"note": null
}
$ curl 'http://localhost:5393/v2/node/payment?index=0000001744926842458-ln_e1f8e7fa3f3b43eb65afe4897ca1c63688636ba0a23b3011710e433b51bb3f9a' \
| jq .
{
"index": "0000001744926842458-ln_e1f8e7fa3f3b43eb65afe4897ca1c63688636ba0a23b3011710e433b51bb3f9a",
"rail": "invoice",
"kind": "invoice",
"direction": "outbound",
"txid": null,
"replacement": null,
"amount": "10",
"fees": "0.03",
"status": "completed",
"status_msg": "completed",
"note": "My personal note",
"finalized_at": 1744926857989
}
# Example of missing payment (returns HTTP 404)
$ curl -i 'http://localhost:5393/v2/node/payment?index=0000000000000000000-ln_0000000000000000000000000000000000000000000000000000000000000000'
HTTP/1.1 404 Not Found
content-type: application/json
content-length: 68
date: Thu, 11 Sep 2025 22:26:53 GMT
{
"code": 107,
"msg": "Payment not found",
"data": null,
"sensitive": false
}