- Create payments (invoices) and receive a unique deposit address per payment.
- Check payment status (waiting → confirming → finished/expired…).
- Read balances and ledger history.
- Issue refunds (opt-in, elevated scope).
- Convert between currencies, and read wallets, currencies and more.
Base URL
All requests go tohttps://api.liddie.io:
cURL
/api/v1/.... A handful of payer-facing public endpoints sit at the root (e.g. GET /getInvoiceStatus) — they return redacted data only and reject raw payment ids.
GET /health and GET /ready are availability probes: auth-free and rate-limit-exempt.
The two hosts you will use
invoiceUrl is a relative path (/i/<slug>). Prepend the checkout host, not the API host — see the table below.
So a payer link is built as
https://dash.liddie.io + invoiceUrl. If you send a payer to https://api.liddie.io/i/<slug> by mistake they are redirected to the checkout host, but build the link correctly and skip the extra hop.
Credentials
Three credential types, three jobs. Pick the one that matches who is calling.Secret API key
lid_live_... — for server-to-server integrations.Dashboard session
For humans in the browser.
Publishable key
pk_live_... — for embeddable widgets only.Secret API key — for server-to-server integrations
- Created in the dashboard (Settings → API Keys) or via Create an API key — that requires a dashboard session plus MFA, so you cannot mint keys with another key.
- Sent as a Bearer token in the
Authorizationheader, as in the example above. - Optional per-key IP whitelist and expiry (
expiresInDays, 1–3650). - A key carries an explicit list of scopes (permissions). A request to an endpoint whose scope the key lacks fails with
403 {"error":"Insufficient API key permissions"}.
All scopes and what they grant
All scopes and what they grant
refunds:manage cannot mint a refunds:create key.
Dashboard session — for humans in the browser
- Obtained by logging in. The session uses secure httpOnly cookies: an access token (15 min) and a refresh token (7 days). The access token is also accepted as
Authorization: Bearer <token>. - A session carries a role:
merchant_admin(owner) ormerchant_member. Members are additionally bounded by a per-user team-permission set (e.g.payments:view,refunds:manage). - Sensitive actions (creating API keys, refunds, withdrawals, whitelist changes) additionally require a fresh MFA factor per call: passkey, TOTP code, or emailed code.
Publishable key — for embeddable widgets only
- Public by design — safe to ship in front-end code. It can only create widget payments (Payment/Donation buttons), gated by each widget’s origin allowlist and rate limits. It can read nothing.
- Retrieved and rotated from the dashboard — see Get publishable key.
How auth failures look
How auth failures look
Conventions
A few rules of thumb that apply across the whole API.Response envelopes
- Older v1 routes: plain object on success,
{"error":"<message>"}on failure. - Newer v1 routes: the standard envelope
{"ok":true,"data":...}on success,{"ok":false,"error":{"code":"UPPER_SNAKE","message":"..."}}on failure. - List routes:
{ items: [...], total }— check each endpoint’s documented shape.
Money
Payment creation takes a fiat amount (your display currency, USD by default).POST /api/v1/payments {"currency":"DOGE","amount":75} means “charge $75, payable in DOGE” — the response quotes the crypto quantity (amount: 1049.29 DOGE).
Amounts travel as JSON numbers in the Payment family and as decimal strings in the ledger/withdrawal/refund family. Each endpoint’s doc states which. Never parse money into floats for arithmetic on your side; keep the string form where provided.
Idempotency
Create a payment and Create a refund accept anIdempotency-Key HTTP header (1–255 printable ASCII characters, no spaces). Retrying with the same key returns the original resource instead of creating a duplicate.
Always send one from job and retry pipelines — especially on refunds: a duplicate refund would move real funds twice, and the key prevents that.
Rate limits
- Global: 60 requests/minute, bucketed per IP for API-key,
/auth/*and unauthenticated traffic, and per user only for cookie-authenticated dashboard sessions. Several keys — or several servers — behind one egress IP share a single bucket, so size your concurrency accordingly. Exceeding it returns429. - Per-route overrides (stricter) exist on sensitive endpoints: refund create 10/min, AML screen 10/min, API-key mint 5/min, cross-chain accept 20/min.
- On
429, back off exponentially and retry after the window.
IDs
Resources use 24-hex string ids. A malformed id returns400 {"error":"Invalid ID format"}. A resource belonging to another merchant reads as 404 (never 403) — the API does not reveal whether a foreign resource exists.
Capability matrix: what an API key can and cannot do
With a secret API key you CAN (given the right scopes)
With a secret API key you CAN (given the right scopes)
- Create, list, read, cancel payments; read status counts; re-run AML screening.
- Accept a wrong-currency/overpaid (cross-chain) deposit on your own payment.
- Read currencies, wallets, ledger balances, conversion data.
- Execute conversions (
conversions:execute). - Issue and poll refunds (
refunds:create/refunds:read).
With a secret API key you CANNOT (dashboard only)
With a secret API key you CANNOT (dashboard only)
- Create, list, or revoke API keys (requires a dashboard session plus MFA).
- Request withdrawals, mass payouts, or manage the withdrawal whitelist (dashboard + fresh MFA per action).
- Manage team members, settings, webhook endpoints, notifications, support tickets.
jwtAuth runs first and rejects it as an unparseable token with 401 {"error":"Invalid or expired token"}.Where everything lives
Guides: Route map (every endpoint at a glance) · Webhooks & IPN (signatures, event catalog) · Authentication (dashboard login, 2FA, passkeys). The API Reference has one page per endpoint, grouped in the sidebar:Create a payment
Start integrating in five minutes.
Webhooks & IPN
Get told when you were paid instead of polling.
Route map
Every endpoint you can call, at a glance.