L402 API
Integrate sms4sats with L402 payment challenges, macaroons, and Lightning preimages.
L402 combines a Lightning invoice with a resource-scoped macaroon. It is designed for AI agents and services that can pay invoices and retrieve payment preimages programmatically.
Discovery
curl -sS https://api.sms4sats.com/v2/l402
curl -sS https://api.sms4sats.com/v2/l402/services
curl -sS https://api.sms4sats.com/v2/l402/catalogGET /v2/l402/services
{ "services": [{ "code", "name" }] }
GET /v2/l402/catalog
{ "items": [...], "updatedAt": "..." }
The catalog is a cached snapshot of receive-SMS and reactivation offers and may be empty. Order creation can use cached catalog data, live provider data, or a fallback quote when configured. Provider allocation after payment is the definitive inventory check; a paid receive-SMS allocation failure follows the refund flow.
Create an order
POST /v2/l402/order
Order types
{
"type": "receive-sms",
"country": "auto",
"service": "tg",
"refundInvoice": "lnbc1..."
}refundInvoice is required. It must be a valid no-amount BOLT11 invoice with at least 30 minutes of validity remaining when the order is created. That is only the validation floor: choose an invoice whose expiry covers payment delay, the full fulfillment timeout, and routing headroom. If it expires before a refund is attempted, the order can end in refund_failed.
{
"type": "receive-sms-reactivate",
"country": "US",
"service": "tg",
"refundInvoice": "lnbc1...",
"reactivationOfActivationId": "123456789"
}reactivationOfActivationId is required and may be a string or number. Reactivation uses the same required refund-invoice flow as a one-time receive-SMS order. Availability depends on the original provider activation ID.
{
"type": "rent-number",
"country": "US",
"service": "tg",
"durationMinutes": 120
}Do not send refundInvoice for a rental. Once its L402 invoice is paid, the rental has no refund flow, including if allocation fails.
country and service are required strings of 1–64 characters. Country accepts auto, numeric provider ID, ISO alpha-2 code, or recognized English name. Service accepts a code from /v2/l402/services or a recognized name; other maps to ot. Rental durationMinutes, when supplied, must be a positive integer. It defaults to 120 minutes; pricing and allocation use a two-hour minimum and round upward to a whole hour.
A paid L402 rental has no refund path, including if provider allocation fails. Use current discovery data and accept this risk before paying a rental invoice.
Payment challenge
Creation returns HTTP 402 Payment Required and a WWW-Authenticate header.
Pay invoice, retrieve its 32-byte preimage, and retain all three credentials: orderId, macaroon, and the preimage. The macaroon carries an expires_at caveat (currently 3,600 seconds after creation) and has no refresh route. Polling and cancellation fail with EXPIRED_MACAROON after that deadline.
L402 creation does not accept an idempotency key. Do not blindly repeat POST /v2/l402/order after an ambiguous network response; each successful creation can issue a separate invoice. Preserve the first successful challenge response and poll its orderId.
Authenticate and poll
GET /v2/l402/order/{orderId}
The first valid authenticated request proves payment, marks the order paid, and starts allocation. Poll every 5–10 seconds. The response includes order state, assigned phoneNumber, timestamps, and messages when available.
The macaroon and preimage together authorize the order. Treat the complete Authorization value as a secret and never log or expose it.
Cancel and refund
POST /v2/l402/order/{orderId}/cancel
Use the same L402 authorization header. Cancellation is available for paid receive-sms and receive-sms-reactivate orders at least three minutes after payment and before any SMS arrives. Rentals cannot use this cancellation flow. sms4sats cancels the provider activation before paying the no-amount refundInvoice.
Refund amount is calculated conservatively so the refund plus a routing-fee allowance fits within the received payment. The returned amount can therefore be slightly lower than priceSats.
Orders without an SMS automatically follow the same cancel-then-refund safety flow when they time out. Do not assume a timeout or network error is final—poll the existing order.
Last updated