Base URL https://altradits.com/api/dev/v1. JSON in, JSON out. This page restates the OpenAPI 3.1 contract in the repo.
Authorization: Bearer <token>. The token is a dashboard session or an API key. Keys start with ak_live_ or ak_test_. A test key serves only the sandbox. A live key serves only live. Sessions manage the account and read everything, flagged per environment. Invoice creation always needs a key.
Every reply carries requestId. Quote it when asking for help. Failures look like this:
{"ok": false, "requestId": "9f2c…", "code": "insufficient_credits",
"error": "This invoice needs 2 sats of fee credit and the balance holds 0. Top up first."}
| Code | Status | Meaning |
|---|---|---|
api_off, sandbox_off | 501 | That environment is not switched on. |
bad_email, email_typo, bad_code | 400, 422, 400/429 | Signup code problems. The typo reply names the likely address. |
unauthorized, invalid_key, key_revoked | 401 | Sign in again, or the key is unknown or revoked. |
suspended, forbidden_scope, bad_scope | 403, 403, 400 | Suspended account, missing scope, unknown scope. |
unknown_key, unknown_destination, unknown_invoice, unknown_webhook, unknown_topup, not_found | 404 | Unknown id. Cross-environment lookups also answer 404. |
destination_unverified, challenge_unpaid, duplicate_destination | 409 | Finish the ownership proof first, or the address is taken. |
challenge_expired | 410 | Register again for a fresh challenge. |
bad_amount, bad_currency, amount_out_of_range, bad_address, address_mismatch, bad_webhook_url, bad_webhook_events, idempotency_conflict, sandbox_address_only, sandbox_only | 422 | The request was understood but refused. The sentence says why. |
rate_limited | 429 | Past a limit. Wait and retry. |
insufficient_credits | 402 | The fee balance can't cover this invoice. Top up first. |
address_unreachable, invoice_mismatch, invoice_untracked, verify_unreachable | 502 | The destination failed or answered wrong. Nothing was paid. |
node_offline, rate_unavailable, lockdown_freeze, account_busy | 503 | Try again later. Lockdown freezes new invoices and top-ups only. |
bad_version | 404 | Unknown API version. The current version is v1. |
List endpoints take limit (1 to 200, default 50) and cursor. The reply carries nextCursor: pass it as cursor for the next page, newest first.
Invoice and top-up creation accept Idempotency-Key. The same key replays the first reply for 24 hours (deduplicated: true). The same key with different details answers 422.
100 invoices an hour per key. 2,000 invoices and 20 top-ups a day per account. 5 signup codes an hour per address. Webhook and settlement polling are capped per invoice and per connection. Past a limit, 429.
/health LiveAlways answers. Names whether the API and the sandbox are on. No authentication.
{"ok": true, "requestId": "…", "version": "v1", "api": "on", "sandbox": "on"}
/accounts/request-code LiveEmails a one-time 8 digit code, good for 10 minutes. Body: {"email", "confirmTypo?"}. Never reveals whether an address is registered.
/accounts/verify-code LiveVerifies the code. Creates the account on first use. Returns the account and a session token, good for 30 days. Body: {"email", "code"}.
/accounts/me LiveThe signed-in account. Session only.
/accounts/sign-out LiveEnds this session at once. Session only.
Session only. Scopes: invoices:create, invoices:read, webhooks. Secrets are shown once and never again.
/keys LiveEvery key, newest first. Public halves only.
/keys LiveBody: {"name?", "scopes?", "sandbox?"}. Scopes default to all three. sandbox: true makes a test key.
/keys/{id}/rotate LiveRevokes the key and returns its replacement, shown once.
/keys/{id}/revoke LiveRevokes the key at once. The record is kept.
Session only. Live: your own Lightning address, proven by a 1 sat challenge payment. Sandbox: only the built-in simulator dev@sandbox.altradits.com, verified at once with no payment.
/destinations LiveEvery registered address on the account.
/destinations LiveBody: {"address", "sandbox?"}. Live returns the destination plus the 1 sat challenge invoice. The address must resolve and name itself. Sandbox returns the verified simulator with challenge: null.
/destinations/{id}/prove LiveAfter the challenge is paid. Checks settlement and re-binds the address, then marks it verified.
Creation needs a key with invoices:create. Reads take a key with invoices:read or a session. A key sees only its own environment.
/invoices LiveFetches your destination's own invoice for exactly the amount, checks it, and tracks it. Body: {"destinationId", "sats?" | "fiat?", "memo?"}. Fiat: {"amount", "currency"}, USD or KES, converted at the live rate and recorded. At most 100,000,000 sats. Frozen in a lockdown (503). Needs its fee covered (402). Accepts Idempotency-Key.
POST /api/dev/v1/invoices {"destinationId": "K7…", "sats": 5000, "memo": "order 123"} 201, or 200 with "deduplicated": true on an Idempotency-Key replay {"ok": true, "requestId": "…", "invoice": { "id": "…", "address": "you@wallet.com", "sats": 5000, "bolt11": "lnbc50u1…", "paymentHash": "…", "status": "pending", "verifySupported": true, "createdAt": "…", "settledAt": null }}
/invoices?limit&cursor LiveYour invoices, newest first. Paginated.
/invoices/{id} LiveThe invoice, with a live settlement check when the destination supports verify. Without verify support, the invoice stays pending and the reply carries a note saying to confirm in your wallet.
/verify/{hash} LiveSettlement by payment hash (64 hex characters). Same live check as invoice status.
Key with the webhooks scope, or a session. A key sees only its own environment. Endpoints are never deleted, only disabled. The delivery log is kept.
/webhooks LiveBody: {"url", "events?", "sandbox?"}. The URL must be https on a public host. Events default to ["invoice.settled"]. Returns the endpoint plus the secret, shown once.
/webhooks LiveEvery endpoint on the account. Secrets are never listed.
/webhooks/{id}/disable LiveStops new deliveries at once.
/webhooks/{id}/deliveries?limit&cursor LiveEvery delivery, newest first, with each attempt. Paginated.
POST to your URL on every settlement
{"event": "invoice.settled", "invoice": {…}, "deliveredAt": "…"}
Session, or a key (invoices:create to top up, invoices:read to read). Top-ups are live only, 100 sats minimum, invoiced from Stanley's node. Fees deduct 0.5% rounded up, minimum 1 sat, when an invoice settles. Credits are non-refundable, except on account close: unused live balance pays out to a verified destination within 7 days.
/topups LiveBody: {"sats"}. Returns the node invoice. Pay it, then poll the top-up. Frozen in a lockdown (503). Accepts Idempotency-Key.
/topups?limit&cursor LiveYour top-ups, newest first. Paginated.
/topups/{id} LiveThe top-up, with a live check that credits the balance when paid. Crediting stays on during a lockdown.
/balance LiveThe prepaid balance: {"live", "test"} in sats.
/statement LiveBalance, per-environment totals (live and test: toppedUp, feesPaid, settledVolume, settledCount, shortfall), and the ledger: every top-up, fee and grant, newest first. Paginated. Only live fees are real sats.
Test keys and the simulator. Free. Works while mainnet is off. The sandbox never touches the network or the node.
/sandbox/settle Sandbox onlyBody: {"invoiceId"}. Plays the customer paying a sandbox invoice. Needs a test key with invoices:create, or a session. Live invoices are refused. Simulator invoices use signet encoding (lntb…), so a real wallet refuses them.
Every delivery carries X-Dev-Signature: t=<unix seconds>,v1=<hex>, where v1 is HMAC-SHA256(secret, "<t>.<raw body>"). Check the timestamp is within 5 minutes. Compare in constant time. Failures retry after 1 minute, 5 minutes, 30 minutes, 2 hours and 12 hours. Then the delivery is marked dead.
Node.js verification
import crypto from "node:crypto";
const [t, v1] = sig.split(",").map((p) => p.split("=")[1]);
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) throw new Error("stale");
const expect = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expect))) throw new Error("bad signature");
| Version | Added |
|---|---|
| 1.0.0 | Accounts, keys, destinations. |
| 1.1.0 | Invoices, verify by hash, webhooks. |
| 1.2.0 | Top-ups, balance, statement. Fee gate on new invoices. |
| 1.3.0 | Sandbox simulator. |
| 1.4.0 | Sessions may read invoices. |