Introduction
Use the Nodana API to create and manage hosted nodes and webhook receivers. Use your node’s Phoenixd API for invoices, Lightning payments, balances, channels and LNURL services.
API addresses
| API | Base URL | Authentication |
|---|---|---|
| Nodana management | https://api.nodana.io/v1 | Bearer API key |
| Phoenixd | Your node’s HTTPS URL | HTTP Basic with an empty username and Phoenixd password |
Host attestation uses your node’s HTTPS URL without an Authorization header.
Examples use https://node-a1b2.nodana.app as a dummy node URL. Replace it with your node’s complete HTTPS connection URL. Keep API keys and passwords in your backend’s secret configuration.
Nodana management endpoint paths are relative to https://api.nodana.io/v1; requests use JSON bodies. Phoenixd endpoint paths are relative to your node URL; POST parameters use form data and payment-history filters use query parameters. See Authentication.
Manage hosted nodes
- Create a node: start provisioning and save the one-time credentials returned in the response.
- List nodes: find your node IDs and statuses.
- Update a node: select and apply an available release.
- Webhooks: receive and verify payment notifications.
- Attestation: request evidence for client-side verification of a protected Nodana host.
Work with Phoenixd
- Payments: create invoices and offers, send funds, track payments and export history.
- Node: inspect balances and channels, decode payment requests and estimate liquidity fees.
- LNURL: pay, withdraw and authenticate with LNURL services.
- WebSocket: subscribe to incoming payments.
The upstream reference describes the daemon API.
See Responses, Error handling and Rate limiting. Compact endpoint lists are available for the Nodana API and Phoenixd API.
Authentication
Choose credentials for the API you are calling: a Nodana account API key for hosted-node and webhook management, or your node’s Phoenixd password for payments and node information.
Nodana
For direct API integrations, authenticate node operations with an API key in the Authorization header.
Create an API key
In the dashboard, open Developers, then API Keys. Create a key for your integration and select the permissions it needs. Save the full key when it is shown; it cannot be retrieved later.
Send authenticated requests
Send your key as Authorization: Bearer YOUR_API_KEY. Replace the placeholder with your API key.
For Lightning operations, use your node URL and Phoenixd password with the Phoenixd API or CLI.
Permissions
| Permission | Scope | Operations |
|---|---|---|
| Nodes → Read | nodes:read | List nodes, read details, check available updates and read webhook settings and deliveries |
| Nodes → Write | nodes:write | Create, rename, start, stop, restart, update or delete nodes; create, change or delete their webhook endpoint |
Write also requires Read. Choose the minimum permissions your integration needs.
Keys belong to one account. The API uses the key to determine your account; you do not need to send an account ID. The key must include the required permission. Missing, invalid, disabled, or revoked keys and insufficient permissions return 401 Unauthorized. Nodes belonging to another account return 404 Not Found.
Keep keys private
Use keys from your backend or trusted scripts. Store them in secret storage, keep them out of browser code and source control, and revoke or replace them if exposed.
A Nodana API key authenticates calls to the Nodana API. Your node's Phoenixd password is a separate credential for direct calls to its Phoenixd API.
Phoenixd
Use HTTP Basic authentication with an empty username and your Phoenixd password. Replace the dummy URL with your node’s connection URL and keep PHOENIXD_PASSWORD in your backend’s environment or secret storage. JavaScript examples in this reference run on the server with Node.js.
Phoenixd creates its passwords on first start. For a self-hosted daemon, find http-password and http-password-limited-access in ~/.phoenix/phoenix.conf, or the corresponding directory on your persistent volume.
The full password permits all operations, including spending funds. Prefer the limited password for reading information and creating invoices. Each endpoint page states the access it needs. Use the full password for spending, channel closure and other operations marked as full access.
For remote requests, use the complete HTTPS connection URL and leave certificate verification enabled. Keep both passwords private, including the limited password. Store them in backend secret settings and replace exposed credentials on the node. Do not put credentials in browser code, URLs or source control.
Attestation
The node’s attestation endpoint does not require a Phoenixd password or Nodana API key. Supply the challenge described on its endpoint page without an Authorization header.
Responses
Read the response format on each endpoint page. Nodana management and Phoenixd return different response shapes and timestamp units.
Nodana
Node reads and start, stop, restart and update operations return node metadata. Lists wrap objects in nodes. Creation returns {node, credentials}; save the one-time recovery seed and passwords from credentials when the response arrives. Node creation and lifecycle operations continue in the background after 202 Accepted. Node deletion returns 202 with no body.
Node response fields
| Field | Type | Description |
|---|---|---|
id | string | Nodana node ID |
name | string | Display name |
region | string | Hosting region |
image | string | Node software image identifier |
accessMode | string | Node access mode |
status | string | Node lifecycle state |
publicUrl | string or null | Phoenixd HTTPS URL, or null while being set up |
failureMessage | string or null | Public failure message |
updateStatus | string or null | Update progress or outcome |
updateCompletedAt | integer or null | Update completion time in Unix seconds |
lastCheckedAt | integer or null | Last status check in Unix seconds |
createdAt | integer | Creation time in Unix seconds |
updatedAt | integer | Last change time in Unix seconds |
Node states
Node states include provisioning, ready, starting, stopping, stopped, restarting, updating, failed, deleting, deleted and cordoned. stopped means the user took the node offline; cordoned means it was suspended because the account ran out of credit.
For shared response handling, see Error handling and Rate limiting.
Webhook responses
Reading a receiver returns {endpoint: {...}}, or {endpoint: null} when none is configured. Creating one returns {endpoint, signingSecret}; save the secret immediately because it is only returned once. Updating returns the endpoint object, and deleting returns 204 No Content without a body.
Delivery history wraps the latest 50 records in deliveries. Its timestamps, and node metadata timestamps, use Unix seconds.
Phoenixd
Read the response format on each endpoint page. Phoenixd returns JSON objects or arrays for structured results, and plain text for offers, addresses and some node actions. Invoice creation returns the invoice in serialized alongside its paymentHash.
Payment lists are arrays, paginated with limit and offset. Date filters and payment timestamps use Unix milliseconds. Fields named amountSat, balanceSat, receivedSat and feeCreditSat use satoshis. Payment-history fees values use millisatoshis; do not infer their unit from the routingFeeSat field returned by a payment attempt.
Optional fields can be absent. Read isPaid to confirm a payment and check receivedSat against the expected order amount. Preserve the payment hash or ID so you can look up an uncertain result. See Error handling.
Error handling
Check the HTTP status and response body before treating an operation as successful. Handle errors according to the API you called.
Nodana
Check the HTTP status before reading a response as a successful result. API errors return an error object containing a stable code and a human-readable message.
Use the code and status for application logic. Keep the message for diagnostics rather than matching its wording.
Status codes
For 400, check the input and the operation's state requirements. For 401, check your key and permissions. For 404, check the node ID and whether it was deleted. For 429, wait for the Retry-After interval.
If credit or billing prevents the operation (402), resolve the account's credit or billing state. Server and upstream failures (500, 502, 503) require checking the outcome before retrying a mutation.
Malformed JSON or unsupported request content types may be rejected before the endpoint runs. Handle unexpected or non-JSON error bodies as well.
Retry carefully
Retry reads after transient failures using bounded exponential backoff. For 429 responses, follow the rate limiting guidance.
A timeout or connection error does not establish that a mutation failed. Check node state before repeating a lifecycle operation. After an interrupted create request, list your nodes and reconcile the outcome before trying again. Each creation attempt requires a new requestId; repeating an accepted request returns 409 Conflict. Credentials are returned only once. If the node was created but you did not receive its credentials, contact Nodana before attempting another creation.
A 202 Accepted creation response means provisioning is still in progress. A successful update request also starts background work; inspect the node to determine the final outcome.
Phoenixd
Check the HTTP status and the endpoint's response body before treating an operation as successful. Response bodies vary by operation.
For 401, check the Phoenixd password, empty Basic-auth username and the endpoint's required access. For invalid parameters, check the field names, amount units and form encoding. If a payment lookup returns 404, check the hash or payment ID and the node URL.
A successful HTTP response alone does not establish that money moved. Inspect the returned payment or action result and use Get incoming payment or Get outgoing payment to confirm its outcome.
Interrupted requests
If an outgoing payment times out, look it up before submitting another payment. A lost response does not mean the payment failed. Save payment IDs and hashes in your backend so you can reconcile them.
Keep your application's invoice creation and fulfilment records. Use externalId to associate invoices with orders and list incoming payments to find them after an interrupted request. Reusing an external ID does not prevent another invoice from being created.
Rate limiting
Limit concurrency and avoid tight polling loops. The Nodana management API and your node’s Phoenixd connection have separate throttling behaviour.
Nodana
Node operations share a request limit per client IP address. Requests from applications behind the same outbound IP count towards the same limit, even when they use different API keys.
Most Nodana operations default to 180 requests per 60-second window. Node creation uses a separate default limit of 10 requests per 60 seconds. Use the response headers to decide when to retry; deployed limits can change.
Rate-limit responses
When the limit is exceeded, the API returns 429 Too Many Requests with these headers:
Retry-After tells you how many seconds to wait before retrying. X-RateLimit-Limit and X-RateLimit-Remaining describe the window, while X-RateLimit-Reset is a reset interval in seconds rather than a Unix timestamp.
These headers are returned on rate-limit errors. Do not rely on receiving them with every successful request.
View response headers
Use curl -i to include response headers when inspecting a request.
Handle throttling
Wait at least the Retry-After interval before retrying, and add a small random delay when multiple workers share an IP. Limit concurrent requests and avoid tight polling loops during node provisioning or updates.
For network failures and other transient errors, use bounded backoff rather than continuously retrying. See Error handling for reconciling requests whose outcome is uncertain.
Phoenixd
Control concurrency in your client and avoid tight polling loops. Use WebSocket for incoming payment notifications, and query payment history to reconcile missed events.
Handle throttling
If your connection endpoint returns 429 Too Many Requests, pause requests and follow Retry-After when present. It tells you how many seconds to wait. Reduce concurrency if requests continue to be throttled.
For network failures and other transient errors, use bounded backoff. Check the outcome of an interrupted payment before sending it again. See Error handling.
Inspect response headers
Use curl -i to include response headers when inspecting a request.
List nodes
List the active nodes in your account. Deleted nodes are excluded.
/nodesRequired permission: Nodes → Read.
Create a node
Start setting up a Phoenixd node in your account.
/nodesRequired permission: Nodes → Write.
Body parameters
requestIdstringRequiredA random 128-bit identifier encoded as 32 hexadecimal characters. Use a new identifier for each creation attempt. Repeating an accepted request returns a conflict.
namestringOptionalDisplay name, up to 16 characters after trimming. Omit it or leave it blank to use a generated name.
autoLiquiditystringRequiredChoose
2m,5mor10mfor automatic liquidity.
The response contains node metadata and one-time credentials: the recovery seed, full-access password and restrictedPassword. Save the credentials in your secret store when this response arrives. Keep them out of logs and conversation output. The node continues launching in the background; use Get a node to check its status before sending payments. If launch fails, discard these credentials and create a new node.
Creation requires sufficient account credit and available capacity. A 402 response means you need to add credit; a 503 node_capacity_unavailable response means capacity is currently full.
Get a node
Return a node's details without its passwords or recovery seed.
/nodes/{nodeId}Required permission: Nodes → Read.
Path parameters
nodeIdstringRequiredID of the node in your account. Use List nodes to find its ID.
Rename a node
Change the display name of a node.
/nodes/{nodeId}Required permission: Nodes → Write.
Path parameters
nodeIdstringRequiredID of the node in your account. Use List nodes to find its ID.
Body parameters
namestringRequiredNew display name for the node. Must be non-blank and contain no more than 16 characters after trimming.
Start a node
Start a stopped or failed node. The node starts in the background.
/nodes/{nodeId}/startRequired permission: Nodes → Write.
Path parameters
nodeIdstringRequiredID of the node in your account. Use List nodes to find its ID.
The node must have status stopped or failed. Other states return 400 Bad Request.
Stop a node
Stop a node while retaining its data.
/nodes/{nodeId}/stopRequired permission: Nodes → Write.
Path parameters
nodeIdstringRequiredID of the node in your account. Use List nodes to find its ID.
The node must have status ready. Its payment API is unavailable while stopped, and incoming requests cannot restart it. Stopping a node does not pause billing.
Restart a node
Stop and start an existing node.
/nodes/{nodeId}/restartRequired permission: Nodes → Write.
Path parameters
nodeIdstringRequiredID of the node in your account. Use List nodes to find its ID.
The node must have status ready. Its payment API is temporarily unavailable during the restart.
Check for an update
Return the current node release and any supported update, using the same availability check as the dashboard.
/nodes/{nodeId}/updateRequired permission: Nodes → Read.
Path parameters
nodeIdstringRequiredID of the node in your account. Use List nodes to find its ID.
Review the target release before submitting its releaseSha256 to Update a node.
availableUpdate is null when there is no supported update. Its version identifies the node release. currentRelease contains the running release identity. currentVersion is the bundle version; currentRelease.phoenixdVersion identifies Phoenixd. The current version may be null while the node is unavailable.
Update a node
Begin the supported node update you have approved. The update continues in the background.
/nodes/{nodeId}/updateRequired permission: Nodes → Write.
Path parameters
nodeIdstringRequiredID of the node in your account. Use List nodes to find its ID.
Use Check for an update first. If availableUpdate is null, there is no update to apply. Otherwise, review that release and send its releaseSha256 in the JSON body. This uses the same update flow as the dashboard. The server checks availability again before accepting the request.
The node must have status ready and an available update. The initial response has status updating; it does not indicate that the update has completed. Node data is retained.
Delete a node
Permanently remove a node.
/nodes/{nodeId}Required permission: Nodes → Write.
Path parameters
nodeIdstringRequiredID of the node in your account. Use List nodes to find its ID.
Reconcile outstanding payments, handle remaining funds, and retain recovery information before deleting. Bearer API-key requests do not require a two-factor code.
Get webhook endpoint
Read the webhook receiver configured for your node.
/nodes/{nodeId}/webhook-endpointRequired permission: nodes:read. See Authentication.
Path parameters
nodeIdstringRequiredID of the node in your account. Find it with List nodes.
Returns { "endpoint": null } if no endpoint is configured. The signing secret is returned only when creating an endpoint.
Create webhook endpoint
Configure your node to deliver payment notifications to your application.
/nodes/{nodeId}/webhook-endpointRequired permission: nodes:write. See Authentication.
Path parameters
nodeIdstringRequiredID of the node in your account. Find it with List nodes.
Body parameters
urlstringRequiredA public HTTPS receiver URL, up to 2048 characters, without embedded credentials.
descriptionstringOptionalOptional description, up to 500 characters after trimming.
Each node supports one endpoint. An existing endpoint returns 409 webhook_endpoint_already_exists. Save the returned signingSecret in your receiver’s secret settings before processing events. See Webhook authentication.
Update webhook endpoint
Change the receiver URL, description or whether delivery is enabled.
/nodes/{nodeId}/webhook-endpointRequired permission: nodes:write. See Authentication.
Path parameters
nodeIdstringRequiredID of the node in your account. Find it with List nodes.
Body parameters
urlstringOptionalA public HTTPS receiver URL, up to 2048 characters, without embedded credentials.
descriptionstringOptionalOptional description, up to 500 characters after trimming.
enabledbooleanOptionalWhether to deliver payment notifications.
Supply at least one field. Omitted fields keep their current values. Use an empty description to clear it. Disabling cancels queued deliveries and stops new notifications. Re-enabling starts delivery for future events.
Delete webhook endpoint
Remove the webhook receiver configured for your node.
/nodes/{nodeId}/webhook-endpointRequired permission: nodes:write. See Authentication.
Path parameters
nodeIdstringRequiredID of the node in your account. Find it with List nodes.
Deleting the endpoint also removes its delivery history. Use Update webhook endpoint to pause delivery or change the URL while keeping the configuration. A missing endpoint returns 404 webhook_endpoint_not_found.
List webhook deliveries
Read the latest 50 deliveries for your node, newest first.
/nodes/{nodeId}/webhook-deliveriesRequired permission: nodes:read. See Authentication.
Path parameters
nodeIdstringRequiredID of the node in your account. Find it with List nodes.
The response wraps records in deliveries. Each record includes id, eventType, payload, status, attemptCount, lastResponseStatus, lastError, createdAt, lastAttemptAt and deliveredAt. See Webhooks for event payload fields.
Use this history to troubleshoot your receiver. Status is pending, retrying, delivered, failed or cancelled. Timestamps use Unix seconds; lastAttemptAt, deliveredAt, lastResponseStatus and lastError may be null.
Attestation
Request fresh evidence of a protected host's boot state and running node bundle before trusting its connection. The response contains an AWS-signed attestation document and the host's TLS certificate. Receiving a successful response does not mean the evidence has been verified; verification happens in your client.
/attestationThis is a Nodana protected-host endpoint. Use your node's normal HTTPS URL, such as https://node-a1b2.nodana.app. Attestation and Phoenixd requests use the same URL on the standard HTTPS port, 443.
Authentication: none. Do not send a Phoenixd password, Nodana API key or Authorization header.
JSON body
noncestringRequiredA cryptographically random 32-byte challenge encoded as standard Base64. Generate a new challenge for every request and retain it to verify the response. Send only this field, with
Content-Type: application/json.
Response
| Field | Type | Description |
|---|---|---|
certificate | string | The protected host's TLS certificate in PEM format. |
attestationDocument | string | The AWS-signed attestation document, encoded as Base64. |
identity | object | The node identity and connection details covered by the proof. |
The document contains boot measurements, a timestamp, your challenge and a signed binding to the certificate, node, owner and bundle identity. Your verifier must check the AWS signature and certificate chain, freshness, challenge, expected identity, approved host measurements and independently approved bundle checksum before trusting the returned certificate or sending credentials.
The identity object contains version (2), hostname, nodeId, nodePublicKey, ownerPublicKey, certificateSha256 and release. Compare its hostname with the URL you requested. If you have saved node or owner public keys, compare those too; an identity supplied by the response alone does not establish that it is your original wallet.
The release object contains releaseSha256, version, phoenixdVersion and stateFormat. Compare releaseSha256 with the canonical manifest checksum you have independently approved. The measured host software checks the installed bundle and running process before reporting this identity.
The signed binding is SHA-256 of nodana-public-tls-v1 followed by a null byte and the canonical JSON encoding of identity (keys sorted, no whitespace). certificateSha256 is the lowercase SHA-256 hex digest of the exact UTF-8 PEM string in certificate. Verify the binding and compare the certificate's leaf with the certificate on your TLS connection.
Keep approved measurements in your client rather than accepting them from the response. Do not trust a certificate merely because it arrived alongside an attestation document. See Security: attestation for what verification establishes.
Errors
| Status | Error | Action |
|---|---|---|
400 | invalid_request | Send a JSON body containing only nonce, without credentials. |
400 | invalid_encoding | Encode exactly 32 random bytes as standard Base64. |
404 | node_not_ready | Check the node ID and wait until the node is ready. |
429 | busy | Wait before requesting new evidence. |
503 | attestation_unavailable | Retry later; connection evidence is unavailable. |
502 | node_unavailable | Retry later; verification has not succeeded. |
Webhooks
Receive an HTTP POST when your Nodana-hosted node receives a payment. Configure one public HTTPS receiver per node to notify your application.
Add your endpoint
- Open your node in the dashboard and select Webhooks.
- Choose Add endpoint and enter your receiver’s public HTTPS URL.
- Copy the signing secret when it is shown and store it in your receiver’s secret settings. It is shown once.
- Keep the endpoint enabled to receive notifications.
You can also create the endpoint through the API using a Nodana key with nodes:write. Read, update or delete it using the same node ID.
Handle a payment
Verify webhook authentication before parsing the request. Match nodeId and paymentHash to your saved payment, then check the amount before fulfilling the order. Use Get incoming payment if you need to look up the invoice or confirm its current state.
| Field | Type | Meaning |
|---|---|---|
id | string | Event identifier |
type | string | payment_received |
nodeId | string | Nodana ID for the receiving node |
paymentHash | string | Payment hash as a hexadecimal string |
amountSat | integer | Amount received in satoshis |
amountMsat | string | Amount received in millisatoshis, encoded as a decimal string |
receivedAt | integer | Time received, in Unix seconds |
payerNote | string | Optional message from the payer |
payerKey | string | Optional public key identifying the payer |
Acknowledge delivery
Return a 2xx response after you have safely recorded the event. Nodana retries failed deliveries, so make processing repeatable: use the event ID or node and payment hash to prevent duplicate fulfilment.
Check recent deliveries or the node’s Webhooks tab when troubleshooting. Confirm that the endpoint is enabled, reachable over HTTPS and returning a successful status. Use incoming payment history to reconcile payments if your receiver was unavailable.
Webhook authentication
Verify the X-Nodana-Signature header before accepting a webhook. Use the signing secret returned when you create the endpoint, or shown when you add it in the dashboard. Store it in your receiver’s secret configuration as NODANA_WEBHOOK_SECRET.
Nodana signs the complete request body with HMAC-SHA256 and sends the signature as a hexadecimal string. Use the entire signing secret as UTF-8 text, including its whsec_ prefix.
Verify a request
- Capture the raw request body before JSON parsing.
- Calculate its HMAC-SHA256 using your endpoint’s signing secret.
- Compare it with
X-Nodana-Signatureusing a constant-time comparison. - Reject a missing or invalid signature. Parse and process the JSON only after verification succeeds.
Use the original request bytes: parsing and reserializing JSON can change the signature. Keep the secret private. If it is lost or exposed, replace the webhook endpoint and configure your receiver with the new signing secret.
After verification, check the node, payment hash and amount against your order, and record fulfilment once. A valid signature does not make a repeated delivery a new payment.
Create BOLT11 invoice
Creates a Bolt11 invoice with a description.
A Bolt11 invoice is a non-reusable, expirable payment request for Lightning, well suited for a retail payment flow. It can only be paid once.
/createinvoiceAuthentication: full or limited Phoenixd password. See Authentication.
Form parameters
descriptionstringOptionalInvoice description, up to 128 characters. Supply either description or descriptionHash.
descriptionHashstringOptionalSHA-256 hash of the description, as an alternative to description.
amountSatintegerOptionalAmount requested in satoshis. Omit to allow the payer to choose the amount.
expirySecondsintegerOptionalInvoice lifetime in seconds. Defaults to 3600 (one hour).
externalIdstringOptionalYour order or payment reference. Use it when looking up incoming invoices.
webhookUrlstringOptionalAdditional callback URL for this invoice, called directly by Phoenixd. Configure Nodana webhooks for notifications delivered by Nodana.
Send parameters as application/x-www-form-urlencoded.
Create BOLT12 offer
Creates a Bolt12 offer with an optional description and amount.
An offer is a static and reusable payment request that does not expire. It can be paid many times. It's well suited for donations or tips.
Note: a getoffer call is also available but it is deprecated. This getoffer endpoint returns an offer, but always the same one. createoffer should be used instead.
/createofferAuthentication: full or limited Phoenixd password. See Authentication.
Form parameters
descriptionstringOptionalOffer description, up to 128 characters. Required when amountSat is provided.
amountSatintegerOptionalAmount requested in satoshis. Omit to allow the payer to choose the amount.
Send parameters as application/x-www-form-urlencoded.
Get Lightning address
Gets a BIP-353 Lightning address from the LSP. Only works if you have a channel.
Note you can also use third-party services or self-host the address.
/getlnaddressAuthentication: full or limited Phoenixd password. See Authentication.
Get swap-in address
Gets an on-chain address to swap on-chain funds into Lightning.
/getswapinaddressAuthentication: full or limited Phoenixd password. See Authentication.
Pay BOLT11 invoice
Pays a BOLT11 Lightning invoice. A 0.4% fee applies. Response includes the internal paymentId for that payment.
/payinvoiceAuthentication: full Phoenixd password. See Authentication.
Form parameters
invoicestringRequiredBOLT11 invoice to pay.
amountSatintegerOptionalAmount in satoshis. If omitted, uses the amount in the payment request. Supply amountSat or sendAll for an amountless request.
sendAllbooleanOptionalSend the wallet balance when there is a single channel. Mutually exclusive with amountSat.
Send parameters as application/x-www-form-urlencoded.
Payment attempts can return HTTP 200 with type: "payment_failed". Check the result before treating the payment as sent. A successful result has type: "payment_sent".
Pay BOLT12 offer
Pays a BOLT12 Lightning offer. A 0.4% fee applies. Response includes the internal paymentId for that payment.
/payofferAuthentication: full Phoenixd password. See Authentication.
Form parameters
offerstringRequiredBOLT12 offer to pay.
amountSatintegerOptionalAmount in satoshis. If omitted, uses the amount in the payment request. Supply amountSat or sendAll for an amountless request.
sendAllbooleanOptionalSend the wallet balance when there is a single channel. Mutually exclusive with amountSat.
messagestringOptionalOptional message for the recipient; the receiving service may restrict its length.
Send parameters as application/x-www-form-urlencoded.
Payment attempts can return HTTP 200 with type: "payment_failed". Check the result before treating the payment as sent. A successful result has type: "payment_sent".
Pay Lightning address
Pays an email-like Lightning address, either based on BIP-353 or LNURL. A 0.4% fee applies. Response includes the internal paymentId for that payment.
/paylnaddressAuthentication: full Phoenixd password. See Authentication.
Form parameters
addressstringRequiredLightning address using BIP-353 or LNURL.
amountSatintegerOptionalAmount in satoshis. Supply amountSat or sendAll; Lightning addresses do not supply a default amount.
sendAllbooleanOptionalSend the wallet balance when there is a single channel. Mutually exclusive with amountSat.
messagestringOptionalOptional message for the recipient; the receiving service may restrict its length.
Send parameters as application/x-www-form-urlencoded.
Payment attempts can return HTTP 200 with type: "payment_failed". Check the result before treating the payment as sent. A successful result has type: "payment_sent".
Pay on-chain
Sends part of your current balance to a Bitcoin address. The spliced channel is not closed and remains active. Returns the transaction id if the splice was successful.
/sendtoaddressAuthentication: full Phoenixd password. See Authentication.
Form parameters
amountSatintegerRequiredAmount to send in satoshis.
addressstringRequiredDestination Bitcoin address.
feerateSatByteintegerRequiredFee rate in satoshis per virtual byte.
Send parameters as application/x-www-form-urlencoded.
The response is plain text. Check that it contains a transaction ID: an unsuccessful action can return an explanatory message with HTTP 200.
Bump fee
Makes all your unconfirmed transactions use a higher fee rate, using CPFP. Returns the ID of the child transaction.
/bumpfeeAuthentication: full Phoenixd password. See Authentication.
Form parameters
feerateSatByteintegerRequiredFee rate in satoshis per virtual byte.
Send parameters as application/x-www-form-urlencoded.
The response is plain text. Check that it contains a transaction ID: an unsuccessful action can return an explanatory message with HTTP 200.
List incoming payments
Lists incoming payments.
/payments/incomingAuthentication: full or limited Phoenixd password. See Authentication.
Query parameters
fromintegerOptionalStart time in Unix milliseconds. Defaults to 0.
tointegerOptionalEnd time in Unix milliseconds. Defaults to now.
limitintegerOptionalNumber of payments to return. Defaults to 20.
offsetintegerOptionalPagination offset. Defaults to 0.
allbooleanOptionalInclude unpaid invoices.
externalIdstringOptionalOnly return payments with this external ID.
Get incoming payment
Look up an incoming payment by its payment hash. Check isPaid and receivedSat before fulfilling an order. isExpired indicates that an unpaid invoice can no longer be paid.
/payments/incoming/{paymentHash}Authentication: full or limited Phoenixd password. See Authentication.
Path parameters
paymentHashstringRequiredPayment hash as a hexadecimal string.
List outgoing payments
Lists outgoing payments.
/payments/outgoingAuthentication: full or limited Phoenixd password. See Authentication.
Query parameters
fromintegerOptionalStart time in Unix milliseconds. Defaults to 0.
tointegerOptionalEnd time in Unix milliseconds. Defaults to now.
limitintegerOptionalNumber of payments to return. Defaults to 20.
offsetintegerOptionalPagination offset. Defaults to 0.
allbooleanOptionalInclude failed payments.
Get outgoing payment
Look up an outgoing payment by its internal payment ID or payment hash. Use the ID returned by the payment request. Check isPaid and completedAt when reconciling an interrupted request.
/payments/outgoing/{paymentId}/payments/outgoingbyhash/{paymentHash}Authentication: full or limited Phoenixd password. See Authentication.
Path parameters
paymentIdstringRequiredInternal payment UUID.
paymentHashstringOptionalPayment hash for the alternative outgoingbyhash route.
For outgoing Lightning payments, isPaid: true with completedAt indicates success. isPaid: false with no completedAt is pending; isPaid: false with completedAt indicates failure.
CSV export
Exports your successful payments history in a CSV file. Returns the path of the generated file on your file system.
The resulting CSV allows precise tracking of the balance and fee credit, and shows the split between mining and service fees:
-
balance: sum of all
amount_msat; -
fee credit: sum of all
fee_credit_msat.
The returned path is on the machine or container running Phoenixd. Retrieve the file there; the response body is a message containing its path.
/exportAuthentication: full or limited Phoenixd password. See Authentication.
Query parameters
fromintegerOptionalStart time in Unix milliseconds. Defaults to 0.
tointegerOptionalEnd time in Unix milliseconds. Defaults to now.
Get node info
Read the Lightning node ID and a compact summary of its channels. Channel balances, inbound liquidity and capacity are expressed in satoshis.
/getinfoAuthentication: full or limited Phoenixd password. See Authentication.
Get balance
Read the available balance and fee credit, both in satoshis.
/getbalanceAuthentication: full or limited Phoenixd password. See Authentication.
List channels
Read detailed channel state. For a compact channel summary, use Get node info. The example shows an excerpt; available fields depend on channel state.
/listchannelsAuthentication: full or limited Phoenixd password. See Authentication.
Close channel
Closes a given channel, and send all funds to an on-chain address. Returns the ID of the closing transaction.
Attention: closing a channel is final, it cannot be cancelled.
/closechannelAuthentication: full Phoenixd password. See Authentication.
Form parameters
channelIdstringRequiredID of the channel to close.
addressstringRequiredBitcoin address to receive the channel balance.
feerateSatByteintegerRequiredFee rate in satoshis per virtual byte.
Send parameters as application/x-www-form-urlencoded.
The response is plain text. An unsuccessful action can return an explanatory message with HTTP 200; confirm the closing transaction ID before reporting success.
Decode invoice
/decodeinvoiceAuthentication: full or limited Phoenixd password. See Authentication.
Form parameters
invoicestringRequiredBOLT11 invoice to decode.
Send parameters as application/x-www-form-urlencoded.
Decode offer
/decodeofferAuthentication: full or limited Phoenixd password. See Authentication.
Form parameters
offerstringRequiredBOLT12 offer to decode.
Send parameters as application/x-www-form-urlencoded.
Estimate liquidity fees
Estimates a liquidity fee for a given amount. Note that it depends on the current mining feerate, which is volatile. The estimate returned is the full cost and does not take into account any fee credit you may have.
/estimateliquidityfeesAuthentication: full or limited Phoenixd password. See Authentication.
Query parameters
amountSatintegerRequiredLiquidity amount in satoshis.
LNURL Pay
Pays a LNURL-pay resource. Note that the service may apply restrictions on the amount to pay or the message -- the lnurl-pay flow is usually interactive.
/lnurlpayAuthentication: full Phoenixd password. See Authentication.
Form parameters
lnurlstringRequiredLNURL-pay resource.
amountSatintegerOptionalAmount to pay in satoshis. If omitted with sendAll unset, uses the minimum accepted by the service.
sendAllbooleanOptionalSend the wallet balance when there is a single channel. Mutually exclusive with amountSat.
messagestringOptionalOptional message for the recipient; the receiving service may restrict its length.
Send parameters as application/x-www-form-urlencoded.
Payment attempts can return type: "payment_failed" with HTTP 200. Check the returned type and reconcile uncertain attempts using Get outgoing payment.
LNURL Withdraw
Withdraws funds from a LNURL service. Phoenixd will withdraw the maximum amount authorized by the service.
/lnurlwithdrawAuthentication: full or limited Phoenixd password. See Authentication.
Form parameters
lnurlstringRequiredLNURL-withdraw resource.
Send parameters as application/x-www-form-urlencoded.
LNURL Auth
Authenticates a LNURL-auth resource to allow an action on a remote service. See LUD-04 for details.
Note: The key used to sign is derived from the wallet's key (derivation depends on the lnurl service's domain). If you have different users using the same phoenixd instance, do not let them use this or they will share the same signature and pubkey!
/lnurlauthAuthentication: full Phoenixd password. See Authentication.
Form parameters
lnurlstringRequiredLNURL-auth resource.
Send parameters as application/x-www-form-urlencoded.
WebSocket
WS /websocket
Subscribe to received-payment events. Use the full or limited Phoenixd password. For an HTTPS node URL, connect with wss://; a daemon on the same machine uses ws://127.0.0.1:9740/websocket.
Authentication
Phoenixd accepts Basic authentication on the WebSocket handshake or authentication through Sec-WebSocket-Protocol. The example uses a server-side client with Basic authentication and an empty username. Keep the password on your backend.
Events
Each JSON message has type: "payment_received", the payment hash and the amount in satoshis. Events can include externalId for an invoice or payerKey and payerNote for an offer. Match the payment hash or external ID to your saved order.
After reconnecting, use incoming payment history to reconcile receipts. Confirm the payment and expected amount before fulfilment, and record fulfilment once for each order.