For integrators
SwapDusk API
The public HTTP API behind swapdusk.com. You can list coins, request a floating quote, create a swap and poll its status. There is no API key and no account. JSON in, JSON out.
Documented from the live API on 10 November 2026. Quotes and coin flags change; always read a fresh coins and quote response.
- Base URL and auth
- Rate type, limits and confirmations
- Errors and rate limits
- Health
- List coins
- Quote
- Create an order
- Track an order
Base URL and auth
Call the front controller with an action query parameter:
https://swapdusk.com/api/index.php?action=…
The same file is also the directory index at https://swapdusk.com/api/, so /api/?action=coins works too. Responses are application/json; charset=utf-8 with Cache-Control: no-store.
A Tor mirror of the site exists at http://duskvjsvrpcpznjpjuaxgpnitb42i5no5vc2oib7esui3m66qeaik4qd.onion/. The same /api/index.php paths are available there.
No API key, token, or account is required for the endpoints on this page. POST bodies are JSON, at most 4096 bytes, with Content-Type: application/json.
This API does not send CORS headers. Browser calls from another origin will fail; call it from your server.
Rate type, limits and confirmations
All quotes and orders are floating. There is no fixed-rate mode. A type of fixed on create is ignored and treated as floating. The notice returned on coins, quotes and orders is:
Floating rate: the final amount is set when your deposit confirms and may differ from this estimate.
Show users receive as the estimate and min_receive as a lower bound. If the market has moved more than max_adverse_move (currently 0.08, or 8%) against the estimate when the deposit confirms, the swap is held for a refund rather than completed at a worse rate.
USD bounds in the live config are a $10 minimum and a $1000 maximum per swap. Each quote also returns limits.min and limits.max in send-coin units. Those can be tighter than the USD bounds (venue minimums, payout floors, or book depth). Never send an amount outside the quote’s limits.
A created order waits 24 hours for a deposit (deposit_deadline). After that it expires.
Deposit confirmations are per asset. The coins list returns confirms, deposit_eta_min and block_sec for each coin. A quote repeats the send-coin figures under params.deposit_confirms, params.deposit_eta_min and params.deposit_block_sec, and a combined estimate in eta_min (deposit time plus withdrawal time, in minutes).
Errors and rate limits
Failed calls return HTTP 400 by default (404, 429 or 503 when those apply) and this body:
{
"ok": false,
"error": "Too many requests, slow down a little."
}
Common messages include Enter an amount, Below the minimum., Above the maximum., Order not found, Please accept the terms, and address-validation errors. A 503 uses Live rates are unavailable right now. Try again in a moment.
Every action shares a per-IP limit of 60 requests per calendar minute. Over the limit, HTTP 429 with the “slow down” message above. Creating orders has an extra limit of 6 new orders per IP per minute; over that limit the error is Too many new orders, wait a minute. Please poll status politely and cache the coins list.
Health
GET /api/index.php?action=health — or omit action, which defaults to health.
A live response includes:
| Field | Meaning |
|---|---|
ok | Boolean. True when the front controller is up. |
mode | Site mode, for example live. |
live_orders | Boolean. False when new swaps are paused. |
rate_type | Always floating. |
time | Server Unix time. |
Additional operational flags may be present. Use ok and live_orders to decide whether you can quote and create.
List coins
GET /api/index.php?action=coins
Returns every listed asset. On 10 November 2026 the live list had 21 coins and networks; 12 can be paid out and all 21 can be sent. Treat the live flags as the source of truth — they can change when a payout route is paused.
Top-level fields: ok, any_to_any (true: any send asset can be quoted into any payout asset, subject to flags and limits), mode, coins, live_orders, rate_type, notice. Each coin includes:
| Field | Meaning |
|---|---|
id | Stable identifier to use in from and to. Examples: BTC, XMR, PIVX-SHIELDED, USDT-ERC20. |
name, ticker, network | Display name, ticker and network label (for example Ethereum or BNB Chain). |
deposit | Whether deposits of this asset are currently accepted. |
payout / can_receive | Whether SwapDusk can pay this asset out right now. Only use a coin as to when this is true. |
payout_note | Present when payout is unavailable; a short reason. |
regex | Address pattern for this asset. Validate payout and refund addresses against it. |
confirms, deposit_eta_min, block_sec | Confirmations required, estimated deposit time in minutes, and block time in seconds. |
shielded | True for shielded PIVX and Pirate Chain (ARRR). |
Send-and-receive on the live list: PIVX, PIVX-SHIELDED, BTC, XMR, ETH, USDT-ERC20, USDC-ERC20, SOL, BNB, DASH, FIRO, ARRR. Send-only: LTC, DOGE, BCH, ZEC, TRX, USDT-BEP20, USDT-PLG20, USDT-SOL, USDT-TRC20. Firo Spark addresses are not listed.
Abbreviated example (one asset; the live response lists all 21):
{
"ok": true,
"any_to_any": true,
"mode": "live",
"live_orders": true,
"rate_type": "floating",
"notice": "Floating rate: the final amount is set when your deposit confirms and may differ from this estimate.",
"coins": [
{
"id": "XMR",
"name": "Monero",
"ticker": "XMR",
"network": "Monero",
"deposit": true,
"can_receive": true,
"payout": true,
"payout_note": null,
"regex": "^[1-9A-HJ-NP-Za-km-z]{60,120}$",
"confirms": 100,
"deposit_eta_min": 205,
"block_sec": 123,
"shielded": false
}
]
}
The XMR regex and confirmation figures above are from the live coins call on 10 November 2026, 22:05 SAST. Re-read the endpoint for current values. Address patterns differ per coin.
Quote
GET /api/index.php?action=quote
Query parameters: from and to (coin ids) and exactly one of amount (how much you will send) or receive (how much you would like to receive). If you send both or neither, the error is Enter an amount. A receive quote is still a floating forward quote: the response’s amount is the send size that is estimated to produce at least your target, and receive / min_receive are the usual forward figures.
Example, send 25 USDT on Ethereum, receive Monero (live GET on 10 November 2026, 22:05 SAST). Numbers move with the book; this is a shape, not a rate you can reuse.
GET /api/index.php?action=quote&from=USDT-ERC20&to=XMR&amount=25
{
"ok": true,
"error": null,
"warnings": [],
"high_impact": false,
"impact_warning": null,
"from": "USDT-ERC20",
"to": "XMR",
"type": "float",
"amount": 25,
"receive": 0.03945569,
"rate": 0.0015782276,
"min_receive": 0.03629923,
"max_adverse_move": 0.08,
"rate_type": "floating",
"notice": "Floating rate: the final amount is set when your deposit confirms and may differ from this estimate.",
"limits": {
"min": 10,
"max": 1000,
"min_reason": "min_usd",
"max_reason": "max_usd"
},
"params": {
"deposit_confirms": 10,
"deposit_eta_min": 2,
"deposit_block_sec": 12
},
"eta_min": 12
}
A successful quote also includes a cost breakdown (already subtracted from receive), route metadata, and other pricing coefficients under params. Show users receive, min_receive, limits, eta_min and the floating-rate notice. The spread is included in the quoted receive amount.
If ok is false, read error. high_impact with an impact_warning means this size moves the book; a smaller amount gets a better rate. warnings is a list of venue pause messages when deposits or payouts are disrupted.
Only quote a to asset that currently has payout / can_receive true. Quotes for send-only coins as the receive side are rejected.
Create an order
POST /api/index.php?action=order
JSON body:
{
"from": "USDT-ERC20",
"to": "XMR",
"amount": 25,
"payout": "<destination address for the receive coin>",
"refund": "<optional refund address for the send coin>",
"accept_terms": true
}
| Field | Required | Notes |
|---|---|---|
from, to, amount | Yes | Same ids and send amount as a current quote. amount must sit inside that pair’s limits. |
payout | Yes | Must match the receive coin’s regex. |
refund | No | If present, must match the send coin’s regex. Recommended so a failed or expired swap can be returned. |
accept_terms | Yes | Must be true. The terms are at /terms.html. |
A successful response is {"ok": true, "order": {…}}. The order object is the public status view described below. On create, status is waiting.
Send send_exact, not amount. The deposit amount can differ slightly from the requested amount because a small tag is added so the deposit can be matched. Pay send_exact to deposit_address. If deposit_memo is a non-empty string, include that memo / payment id. Missing the memo or sending the untagged amount can delay or mis-attribute the deposit.
Keep the order id private. It is the only credential needed to read status.
Track an order
GET /api/index.php?action=order&id={id}
Returns {"ok": true, "order": {…}}, or 404 Order not found. The public tracker page is /status.html?id= for the same id. A typical order object includes:
| Field | Meaning |
|---|---|
id | 12-character order id. |
status | Public status (see below). |
settlement_stage | Coarser progress label (deposit, confirmations, exchange, payout, and so on). |
from, to, from_name, to_name, from_network, to_network | Pair and display names. |
amount, send_exact | Requested send amount, and the exact amount to deposit. |
expected_receive / estimate_receive, min_receive, final_receive | Quoted estimate, lower bound, and the settled payout once finished. |
rate_type, type, notice | Always floating / float, with the floating-rate notice. |
deposit_address, deposit_memo, deposit_deadline | Where and by when to send funds. Deadline is a Unix time. |
confirms_needed, eta_min | Confirmations required and estimated minutes. |
payout, refund | Addresses you submitted. refund_address_recorded is a boolean. |
deposit_txid, deposit_confirmations, payout_txid, refund_txid | Set as the swap progresses. |
Public status values:
| Status | Meaning |
|---|---|
waiting | Waiting for the deposit. |
confirming | Deposit seen; waiting for confirmations. |
exchanging | Deposit confirmed; conversion in progress. |
sending | Payout is being sent. |
finished | Payout broadcast (see payout_txid). |
expired | No qualifying deposit before the deadline. |
refunding / refunded | A refund is in progress or done (refund_txid when available). |
review / closed | Needs attention, or closed without a normal payout. Read notice. |
If a deposit arrives at a different amount than send_exact, the order may include deposit_mismatch, deposit_expected, deposit_received and deposit_diff_pct.
Support: Telegram. Terms: /terms.html. Privacy: /privacy.