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.
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.
{
"data": { },
"message": "Operation completed successfully!",
"error": { },
"status": 200,
"version": "1.0.0"
}Authentication
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.
Authorization: Bearer swp_live_...API keys are scoped per-merchant. Endpoints marked No auth required are public and do not need a key.
Payments
Invoice creation and payment lifecycle
/invoiceGenerate 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.
| Field | Type | Description |
|---|---|---|
| amountrequired | number | Payment amount in USD. The `currency` field is display/reference only at launch — `amount` is always interpreted as USD. |
| currency | string | Display/reference only at launch. `amount` is always treated as USD. |
| lifetime | integer | Invoice 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_coverage | number | Max underpayment still accepted as paid, as a percentage of the due crypto amount (combined with platform accuracy settings). |
| to_currency | string | Optional 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_withdrawal | boolean | Reserved — not applied. Auto-forward on payment is not implemented; use payouts separately. |
| mixed_payment | boolean | Reserved — not applied. Multi-coin remainder payments are not supported. |
| callback_url | string | Webhook 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_url | string | Redirect 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. |
| string | Customer email stored on the invoice (receipts if enabled). | |
| order_id | string | Your internal order reference (echoed in webhooks and GET invoice). |
| thanks_message | string | Message shown to customer after successful payment. |
| description | string | Order details shown in reports and on the payment page. |
| sandbox | boolean | Reserved — not applied. There is no separate sandbox ledger; omit this field. |
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"
}'{
"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"
}/whiteLabelInvoiceGenerate 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.
| Field | Type | Description |
|---|---|---|
| pay_currencyrequired | string (32 symbols — see GET /currencies) | The cryptocurrency the customer will pay in. |
| amountrequired | number | Payment amount (in `currency`, defaults to USD). |
| currency | string | Currency of `amount`. Fiat or crypto. Defaults to `USD`. |
| network | string | Reserved — network is implied by `pay_currency`. |
| lifetime | integer | Invoice 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_coverage | number | |
| to_currency | string | Optional target asset for auto-convert after payment (see POST /invoice). |
| auto_withdrawal | boolean | Reserved — not applied. |
| callback_url | string | |
| string | ||
| order_id | string | |
| description | string |
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"
}'{
"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"
}/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.
| Name | In | Type | Description |
|---|---|---|---|
| track_idrequired | path | string | The `track_id` returned when the invoice was created. |
| Name | Type | Description |
|---|---|---|
| refresh | "0" | "1"default: 0 | Set to `1` to force a live on-chain re-check before responding. Rate-limited to 60/min per merchant and client IP. |
curl "https://swp.gg/api/v1/invoice/063af560-ab81-496e-8a9e-e8c1b636a56e" \
-H "Authorization: Bearer swp_live_..."/invoicesPayment History
Paginated list of all invoices for the authenticated merchant, sorted newest-first. Filter by status, currency, or date range.
| Name | Type | Description |
|---|---|---|
| page | integerdefault: 1 | |
| size | integerdefault: 20 | |
| status | "pending" | "confirming" | "paid" | "partially_paid" | "expired" | Filter by invoice status. |
| currency | string | Filter by payment currency (e.g. `BTC`). |
| from_date | integer | Unix timestamp — only return invoices created after this time. |
| to_date | integer | Unix timestamp — only return invoices created before this time. |
curl "https://swp.gg/api/v1/invoices" \
-H "Authorization: Bearer swp_live_..."/statisticsPayment Statistics
Aggregate statistics for the authenticated merchant.
| Name | Type | Description |
|---|---|---|
| period | "day" | "week" | "month" | "all"default: month | Time period to aggregate over. |
curl "https://swp.gg/api/v1/statistics" \
-H "Authorization: Bearer swp_live_..."{
"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"
}/currenciesNo auth requiredAccepted 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 "https://swp.gg/api/v1/currencies"{
"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"
}/statusesNo auth requiredPayment Status Table
Returns all possible invoice statuses and their meanings.
curl "https://swp.gg/api/v1/statuses"{
"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"
}Static Addresses
Permanent deposit addresses that accept multiple payments over time
/staticAddressesStatic Address List
Returns all active static deposit addresses for the authenticated merchant. Static addresses accept payments indefinitely — unlike invoices they never expire.
curl "https://swp.gg/api/v1/staticAddresses" \
-H "Authorization: Bearer swp_live_..."/staticAddressesGenerate 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.
| Field | Type | Description |
|---|---|---|
| currencyrequired | string (32 symbols — see GET /currencies) | The cryptocurrency for this static address. |
| label | string | Optional label for your reference. |
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"
}'/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.
| Name | In | Type | Description |
|---|---|---|---|
| idrequired | path | string | The static address `id` to revoke. |
curl -X DELETE "https://swp.gg/api/v1/staticAddresses/YOUR_ID" \
-H "Authorization: Bearer swp_live_..."{
"data": {
"id": "sa_abc123",
"revoked": true
},
"message": "Operation completed successfully!",
"error": {},
"status": 200,
"version": "1.0.0"
}Payouts
Request crypto withdrawals to external addresses
/payoutsGenerate 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.
| Field | Type | Description |
|---|---|---|
| currencyrequired | string (32 symbols — see GET /currencies) | The cryptocurrency to send (must match a funded wallet balance). |
| addressrequired | string | The destination on-chain address. |
| amountrequired | number | Crypto amount to send. |
| order_id | string | Your internal reference for this payout. |
| note | string | Optional note stored with the payout. |
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"
}'/payoutsPayout History
Paginated list of all payout requests for the authenticated merchant, sorted newest-first. Filter by status, currency, or date range.
| Name | Type | Description |
|---|---|---|
| page | integerdefault: 1 | |
| size | integerdefault: 20 | |
| status | "pending" | "processing" | "completed" | "failed" | "cancelled" | Filter by payout status. |
| currency | string | Filter by currency (e.g. `BTC`). |
| from_date | integer | Unix timestamp — only return payouts created after this time. |
| to_date | integer | Unix timestamp — only return payouts created before this time. |
curl "https://swp.gg/api/v1/payouts" \
-H "Authorization: Bearer swp_live_..."/payouts/{id}Payout Information
Retrieve the current state of a single payout request.
| Name | In | Type | Description |
|---|---|---|---|
| idrequired | path | string | The payout `id` returned when the payout was created. |
curl "https://swp.gg/api/v1/payouts/cm4payout123" \
-H "Authorization: Bearer swp_live_..."/payout-statusesNo auth requiredPayout Status Table
Returns all possible payout statuses and their meanings.
curl "https://swp.gg/api/v1/payout-statuses"{
"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
your callback_urlIncomingInvoice 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.
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"),
);
}| Field | Type | Description |
|---|---|---|
| event | "invoice.confirming" | "invoice.paid" | "invoice.partially_paid" | "invoice.expired" | The specific event that triggered this delivery. |
| track_id | string | Unique invoice identifier. |
| status | "pending" | "confirming" | "paid" | "partially_paid" | "expired" | |
| order_id | string | null | Your original order reference, if provided. |
| amount | string | Requested amount in `currency` (decimal string). |
| currency | string | |
| pay_currency | string | null | Cryptocurrency the customer is paying with. |
| network | string | null | Human-readable network name (e.g. `Bitcoin Network`). |
| address | string | null | On-chain deposit address. |
| pay_amount | string | null | Exact crypto amount requested (decimal string). |
| received_amount | string | Crypto amount received on-chain so far. |
| tx_hash | string | null | Funding transaction hash once seen on-chain. |
| confirmations | integer | Current on-chain confirmation count. |
| required_confirmations | integer | null | Confirmations needed before `paid` status is set. |
| expired_at | integer | null | Unix timestamp when the invoice expires/expired. |
| paid_at | integer | null | Unix timestamp when the invoice was settled (null until paid). |
| date | integer | Unix timestamp when the invoice was created. |
{
"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
}