Skip to main content
Liddie is a crypto payment gateway. Its API lets your own software take payments, watch them settle, and move money — everything else happens in the dashboard. With the API you can:
  • 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.
Everything else — managing API keys, withdrawals, team members, settings — happens in the dashboard (a logged-in browser session), not with an API key. The capability matrix below has the full picture.

Base URL

All requests go to https://api.liddie.io:
cURL
The modern API lives under /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 Authorization header, 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"}.
Only a secure hash of the key is stored. The raw key is shown exactly once at creation and can never be recovered — store it in a secrets manager.
Anti-escalation rule: a team member (non-owner) minting a key can only put scopes on it that their own team role already grants. For example, a member without 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) or merchant_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.

Conventions

A few rules of thumb that apply across the whole API.

Response envelopes

  1. Older v1 routes: plain object on success, {"error":"<message>"} on failure.
  2. Newer v1 routes: the standard envelope {"ok":true,"data":...} on success, {"ok":false,"error":{"code":"UPPER_SNAKE","message":"..."}} on failure.
  3. 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 an Idempotency-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 returns 429.
  • 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 returns 400 {"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

  • 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).
  • 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.
Dashboard-only routes never see the key as a credential: 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.