SatLane
Documentation

Error codes

Errors

All errors return the same shape:

JSON
{
  "error": {
    "code": "no_active_xpub",
    "message": "Store has no active xpub for this environment...",
    "request_id": "b9fc7e29-587f-4dda-b220-86d7144893fe"
  }
}

Include the request_id when contacting support. It correlates to our server logs.

Errors POST /v1/invoices can return

401 authentication

CodeWhen
api_key_invalidMissing Authorization header, malformed, or the key does not exist. Use Authorization: Bearer sl_live_… or sl_test_….
api_key_revokedKey was revoked from the dashboard or by an admin. Mint a new one.
api_key_wrong_envCalling a live store with a test key, or vice versa. Use the key that matches the store's mode.

403 authenticated but blocked

CodeWhen
auth_account_suspendedVendor account suspended by an admin. No invoice creation until reinstated.

402 payment required (billing lock)

CodeWhen
billing_overdueLive invoicing locked: unpaid plan invoice, exhausted trial, or suspended subscription. Pay or choose a plan at /billing.

404 resource missing

CodeWhen
not_found (Store)The store the API key belongs to was archived. Restore it or use a different store.

409 conflict / not configured

CodeWhenResolution
no_active_xpubStore has no active xpub for this environment. Live invoices need a mainnet xpub; test invoices need any active xpub.Add an xpub at app.satlane.com/stores/<id>/xpubs.
gap_limit_exceededWallet's gap limit is within 5 of being reached and we have not seen recent funding.Bump the gap limit in Electrum (recommend 100+) or rotate xpubs.
idempotency_conflictThe same Idempotency-Key was reused with a different request body.Reuse the key with the original body (cached response) or generate a new key.

400 validation

CodeCause
validation_errorZod rejected the body. Common: missing both (amount + currency) and amount_sats, providing both, expires_in_minutes outside [5, 120], invalid callback_url, metadata value > 255 chars. The message names the field.
validation_errorIdempotency-Key header > 255 chars or empty.
invalid_currencyCurrency code not supported (only USD today).
invalid_amountSats amount ≤ 0, or fiat amount rounds to zero sats at the current rate.

429 rate limited

CodeWhenResolution
rate_limitedMore than 100 invoice creations per minute on one API key.Back off using retry_after_seconds.

503 temporary infrastructure (retry safe)

These mean the call would have succeeded without an infra condition. Retry with exponential backoff.

CodeWhen
chain_syncingBitcoin node is in initial block download. We refuse new invoices against a stale tip.
disk_fullHost critically low on disk. Writes blocked to protect webhook delivery state.
database_unavailablePostgres unreachable. Rare.

Recommended client retry policy

HTTPAction
200 / 201Use the response.
400, 401, 402, 403, 404, 409Stop. Caller bugs, billing lock, or configuration errors. Log and surface to the user.
429Back off using retry_after_seconds, then retry.
503Exponential backoff (1s → 2s → 4s → 8s → 16s, max 5 tries).
Other 5xxTreat as a bug on our side. Log request_id, escalate.

Always send an Idempotency-Key when retrying creates. We cache the response for 24 hours per key.

Errors from other endpoints

A non-exhaustive selection:

  • auth_required (401): session cookie missing on dashboard endpoints
  • auth_totp_required (401): 2FA-gated endpoint; prompt for code and call /v1/auth/totp/verify
  • auth_email_not_verified (403): vendor email not yet verified
  • invoice_not_cancellable (409): invoice already paid / late_paid / cancelled / expired
  • invoice_expired (410): payment flow hit a fully-expired invoice
  • invoice_already_paid (409): duplicate paid transition attempt
  • not_found: UUID does not match anything you own
  • gone (410): resource intentionally removed