Skip to content

Payments ​

Complete reference for Lightning payment endpoints. All paths carry the /api/v1 prefix. In amount fields _msat is millisatoshis and _sats is sats; do not mix them.

BOLT11 invoices ​

POST /api/v1/bolt11/receive ​

Generate a fixed-amount BOLT11 invoice.

Request:

json
{
  "amount_msat": "10000000",
  "description": "Service payment",
  "expiry_secs": 3600
}

Response:

json
{
  "invoice": "lntb100u1..."
}

POST /api/v1/bolt11/receive_var ​

Generate a variable-amount BOLT11 invoice (no amount, chosen by the payer).

Request:

json
{
  "description": "Tip",
  "expiry_secs": 3600
}

Response: same as receive.

POST /api/v1/bolt11/receive_for_hash ​

Generate an invoice with a specified payment_hash, for callers that manage the hash themselves.

Request:

json
{
  "amount_msat": "10000000",
  "description": "Service payment",
  "expiry_secs": 3600,
  "payment_hash": "abc123..."
}

Response: same as receive.

POST /api/v1/bolt11/pay ​

Pay a BOLT11 invoice, wait for completion and return the result.

Request:

json
{
  "invoice": "lntb100u1...",
  "amount_msat": "10000000",
  "channel_id": "abc123..."
}

amount_msat is optional and only used for variable-amount invoices; channel_id is optional and prefers a specific channel.

Response:

json
{
  "payment_id": "pay_abc123",
  "preimage": "def456...",
  "amount_sats": "10000",
  "destination": "02def456...",
  "fee_paid_msat": "1000"
}

POST /api/v1/bolt11/send ​

Send a fixed-amount invoice and return payment_id immediately without waiting.

Request:

json
{
  "invoice": "lntb100u1..."
}

Response:

json
{
  "payment_id": "pay_abc123"
}

POST /api/v1/bolt11/send_using_amount ​

Specify an amount for a variable-amount invoice and send it.

Request:

json
{
  "invoice": "lntb100u1...",
  "amount_msat": "50000000"
}

Response: same as bolt11/send.

POST /api/v1/bolt11/decode ​

Decode a BOLT11 invoice.

Request:

json
{
  "invoice": "lntb100u1..."
}

Response:

json
{
  "payment_hash": "abc123...",
  "destination": "02def456...",
  "amount_msat": "10000000",
  "expiry_secs": "3600"
}

amount_msat may be absent when the invoice carries no amount.

POST /api/v1/bolt11/claim_for_hash ​

Claim an inbound HTLC locked to a given hash using the provided preimage.

Request:

json
{
  "payment_hash": "abc123...",
  "preimage": "def456...",
  "claimable_amount_msat": "10000000"
}

Response:

json
{ "ok": true }

POST /api/v1/bolt11/fail_for_hash ​

Fail an inbound HTLC locked to a given hash.

Request:

json
{
  "payment_hash": "abc123..."
}

Response:

json
{ "ok": true }

BOLT12 offers ​

POST /api/v1/bolt12/offer/receive ​

Create a fixed-amount BOLT12 offer (a reusable payment request).

Request:

json
{
  "amount_msat": "50000000",
  "description": "Subscription",
  "expiry_secs": 86400,
  "quantity": "1"
}

expiry_secs and quantity are optional.

Response:

json
{
  "offer": "lno1..."
}

POST /api/v1/bolt12/offer/receive_var ​

Create a variable-amount BOLT12 offer.

Request:

json
{
  "description": "Subscription",
  "expiry_secs": 86400
}

Response: same as offer/receive.

POST /api/v1/bolt12/offer/send ​

Pay a BOLT12 offer.

Request:

json
{
  "offer": "lno1...",
  "amount_msat": "50000000",
  "quantity": "1",
  "payer_note": "Order #123"
}

Response:

json
{
  "payment_id": "pay_abc123"
}

POST /api/v1/bolt12/offer/decode ​

Decode a BOLT12 offer.

Request:

json
{
  "offer": "lno1..."
}

Response:

json
{
  "offer_id": "offer_abc123",
  "signing_pubkey": "02def456...",
  "description": "Subscription",
  "issuer": "Example",
  "amount_msat": "50000000",
  "absolute_expiry_unix_secs": "1704067200",
  "chain_hashes": ["000000000019d668..."],
  "paths_count": 1,
  "expects_quantity": false
}

BOLT12 refunds ​

POST /api/v1/bolt12/refund/initiate ​

Initiate a BOLT12 refund and produce a refund request.

Request:

json
{
  "amount_msat": "50000000",
  "expiry_secs": 86400,
  "quantity": "1",
  "payer_note": "Refund"
}

Response:

json
{
  "refund": "lnr1...",
  "payment_id": "pay_abc123"
}

POST /api/v1/bolt12/refund/decode ​

Decode a BOLT12 refund request.

Request:

json
{
  "refund": "lnr1..."
}

Response:

json
{
  "description": "Refund",
  "issuer": "Example",
  "amount_msat": "50000000",
  "absolute_expiry_unix_secs": "1704067200",
  "chain_hash": "000000000019d668...",
  "payer_signing_pubkey": "02def456...",
  "payer_note": "Refund",
  "quantity": "1",
  "paths_count": 1
}

POST /api/v1/bolt12/refund/request_payment ​

Produce the matching invoice for a refund request.

Request:

json
{
  "refund": "lnr1..."
}

Response:

json
{
  "invoice": "lni1...",
  "invoice_hex": "6c6e6931...",
  "payment_id": "pay_abc123"
}

Spontaneous payments ​

POST /api/v1/spontaneous/send ​

Send a spontaneous (keysend) payment without an invoice, directly to a destination pubkey.

Request:

json
{
  "counterparty_node_id": "02def456...",
  "amount_msat": "10000000",
  "custom_tlvs": [
    { "type": "5482373484", "value_hex": "0102..." }
  ]
}

custom_tlvs is optional; each entry has type (u64 string) and value_hex.

Response:

json
{
  "payment_id": "pay_abc123"
}

Payment status ​

GET /api/v1/payments ​

List the node's payment records.

Response:

json
[
  {
    "id": "pay_abc123",
    "direction": "Outbound",
    "status": "Succeeded",
    "amount_msat": "10000000",
    "kind": "bolt11",
    "fee_paid_msat": "1000",
    "htlc_locked": false,
    "payment_hash": "abc123..."
  }
]

Field notes:

  • direction: Inbound or Outbound
  • status: Pending, Succeeded or Failed
  • kind: payment kind
  • htlc_locked: whether an inbound HTLC is locked awaiting claim or fail
  • payment_hash: top-level payment hash (32-byte hex); may be null for on-chain or BOLT12 payments

GET /api/v1/payment/ ​

Get one payment's details.

Response: the same structure as a single object in the list.

POST /api/v1/payment/{paymentId}/wait ​

Block until the payment reaches a terminal state or times out.

Request:

json
{
  "timeout_secs": 30
}

Response:

json
{
  "ok": true,
  "payment": {
    "id": "pay_abc123",
    "direction": "Outbound",
    "status": "Succeeded",
    "amount_msat": "10000000"
  }
}

POST /api/v1/payment/{paymentId}/abandon ​

Abandon a stuck payment attempt.

Response:

json
{ "ok": true }

Error handling ​

  • 400: invalid request parameters
  • 402: insufficient balance or channel capacity
  • 404: no route found or payment does not exist
  • 408: payment or wait timeout
  • 500: node internal error
  • 503: node not ready or still syncing

A payment request that times out or drops its connection may still have changed node state; re-check the real result through GET /payment/{paymentId} or GET /payments instead of retrying the payment blindly.

Examples ​

Generate an invoice and pay it ​

bash
# Generate invoice
curl -X POST https://<your-node-domain>/api/v1/bolt11/receive \
  -H "Authorization: Bearer <node-credential>" \
  -H "Content-Type: application/json" \
  -d '{
    "amount_msat": "10000000",
    "description": "Coffee payment",
    "expiry_secs": 3600
  }'

# Pay invoice
curl -X POST https://<your-node-domain>/api/v1/bolt11/pay \
  -H "Authorization: Bearer <node-credential>" \
  -H "Content-Type: application/json" \
  -d '{
    "invoice": "lntb100u1..."
  }'

Send a spontaneous payment ​

bash
curl -X POST https://<your-node-domain>/api/v1/spontaneous/send \
  -H "Authorization: Bearer <node-credential>" \
  -H "Content-Type: application/json" \
  -d '{
    "counterparty_node_id": "02def456...",
    "amount_msat": "50000000"
  }'

Wait for a payment ​

bash
curl -X POST https://<your-node-domain>/api/v1/payment/pay_abc123/wait \
  -H "Authorization: Bearer <node-credential>" \
  -H "Content-Type: application/json" \
  -d '{ "timeout_secs": 30 }'

Trade and secure your RGB assets | Unlock the full potential of the RGB protocol