REST API
Complete REST API reference for ln.bot — wallets, invoices, payments, addresses, transactions, webhooks, keys, events, and L402.
Standard HTTP endpoints for programmatic access.
- Base URL:
https://api.ln.bot - Auth:
Authorization: Bearer key__... - Content-Type:
application/json
Wallets
POST/v1/wallets
Create a new wallet. No authentication required.
Request body:
{
"name": null
}Response:
{
"walletId": "wal_c7i0hnuoxxupuwej",
"primaryKey": "key__...",
"secondaryKey": "key__...",
"name": "k9x2mwp",
"address": "k9x2mwp@ln.bot",
"recoveryPassphrase": "abandon ability able about ..."
}No auth required. Save both keys — the recovery passphrase is shown only once.
GET/v1/wallets/current
Get current wallet. Returns the wallet ID, name, and balance.
Response:
{
"walletId": "wal_c7i0hnuoxxupuwej",
"name": "k9x2mwp",
"balance": 12500,
"onHold": 0,
"available": 12500
}PATCH/v1/wallets/current
Update wallet name.
Request body:
{
"name": "my-agent"
}Response:
{
"walletId": "wal_c7i0hnuoxxupuwej",
"name": "my-agent",
"balance": 12500,
"onHold": 0,
"available": 12500
}Invoices
POST/v1/invoices
Create an invoice. Creates a BOLT11 invoice valid for 60 minutes. Optionally include a reference for tracking and a memo embedded in the invoice.
Request body:
{
"amount": 1000,
"memo": "AI task payment",
"reference": null
}Response:
{
"number": 1,
"status": "pending",
"amount": 1000,
"bolt11": "lnbc10u1pn...",
"reference": null,
"memo": "AI task payment",
"preimage": null,
"txNumber": null,
"createdAt": "2026-01-15T10:30:00Z",
"settledAt": null,
"expiresAt": "2026-01-15T11:30:00Z"
}GET/v1/invoices
List invoices. Returns invoices in reverse chronological order.
| Parameter | In | Type | Description |
|---|---|---|---|
limit | query | int | Max results |
after | query | int | Paginate by invoice number |
Response:
[
{
"number": 2,
"status": "settled",
"amount": 500,
"bolt11": "lnbc5u1pn...",
"reference": null,
"memo": null,
"preimage": "d4e5f6...",
"txNumber": 3,
"createdAt": "2026-01-15T11:00:00Z",
"settledAt": "2026-01-15T11:02:00Z",
"expiresAt": "2026-01-15T12:00:00Z"
}
]GET/v1/invoices/{number}
Get invoice by number.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
number | path | int | yes | Invoice number |
Response: Same shape as POST /v1/invoices, with settlement data populated.
GET/v1/invoices/{paymentHash}
Get invoice by payment hash.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
paymentHash | path | string | yes | Payment hash |
Same response as GET /v1/invoices/{number}.
GET/v1/invoices/{number}/events
Wait for invoice (SSE). Server-Sent Events stream. Emits 'settled' or 'expired' then closes.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
number | path | int | yes | Invoice number |
timeout | query | int | no | Max wait in seconds (default 60, max 300) |
Also available as /v1/invoices/{paymentHash}/events. Keepalive comments every 30s.
POST/v1/invoices/for-wallet
Create an invoice for a wallet. Creates a BOLT11 invoice for the given wallet ID (wal_xxx). The invoice is not saved until payment settles. No authentication required. Rate limited by IP.
Request body:
{
"walletId": "wal_c7i0hnuoxxupuwej",
"amount": 1000,
"reference": null,
"comment": null
}Response:
{
"bolt11": "lnbc10u1pn...",
"amount": 1000,
"expiresAt": "2026-01-15T11:30:00Z"
}No auth required.
POST/v1/invoices/for-address
Create an invoice for a Lightning address. Creates a BOLT11 invoice for the wallet that owns the given address. No authentication required. Rate limited by IP.
Request body:
{
"address": "mybot@ln.bot",
"amount": 1000,
"tag": null,
"comment": null
}Response:
{
"bolt11": "lnbc10u1pn...",
"amount": 1000,
"expiresAt": "2026-01-15T11:30:00Z"
}No auth required.
Payments
POST/v1/payments
Send a payment. Accepts a Lightning address (user@domain), LNURL (lnurl1...), or BOLT11 invoice in 'target'. Amount required for addresses and LNURLs, optional for BOLT11 (uses invoice amount). Use idempotencyKey to safely retry.
Request body:
{
"target": "r7vq3np@ln.bot",
"amount": 500,
"maxFee": null,
"idempotencyKey": null,
"reference": null
}Response:
{
"number": 1,
"status": "settled",
"amount": 500,
"maxFee": 10,
"serviceFee": 0,
"actualFee": 0,
"address": "r7vq3np@ln.bot",
"reference": null,
"preimage": "e5f6a7b8...",
"txNumber": 2,
"failureReason": null,
"createdAt": "2026-01-15T10:35:00Z",
"settledAt": "2026-01-15T10:35:01Z"
}GET/v1/payments
List payments. Returns payments in reverse chronological order.
| Parameter | In | Type | Description |
|---|---|---|---|
limit | query | int | Max results |
after | query | int | Paginate by payment number |
Response:
[
{
"number": 1,
"status": "settled",
"amount": 500,
"maxFee": 10,
"serviceFee": 0,
"actualFee": 0,
"address": "r7vq3np@ln.bot",
"reference": null,
"preimage": "e5f6a7b8...",
"txNumber": 2,
"failureReason": null,
"createdAt": "2026-01-15T10:35:00Z",
"settledAt": "2026-01-15T10:35:01Z"
}
]GET/v1/payments/{number}
Get payment by number.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
number | path | int | yes | Payment number |
Same response shape as POST /v1/payments.
GET/v1/payments/{paymentHash}
Get payment by payment hash.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
paymentHash | path | string | yes | Payment hash |
Same response shape as POST /v1/payments.
GET/v1/payments/{number}/events
Wait for payment (SSE). Server-Sent Events stream. Emits 'settled' or 'failed' then closes.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
number | path | int | yes | Payment number |
timeout | query | int | no | Max wait in seconds (default 60, max 300) |
Also available as /v1/payments/{paymentHash}/events. Keepalive comments every 30s.
Addresses
POST/v1/addresses
Create an address. Creates a random address (if address is null) or claims a vanity address. Vanity addresses are charged based on length.
Request body:
{
"address": null
}Response:
{
"address": "j4hf8tj",
"generated": true,
"cost": 0,
"createdAt": "2026-01-15T10:00:00Z"
}GET/v1/addresses
List addresses.
Response:
[
{
"address": "j4hf8tj",
"generated": true,
"cost": 0,
"createdAt": "2026-01-15T10:00:00Z"
},
{
"address": "mybot",
"generated": false,
"cost": 2000,
"createdAt": "2026-01-16T08:00:00Z"
}
]DELETE/v1/addresses/{address}
Delete an address. No refund for vanity addresses.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
address | path | string | yes | Address to delete |
Returns 204 No Content on success.
POST/v1/addresses/{address}/transfer
Transfer to another wallet. Transfers an address to another wallet by providing its API key.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
address | path | string | yes | Address to transfer |
Request body:
{
"targetWalletKey": "key__..."
}Response:
{
"address": "mybot",
"transferredTo": "wal_x8j2knroyyqpvwfh"
}Transactions
GET/v1/transactions
List transactions. Returns credit and debit transactions in reverse chronological order. Each includes the balance after it was applied.
| Parameter | In | Type | Description |
|---|---|---|---|
limit | query | int | Max results |
after | query | int | Paginate by transaction number |
Response:
[
{
"number": 3,
"type": "credit",
"amount": 500,
"balanceAfter": 13000,
"networkFee": 0,
"serviceFee": 0,
"paymentHash": "a1b2c3...",
"preimage": "d4e5f6...",
"reference": null,
"note": null,
"createdAt": "2026-01-15T11:02:00Z"
},
{
"number": 2,
"type": "debit",
"amount": 500,
"balanceAfter": 12500,
"networkFee": 0,
"serviceFee": 0,
"paymentHash": "f6e5d4...",
"preimage": "c3b2a1...",
"reference": null,
"note": null,
"createdAt": "2026-01-15T10:35:01Z"
}
]Webhooks
POST/v1/webhooks
Create a webhook. Registers a URL to receive event callbacks. The signing secret is returned only once. Max 10 per wallet.
Request body:
{
"url": "https://example.com/hooks/lnbot"
}Response:
{
"id": "whk_a1b2c3d4",
"url": "https://example.com/hooks/lnbot",
"secret": "whsec_...",
"createdAt": "2026-01-15T10:00:00Z"
}Save the secret — it cannot be retrieved again.
GET/v1/webhooks
List webhooks. Secrets are not included in the response.
Response:
[
{
"id": "whk_a1b2c3d4",
"url": "https://example.com/hooks/lnbot",
"active": true,
"createdAt": "2026-01-15T10:00:00Z"
}
]DELETE/v1/webhooks/{id}
Delete a webhook. Pending deliveries are discarded.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | Webhook ID |
Returns 204 No Content on success.
API Keys
POST/v1/keys/{slot}/rotate
Rotate an API key. Generates a new secret for the slot (0 = primary, 1 = secondary). The old key is immediately invalidated.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
slot | path | int | yes | 0 = primary, 1 = secondary |
Response:
{
"key": "key__newrotated...",
"name": "primary"
}The new key is returned once and cannot be retrieved again.
Events
GET/v1/events
Real-time event stream. Opens a Server-Sent Events (SSE) stream that pushes real-time notifications for the authenticated wallet.
Events: invoice.created, invoice.settled, payment.created, payment.settled, payment.failed. Each message is a JSON object with event, created_at, and data fields. Keepalive comments every 30s.
L402
POST/v1/l402/challenges
Create an L402 challenge. Creates a Lightning invoice and mints a macaroon. Returns the pre-formatted WWW-Authenticate header value for use in HTTP 402 responses.
Request body:
{
"amount": 100,
"description": "API access",
"expirySeconds": 3600,
"caveats": null
}Response:
{
"macaroon": "AgELbG4uYm90...",
"invoice": "lnbc1u1pn...",
"paymentHash": "a1b2c3d4...",
"expiresAt": "2026-01-15T11:30:00Z",
"wwwAuthenticate": "L402 macaroon=\"...\", invoice=\"lnbc...\""
}POST/v1/l402/verify
Verify an L402 token. Stateless verification of an L402 token. Checks macaroon signature, preimage proof-of-payment, and caveat validity (e.g., expiry). No database lookup needed.
Request body:
{
"authorization": "L402 AgELbG4uYm90...:a1b2c3d4..."
}Response:
{
"valid": true,
"paymentHash": "a1b2c3d4...",
"caveats": ["expiry=1737000000"],
"error": null
}POST/v1/l402/pay
Pay an L402 challenge. Parses a WWW-Authenticate header, pays the embedded invoice, and returns a ready-to-use Authorization header. If wait=true (default), polls for settlement up to timeout seconds.
Request body:
{
"wwwAuthenticate": "L402 macaroon=\"...\", invoice=\"lnbc...\"",
"maxFee": null,
"reference": null,
"wait": true,
"timeout": 60
}Response:
{
"authorization": "L402 AgELbG4uYm90...:e5f6a7b8...",
"paymentHash": "a1b2c3d4...",
"preimage": "e5f6a7b8...",
"amount": 100,
"fee": 0,
"paymentNumber": 5,
"status": "settled"
}