REST API
REST API reference for ln.bot covering accounts, wallets, invoices, payments, addresses, webhooks, events, and L402.
Standard HTTP endpoints for programmatic access.
- Base URL:
https://api.ln.bot - Auth:
Authorization: Bearer uk_...(user key) orBearer wk_...(wallet key) - Content-Type:
application/json
Two key types:
| Key type | Prefix | Scope |
|---|---|---|
| User key | uk_ | All wallets under the account |
| Wallet key | wk_ | Single wallet only |
Account
POST/v1/register
Register a new account. No authentication required.
Response:
{
"userId": "usr_a1b2c3d4",
"primaryKey": "uk_...",
"secondaryKey": "uk_...",
"recoveryPassphrase": "abandon ability able about ..."
}No auth required. Save both keys — the recovery passphrase is shown only once.
GET/v1/me
Get authenticated identity. Works with both user keys and wallet keys.
Response:
{
"walletId": "wal_c7i0hnuoxxupuwej"
}Wallets
POST/v1/wallets
Create a new wallet. Requires user key authentication. Name is auto-generated.
Response:
{
"walletId": "wal_c7i0hnuoxxupuwej",
"name": "k9x2mwp",
"address": "k9x2mwp@ln.bot"
}GET/v1/wallets
List all wallets. Requires user key authentication.
Response:
[
{
"walletId": "wal_c7i0hnuoxxupuwej",
"name": "k9x2mwp",
"createdAt": "2026-01-15T10:00:00Z"
}
]GET/v1/wallets/{walletId}
Get wallet details. With a wallet key (wk_), use /v1/wallets/current.
Response:
{
"walletId": "wal_c7i0hnuoxxupuwej",
"name": "k9x2mwp",
"balance": 12500,
"onHold": 0,
"available": 12500
}PATCH/v1/wallets/{walletId}
Update wallet name. With a wallet key (wk_), use /v1/wallets/current.
Request body:
{
"name": "my-agent"
}Response:
{
"walletId": "wal_c7i0hnuoxxupuwej",
"name": "my-agent",
"balance": 12500,
"onHold": 0,
"available": 12500
}Wallet Keys
Wallet keys (wk_) give scoped access to a single wallet. Maximum 1 per wallet.
POST/v1/wallets/{walletId}/key
Create a wallet key.
Response:
{
"key": "wk_...",
"hint": "wk_...a1b2"
}The key is shown once and cannot be retrieved again.
GET/v1/wallets/{walletId}/key
Get wallet key info (no plaintext key).
Response:
{
"hint": "wk_...a1b2",
"createdAt": "2026-01-15T10:00:00Z",
"lastUsedAt": "2026-01-16T08:00:00Z"
}DELETE/v1/wallets/{walletId}/key
Revoke the wallet key immediately.
Returns 204 No Content on success.
POST/v1/wallets/{walletId}/key/rotate
Rotate the wallet key. Old key is immediately invalidated.
Response:
{
"key": "wk_...",
"hint": "wk_...c3d4"
}Invoices
POST/v1/wallets/{walletId}/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/wallets/{walletId}/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/wallets/{walletId}/invoices/{number}
Get invoice by number.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
number | path | int | yes | Invoice number |
Response: Same shape as POST, with settlement data populated.
GET/v1/wallets/{walletId}/invoices/{paymentHash}
Get invoice by payment hash.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
paymentHash | path | string | yes | Payment hash |
Same response as GET by number.
GET/v1/wallets/{walletId}/invoices/{number}/events
Wait for invoice (SSE). Server-Sent Events stream. Emits 'settled' or 'expired' then closes. Requires wallet key (wk_).
| 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/wallets/{walletId}/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/wallets/{walletId}/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/wallets/{walletId}/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/wallets/{walletId}/payments/{number}
Get payment by number.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
number | path | int | yes | Payment number |
Same response shape as POST.
GET/v1/wallets/{walletId}/payments/{paymentHash}
Get payment by payment hash.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
paymentHash | path | string | yes | Payment hash |
Same response shape as POST.
GET/v1/wallets/{walletId}/payments/resolve
Inspect a payment target before sending. Returns amount constraints.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
target | query | string | yes | Lightning address, LNURL, or BOLT11 |
Response:
{
"type": "address",
"min": 1,
"max": 1000000000,
"fixed": false,
"amount": null
}GET/v1/wallets/{walletId}/payments/{number}/events
Wait for payment (SSE). Server-Sent Events stream. Emits 'settled' or 'failed' then closes. Requires wallet key (wk_).
| 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/wallets/{walletId}/payments/{paymentHash}/events. Keepalive comments every 30s.
Addresses
POST/v1/wallets/{walletId}/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/wallets/{walletId}/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/wallets/{walletId}/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/wallets/{walletId}/addresses/{address}/transfer
Transfer to another wallet. Only vanity (purchased) addresses can be transferred.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
address | path | string | yes | Address to transfer |
Request body:
{
"targetWalletKey": "uk_..."
}Response:
{
"address": "mybot",
"transferredTo": "wal_x8j2knroyyqpvwfh"
}Transactions
GET/v1/wallets/{walletId}/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/wallets/{walletId}/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/wallets/{walletId}/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/wallets/{walletId}/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.
User Keys
POST/v1/keys/{slot}/rotate
Rotate a user 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": "uk_newrotated...",
"name": "primary"
}The new key is returned once and cannot be retrieved again.
Events
GET/v1/wallets/{walletId}/events
Real-time event stream. Opens a Server-Sent Events (SSE) stream that pushes real-time notifications for the wallet. Requires wallet key (wk_).
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/wallets/{walletId}/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/wallets/{walletId}/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/wallets/{walletId}/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"
}