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

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:

FieldMeaning
okBoolean. True when the front controller is up.
modeSite mode, for example live.
live_ordersBoolean. False when new swaps are paused.
rate_typeAlways floating.
timeServer 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:

FieldMeaning
idStable identifier to use in from and to. Examples: BTC, XMR, PIVX-SHIELDED, USDT-ERC20.
name, ticker, networkDisplay name, ticker and network label (for example Ethereum or BNB Chain).
depositWhether deposits of this asset are currently accepted.
payout / can_receiveWhether SwapDusk can pay this asset out right now. Only use a coin as to when this is true.
payout_notePresent when payout is unavailable; a short reason.
regexAddress pattern for this asset. Validate payout and refund addresses against it.
confirms, deposit_eta_min, block_secConfirmations required, estimated deposit time in minutes, and block time in seconds.
shieldedTrue 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
}
FieldRequiredNotes
from, to, amountYesSame ids and send amount as a current quote. amount must sit inside that pair’s limits.
payoutYesMust match the receive coin’s regex.
refundNoIf present, must match the send coin’s regex. Recommended so a failed or expired swap can be returned.
accept_termsYesMust 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:

FieldMeaning
id12-character order id.
statusPublic status (see below).
settlement_stageCoarser progress label (deposit, confirmations, exchange, payout, and so on).
from, to, from_name, to_name, from_network, to_networkPair and display names.
amount, send_exactRequested send amount, and the exact amount to deposit.
expected_receive / estimate_receive, min_receive, final_receiveQuoted estimate, lower bound, and the settled payout once finished.
rate_type, type, noticeAlways floating / float, with the floating-rate notice.
deposit_address, deposit_memo, deposit_deadlineWhere and by when to send funds. Deadline is a Unix time.
confirms_needed, eta_minConfirmations required and estimated minutes.
payout, refundAddresses you submitted. refund_address_recorded is a boolean.
deposit_txid, deposit_confirmations, payout_txid, refund_txidSet as the swap progresses.

Public status values:

StatusMeaning
waitingWaiting for the deposit.
confirmingDeposit seen; waiting for confirmations.
exchangingDeposit confirmed; conversion in progress.
sendingPayout is being sent.
finishedPayout broadcast (see payout_txid).
expiredNo qualifying deposit before the deadline.
refunding / refundedA refund is in progress or done (refund_txid when available).
review / closedNeeds 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.