Developers

API reference

Accept BTC, LTC, ETH, SOL, major EVM chains, TRX, TON, and USDT/USDC with a few REST calls. JSON in, JSON out — no SDK required.

Base URLhttps://swp.gg/api/v1
Version1.0.0
Response envelope

Every response is wrapped in the same envelope. On success, data carries the result. On error, data is empty and error.code describes what went wrong.

Envelope shape
{
  "data":    { },
  "message": "Operation completed successfully!",
  "error":   { },
  "status":  200,
  "version": "1.0.0"
}

Authentication

Bearer token

Every request (except public endpoints) requires your merchant API key as a Bearer token. Create keys in the dashboard under API Keys. Per-merchant coin acceptance and checkout pricing live under Payments settings.

Header
Authorization: Bearer swp_live_...

API keys are scoped per-merchant. Endpoints marked No auth required are public and do not need a key.

Endpoints

Payments

Invoice creation and payment lifecycle

POST/invoice

Generate Invoice

Create a hosted-checkout invoice. Redirect your customer to payment_url so they can select their preferred coin and pay. Poll the returned track_id via GET /invoice/{track_id} to check status, or use callback_url for push notifications.

Request body
FieldTypeDescription
amountrequirednumberPayment amount in USD. The `currency` field is display/reference only at launch — `amount` is always interpreted as USD.
currencystringDisplay/reference only at launch. `amount` is always treated as USD.
lifetimeintegerInvoice expiry in minutes from creation. After `expired_at`, status becomes `expired` (poll or `?refresh=1` to materialize). Late chain deposits may still credit the merchant balance.
fee_paid_by_payer"0" | "1"`1` = when the payer selects a coin, inflate `pay_amount` so they cover the merchant's platform deposit fee; settlement still takes the fee cut, so the merchant nets ~full invoice USD. `0` (default) = fee is deducted from the merchant credit only.
under_paid_coveragenumberMax underpayment still accepted as paid, as a percentage of the due crypto amount (combined with platform accuracy settings).
to_currencystringOptional target asset for auto-convert after payment (e.g. `USDT`, `USDC_ETH`). Applies when the merchant account has auto-convert enabled in dashboard Payments settings; otherwise ignored. After settlement, net credit is auto-converted via ChangeNOW on-chain swap when supported, or ledger convert on the same network.
auto_withdrawalbooleanReserved — not applied. Auto-forward on payment is not implemented; use payouts separately.
mixed_paymentbooleanReserved — not applied. Multi-coin remainder payments are not supported.
callback_urlstringWebhook URL for payment status updates (see Webhooks). Must be a public `https://` URL in production; private/reserved hosts are rejected with **400** `INVALID_CALLBACK`.
return_urlstringRedirect URL after successful payment on the hosted checkout. When omitted, uses the merchant default from dashboard **Payments settings → After payment**. Per-invoice value overrides the default.
emailstringCustomer email stored on the invoice (receipts if enabled).
order_idstringYour internal order reference (echoed in webhooks and GET invoice).
thanks_messagestringMessage shown to customer after successful payment.
descriptionstringOrder details shown in reports and on the payment page.
sandboxbooleanReserved — not applied. There is no separate sandbox ledger; omit this field.
cURL
curl -X POST "https://swp.gg/api/v1/invoice" \
  -H "Authorization: Bearer swp_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 49.99,
    "currency": "USD",
    "lifetime": 60,
    "order_id": "order-1001",
    "fee_paid_by_payer": 1,
    "under_paid_coverage": 5,
    "callback_url": "https://example.com/webhook/swp",
    "return_url": "https://example.com/order/1001/thank-you",
    "description": "2× Pro licence"
  }'
Response · 200
{
  "data": {
    "track_id": "063af560-ab81-496e-8a9e-e8c1b636a56e",
    "payment_url": "https://pay.swp.gg/pay/063af560-ab81-496e-8a9e-e8c1b636a56e",
    "expired_at": 1734546589,
    "date": 1734510589
  },
  "message": "Operation completed successfully!",
  "error": {},
  "status": 200,
  "version": "1.0.0"
}
POST/whiteLabelInvoice

Generate White Label Invoice

Like Generate Invoice but returns the deposit address and crypto amount immediately — no hosted payment page. Use this when you want to build your own checkout UI and manage the coin-selection flow yourself.

You must specify pay_currency (the coin you want to receive). The response includes the on-chain address, the exact amount to request, and a QR code URL.

Request body
FieldTypeDescription
pay_currencyrequiredstring (32 symbols — see GET /currencies)The cryptocurrency the customer will pay in.
amountrequirednumberPayment amount (in `currency`, defaults to USD).
currencystringCurrency of `amount`. Fiat or crypto. Defaults to `USD`.
networkstringReserved — network is implied by `pay_currency`.
lifetimeintegerInvoice expiry in minutes from creation.
fee_paid_by_payer"0" | "1"`1` = inflate crypto `pay_amount` so the payer covers the platform fee; merchant nets ~full invoice USD. `0` = fee from merchant credit.
under_paid_coveragenumber
to_currencystringOptional target asset for auto-convert after payment (see POST /invoice).
auto_withdrawalbooleanReserved — not applied.
callback_urlstring
emailstring
order_idstring
descriptionstring
cURL
curl -X POST "https://swp.gg/api/v1/whiteLabelInvoice" \
  -H "Authorization: Bearer swp_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "pay_currency": "BTC",
    "amount": 49.99,
    "currency": "USD",
    "lifetime": 60,
    "order_id": "order-1001",
    "callback_url": "https://example.com/webhook/swp"
  }'
Response · 200
{
  "data": {
    "track_id": "063af560-ab81-496e-8a9e-e8c1b636a56e",
    "amount": 49.99,
    "currency": "usd",
    "pay_amount": 0.00120048,
    "pay_currency": "btc",
    "network": "Bitcoin Network",
    "address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq",
    "memo": "",
    "callback_url": "https://example.com/webhook/swp",
    "description": "2× Pro licence",
    "email": "",
    "fee_paid_by_payer": 0,
    "lifetime": 60,
    "order_id": "order-1001",
    "under_paid_coverage": 0,
    "rate": 41650.25,
    "qr_code": "https://api.qrserver.com/v1/create-qr-code/?data=bitcoin%3Abc1q...&size=200x200",
    "expired_at": 1734546589,
    "date": 1734510589
  },
  "message": "Operation completed successfully!",
  "error": {},
  "status": 200,
  "version": "1.0.0"
}
GET/invoice/{track_id}

Payment Information

Retrieve the current state of an invoice. Call this to poll for status changes or to reconcile a webhook notification. Add ?refresh=1 to trigger a live on-chain check before returning.

Parameters
NameInTypeDescription
track_idrequiredpathstringThe `track_id` returned when the invoice was created.
Query Parameters
NameTypeDescription
refresh"0" | "1"default: 0Set to `1` to force a live on-chain re-check before responding. Rate-limited to 60/min per merchant and client IP.
cURL
curl "https://swp.gg/api/v1/invoice/063af560-ab81-496e-8a9e-e8c1b636a56e" \
  -H "Authorization: Bearer swp_live_..."
GET/invoices

Payment History

Paginated list of all invoices for the authenticated merchant, sorted newest-first. Filter by status, currency, or date range.

Query Parameters
NameTypeDescription
pageintegerdefault: 1
sizeintegerdefault: 20
status"pending" | "confirming" | "paid" | "partially_paid" | "expired"Filter by invoice status.
currencystringFilter by payment currency (e.g. `BTC`).
from_dateintegerUnix timestamp — only return invoices created after this time.
to_dateintegerUnix timestamp — only return invoices created before this time.
cURL
curl "https://swp.gg/api/v1/invoices" \
  -H "Authorization: Bearer swp_live_..."
GET/statistics

Payment Statistics

Aggregate statistics for the authenticated merchant.

Query Parameters
NameTypeDescription
period"day" | "week" | "month" | "all"default: monthTime period to aggregate over.
cURL
curl "https://swp.gg/api/v1/statistics" \
  -H "Authorization: Bearer swp_live_..."
Response · 200
{
  "data": {
    "period": "month",
    "total_invoices": 45,
    "paid_invoices": 32,
    "pending_invoices": 8,
    "expired_invoices": 5,
    "total_received_usd": 1580.5,
    "by_currency": {
      "BTC": {
        "amount": "0.01250000",
        "usd": 840.5
      },
      "ETH": {
        "amount": "0.32000000",
        "usd": 740
      }
    }
  },
  "message": "Operation completed successfully!",
  "error": {},
  "status": 200,
  "version": "1.0.0"
}
GET/currenciesNo auth required

Accepted Currencies

Returns cryptocurrencies accepted by swp.gg, including required confirmation counts. Without an API key, the full platform list is returned. With a valid Bearer key, the list is scoped to that merchant's accepted coins.

cURL
curl "https://swp.gg/api/v1/currencies"
Response · 200
{
  "data": [
    {
      "symbol": "BTC",
      "name": "Bitcoin",
      "network": "Bitcoin Network",
      "confirmations": 2,
      "decimals": 8
    },
    {
      "symbol": "LTC",
      "name": "Litecoin",
      "network": "Litecoin Network",
      "confirmations": 6,
      "decimals": 8
    },
    {
      "symbol": "ETH",
      "name": "Ethereum",
      "network": "Ethereum Network",
      "confirmations": 12,
      "decimals": 18
    },
    {
      "symbol": "SOL",
      "name": "Solana",
      "network": "Solana Network",
      "confirmations": 1,
      "decimals": 9
    },
    {
      "symbol": "BNB",
      "name": "BNB",
      "network": "BNB Chain",
      "confirmations": 15,
      "decimals": 18
    },
    {
      "symbol": "TRX",
      "name": "Tron",
      "network": "Tron Network",
      "confirmations": 20,
      "decimals": 6
    },
    {
      "symbol": "USDT_ETH",
      "name": "Tether",
      "network": "Ethereum Network",
      "confirmations": 12,
      "decimals": 6
    },
    {
      "symbol": "USDC_BASE",
      "name": "USD Coin",
      "network": "Base",
      "confirmations": 12,
      "decimals": 6
    }
  ],
  "message": "Operation completed successfully!",
  "error": {},
  "status": 200,
  "version": "1.0.0"
}
GET/statusesNo auth required

Payment Status Table

Returns all possible invoice statuses and their meanings.

cURL
curl "https://swp.gg/api/v1/statuses"
Response · 200
{
  "data": [
    {
      "status": "pending",
      "description": "Invoice created, awaiting payment."
    },
    {
      "status": "confirming",
      "description": "Payment detected on-chain, waiting for required confirmations."
    },
    {
      "status": "paid",
      "description": "Payment confirmed within accuracy tolerance and credited to your merchant balance."
    },
    {
      "status": "partially_paid",
      "description": "Payment confirmed but below the invoice amount (outside accuracy / below partial threshold). Top-ups can still reach paid."
    },
    {
      "status": "expired",
      "description": "Invoice expired without receiving a full payment. Late payments that arrive after expiry are still credited."
    }
  ],
  "message": "Operation completed successfully!",
  "error": {},
  "status": 200,
  "version": "1.0.0"
}
Endpoints

Static Addresses

Permanent deposit addresses that accept multiple payments over time

GET/staticAddresses

Static Address List

Returns all active static deposit addresses for the authenticated merchant. Static addresses accept payments indefinitely — unlike invoices they never expire.

cURL
curl "https://swp.gg/api/v1/staticAddresses" \
  -H "Authorization: Bearer swp_live_..."
POST/staticAddresses

Generate Static Address

Activate a permanent deposit address for the specified currency on your merchant account. Funds sent to this address at any time are credited to your balance. Only one active static address per currency is allowed.

Request body
FieldTypeDescription
currencyrequiredstring (32 symbols — see GET /currencies)The cryptocurrency for this static address.
labelstringOptional label for your reference.
cURL
curl -X POST "https://swp.gg/api/v1/staticAddresses" \
  -H "Authorization: Bearer swp_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "currency": "BTC",
    "label": "My BTC deposit address"
  }'
DELETE/staticAddresses/{id}

Revoke Static Address

Deactivate a static address. Funds sent to a revoked address after revocation will not be credited. Revocation is permanent — generate a new static address if you need one again.

Parameters
NameInTypeDescription
idrequiredpathstringThe static address `id` to revoke.
cURL
curl -X DELETE "https://swp.gg/api/v1/staticAddresses/YOUR_ID" \
  -H "Authorization: Bearer swp_live_..."
Response · 200
{
  "data": {
    "id": "sa_abc123",
    "revoked": true
  },
  "message": "Operation completed successfully!",
  "error": {},
  "status": 200,
  "version": "1.0.0"
}
Endpoints

Payouts

Request crypto withdrawals to external addresses

POST/payouts

Generate Payout

Request a crypto withdrawal to an external address.

Disabled at launch — this endpoint returns 503 PAYOUTS_DISABLED. Use the dashboard Send flow for withdrawals. GET /payouts and GET /payouts/{id} remain available for payout history.

Request body
FieldTypeDescription
currencyrequiredstring (32 symbols — see GET /currencies)The cryptocurrency to send (must match a funded wallet balance).
addressrequiredstringThe destination on-chain address.
amountrequirednumberCrypto amount to send.
order_idstringYour internal reference for this payout.
notestringOptional note stored with the payout.
cURL
curl -X POST "https://swp.gg/api/v1/payouts" \
  -H "Authorization: Bearer swp_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "currency": "BTC",
    "address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq",
    "amount": 0.05,
    "order_id": "payout-2024-001",
    "note": "Weekly withdrawal"
  }'
GET/payouts

Payout History

Paginated list of all payout requests for the authenticated merchant, sorted newest-first. Filter by status, currency, or date range.

Query Parameters
NameTypeDescription
pageintegerdefault: 1
sizeintegerdefault: 20
status"pending" | "processing" | "completed" | "failed" | "cancelled"Filter by payout status.
currencystringFilter by currency (e.g. `BTC`).
from_dateintegerUnix timestamp — only return payouts created after this time.
to_dateintegerUnix timestamp — only return payouts created before this time.
cURL
curl "https://swp.gg/api/v1/payouts" \
  -H "Authorization: Bearer swp_live_..."
GET/payouts/{id}

Payout Information

Retrieve the current state of a single payout request.

Parameters
NameInTypeDescription
idrequiredpathstringThe payout `id` returned when the payout was created.
cURL
curl "https://swp.gg/api/v1/payouts/cm4payout123" \
  -H "Authorization: Bearer swp_live_..."
GET/payout-statusesNo auth required

Payout Status Table

Returns all possible payout statuses and their meanings.

cURL
curl "https://swp.gg/api/v1/payout-statuses"
Response · 200
{
  "data": [
    {
      "status": "pending",
      "description": "Payout requested and queued for processing."
    },
    {
      "status": "processing",
      "description": "Transaction is being broadcast to the network."
    },
    {
      "status": "completed",
      "description": "Transaction confirmed on-chain. Funds delivered."
    },
    {
      "status": "failed",
      "description": "Payout could not be sent. Contact support to resolve."
    },
    {
      "status": "cancelled",
      "description": "Payout was cancelled before processing began."
    }
  ],
  "message": "Operation completed successfully!",
  "error": {},
  "status": 200,
  "version": "1.0.0"
}
Webhooks

Webhooks

POSTyour callback_urlIncoming

Invoice status update

swp.gg sends an HTTP POST to your invoice callback_url whenever status changes. Each request is signed so you can verify it came from us.

Signature verification

Every webhook POST includes:

The primary signature is HMAC-SHA256(rawBody, secret) where secret is the full whsec_… string shown in the dashboard under API Keys → Webhook signing secret (Reveal). Use that string as the HMAC key — do not prefix it again.

Recommended (v2): verify X-Swp-Signature-V2 over ` ${timestamp}.${rawBody} with the same secret and reject replays when |now - X-Swp-Timestamp| > 300` seconds.

Example (Node.js):

callback_url requirements: must be a public https:// URL in production. Private, localhost, link-local, and cloud-metadata hosts are rejected, as are hostnames resolving to private/reserved IPs. Invalid URLs return 400 INVALID_CALLBACK at invoice creation.

Events: invoice.confirming, invoice.paid, invoice.partially_paid, invoice.expired.

Retry policy

Webhooks are best-effort (single attempt per status-check cycle, ~8s timeout). If your endpoint is unreachable, poll GET /invoice/{track_id} (optionally with ?refresh=1) to reconcile missed events.

Signature verification · Node.js
verify.js
const crypto = require("crypto");
function verifyWebhook(rawBody, header, secret) {
  // secret = full "whsec_…" value from the dashboard
  const expected = crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");
  const received = header.replace("sha256=", "");
  return crypto.timingSafeEqual(
    Buffer.from(expected, "hex"),
    Buffer.from(received, "hex"),
  );
}
function verifyWebhookV2(rawBody, headerV2, timestamp, secret) {
  const ts = String(timestamp);
  if (Math.abs(Math.floor(Date.now() / 1000) - Number(ts)) > 300) return false;
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${ts}.${rawBody}`)
    .digest("hex");
  const received = headerV2.replace("sha256=", "");
  return crypto.timingSafeEqual(
    Buffer.from(expected, "hex"),
    Buffer.from(received, "hex"),
  );
}
Payload fields
FieldTypeDescription
event"invoice.confirming" | "invoice.paid" | "invoice.partially_paid" | "invoice.expired"The specific event that triggered this delivery.
track_idstringUnique invoice identifier.
status"pending" | "confirming" | "paid" | "partially_paid" | "expired"
order_idstring | nullYour original order reference, if provided.
amountstringRequested amount in `currency` (decimal string).
currencystring
pay_currencystring | nullCryptocurrency the customer is paying with.
networkstring | nullHuman-readable network name (e.g. `Bitcoin Network`).
addressstring | nullOn-chain deposit address.
pay_amountstring | nullExact crypto amount requested (decimal string).
received_amountstringCrypto amount received on-chain so far.
tx_hashstring | nullFunding transaction hash once seen on-chain.
confirmationsintegerCurrent on-chain confirmation count.
required_confirmationsinteger | nullConfirmations needed before `paid` status is set.
expired_atinteger | nullUnix timestamp when the invoice expires/expired.
paid_atinteger | nullUnix timestamp when the invoice was settled (null until paid).
dateintegerUnix timestamp when the invoice was created.
Example payload
{
  "event": "invoice.paid",
  "track_id": "063af560-ab81-496e-8a9e-e8c1b636a56e",
  "status": "paid",
  "order_id": "order-1001",
  "amount": "49.99",
  "currency": "USD",
  "pay_currency": "BTC",
  "network": "Bitcoin Network",
  "address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq",
  "pay_amount": "0.00120048",
  "received_amount": "0.00120048",
  "tx_hash": "a1b2c3d4e5f6...",
  "confirmations": 2,
  "required_confirmations": 2,
  "expired_at": 1734546589,
  "paid_at": 1734546590,
  "date": 1734510589
}