L402 API
Pay with Bitcoin, get AI results. Copy-paste the commands below.
Choose a service:
Before You Start
Want to try this without a terminal? Use Receive Fax on the web — pay with any Lightning wallet, no setup needed.
L402 Fax Receiving API
Open a 24h window to receive a fax at our shared number +1 320 299 1523. When a fax arrives matching the caller ID you specified, we email the PDF to you (plus OCR text file if requested).
Endpoint: https://sats4ai.com/api/l402/receive-fax
Step 1 — Request invoice
curl -X POST https://sats4ai.com/api/l402/receive-fax \
-H "Content-Type: application/json" \
-d '{"email":"you@example.com","from_number":"+15551234567","ocr":true}' \
-iStep 2 — Pay the Lightning invoice
500 sats base, 700 sats if OCR is enabled.
Step 3 — Replay with auth
curl -X POST https://sats4ai.com/api/l402/receive-fax \
-H "Content-Type: application/json" \
-H "Authorization: L402 <MACAROON>:<PREIMAGE>" \
-d '{"email":"you@example.com","from_number":"+15551234567","ocr":true}'Success response:
{
"status": "active",
"subscription_id": 42,
"from_number": "+15551234567",
"email": "you@example.com",
"ocr": true,
"expires_at": "2026-04-20T12:00:00.000Z",
"forward_to_number": "+13202991523"
}Parameters
email: string
Address to deliver the received fax to.
from_number: string
Expected sender fax number in E.164. Matching is by last 10 digits of caller ID (handles most international formatting differences). First-come-first-served per from-number during the 24h window.
ocr: boolean (default: false)
Add +200 sats to include OCR text extraction. The delivery email attaches both the PDF and a fax-ocr.txt with extracted text (useful for feeding to agents or searching). If OCR fails, an LNURL-withdraw for 200 sats is included in the email so the customer can claim a partial refund.
callback_url, callback_id: strings (optional)
Public HTTPS URL we POST when the fax is delivered. Private / loopback / RFC1918 URLs are rejected (SSRF protection). callback_id is an opaque correlation string (max 128 chars) we echo back in the body.
The purchase response includes a callback_secret. This is the ONLY time we return it — save it to verify future callbacks.
Webhook verification (Node.js):
import { createHmac, timingSafeEqual } from "crypto";
// body = raw request body as Buffer (NOT parsed JSON)
function verifyFaxWebhook(rawBody, headers, secret) {
const expected = "sha256=" + createHmac("sha256", secret).update(rawBody).digest("hex");
const received = headers["x-sats4ai-signature"] || "";
try {
return received.length === expected.length &&
timingSafeEqual(Buffer.from(expected), Buffer.from(received));
} catch { return false; }
}On delivery we POST to your URL with Content-Type: application/json, User-Agent: Sats4AI-Webhook/1.0, and X-Sats4AI-Signature: sha256=<hex>. The body is JSON:
{
"subscription_id": 42,
"callback_id": "your-correlation-string",
"timestamp": "2026-04-19T05:12:00.000Z",
"status": "delivered",
"from_number": "+15551234567",
"pages": 3,
"fax_id": "fax_xyz",
"ocr": true,
"ocr_failed": false
}Best-effort, 10s timeout, no retries. Polling the subscription / email remains the source of truth.
Behavior
- Subscription is consumed on first matching delivery. Subsequent faxes from the same sender during the window are dropped silently.
- Faxes over 10 pages trigger an overage invoice emailed separately (+50 sats/page, +20 sats/page OCR). PDF held 7 days pending payment.
- If Telnyx reports transmission failure, window auto-extends by 8h (max 2 extensions).
- No refund if no fax arrives within the window — prevents subscription squatting.
- Caller-ID spoofing risk acknowledged: if the sender misdials, a fax not intended for you may be forwarded. Use only with trusted senders or for faxes you would be comfortable seeing misdirected.