Swap API
Swaps in your app, with your own fee
Quotes, orders and status over plain HTTPS and JSON. No account for your users, no KYC.
How it works
- Open a free account (a username and password; email optional), then press Request API access on your dashboard: tell us what you are building and the fee you want on top of ours (for example 0.5%). Questions: contact@hiddenswap.com.
- Once approved, make your API keys in your dashboard (several, each with a name; revoke any at once). We then set up your fee. Until it is active the API answers your keys with api_key_pending, so no swap ever runs at the wrong fee.
- Your users get quotes that already include your fee, and you see every swap and what it earned on your dashboard (every swap with its status and amounts, refreshed from the moment it starts) or from
GET /api/partner/stats. Payouts go out weekly from $50.
Authentication
Send your key on every request, from your server only (never in a page or an app bundle): Authorization: Bearer hs_live_… or X-Api-Key: hs_live_…. A request without a key is treated as an ordinary visitor and gets no fee of yours. Make and revoke keys on your dashboard; a revoked key stops at once.
Endpoints
Coins
GET /api/currencies lists every coin as rows of [id, ticker, name, network, label, icon, memoName, flags]. Flags: 1 cannot be sent, 2 cannot be received, 4 memo usually needed, 8 no fixed rate. Use the id in the calls below.
Quote
GET /api/quote?from=&to=&amount=&rateType=float|fixed. For an exact amount to receive (fixed rate only): side=to&amountTo=. A fixed quote returns rateId and expiresAt; send the rateId back when you create the order. It works once, only with your key, and only for that pair.
curl -s "https://hiddenswap.com/api/quote?from=btc&to=xmr&amount=0.01&rateType=float" \
-H "Authorization: Bearer hs_live_YOUR_KEY"All rates
GET /api/rates returns the floating rate of every main pair in one response: every listed coin to and from Monero, and the main coins against each other. Each pair has rate (before the network fee), the amountFrom it was quoted for and theamountTo that buys after all fees, min, max, networkFee and updatedAt. Rates are refreshed about every minute while the feed is read and are at most a few minutes old. Add from= or to= for one coin. No key needed; for an exact amount or a fixed rate, ask /api/quote.
Create an order
POST /api/orders with a JSON body: from, to, amount, rateType, address (where the new coins go), sourceAddress (the address the coins will be sent from, needed for every coin), and when needed extraId (memo or tag), rateId, side and amountTo. The answer (201) carries the order id, the depositAddress, any depositExtraId, the amounts and, for a fixed rate, the depositDeadline. Show your user the deposit address and the exact amount.
curl -s -X POST "https://hiddenswap.com/api/orders" \
-H "Authorization: Bearer hs_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"from":"btc","to":"xmr","amount":"0.01","rateType":"float",
"address":"4YOUR_MONERO_ADDRESS","sourceAddress":"bc1qTHE_SENDING_ADDRESS"}'Order status
GET /api/orders/{id} with your key returns the same fields with the current status: waiting, confirming, exchanging, sending, finished, failed, refunded or expired, plus transaction hashes once known. Only orders made with your key. Every order also has a public page at url.
curl -s "https://hiddenswap.com/api/orders/ORDER_ID" \
-H "Authorization: Bearer hs_live_YOUR_KEY"Your stats
GET /api/partner/stats: your status, orders, finished swaps, volume, earnings, payouts and a month by month breakdown.
Errors
Every error is JSON with a stable code and the values a message needs:
{"error":{"code":"amount_too_low","details":{"min":"0.0005","ticker":"BTC"}}}| HTTP | Code | Meaning |
|---|---|---|
| 401 | api_key_invalid | The key is wrong, was replaced or is turned off. |
| 403 | api_key_pending | Your fee is still being set up. Quotes and orders open once it is active; we tell you when. |
| 400 | bad_request | The body is not JSON, is too large, or a field has the wrong form. |
| 404 | not_found | No such order, or not one made with your key. |
| 422 | amount_too_low, amount_too_high, amount_decimals | The amount is outside the pair limits; details carry min or max and the ticker. |
| 422 | address_invalid, extra_id_required, source_address_missing | An address or memo is missing or does not fit the coin and network. |
| 422 | addresses_refused | The order cannot be made with these addresses. Ask your user for a different wallet. |
| 422 | rate_expired | A fixed rate ran out or was already used. Ask for a new quote. |
| 422 | pair_unavailable, fixed_unavailable | The pair, or a fixed rate for it, is not available right now. |
| 429 | rate_limited | Too many requests. The Retry-After header says how many seconds to wait. |
| 503 | unavailable | A temporary problem on our side. Try again shortly. |
Rate limits
Per key: quotes and status 600 per 1 minute, new orders 120 per 10 minutes. Need more? Write to us. Over the limit you get 429 with Retry-After.
Good to know
- Quotes are estimates on a floating rate: the final amount is set when the deposit is confirmed. A fixed rate holds until its deadline.
- Refunds go to the address the coins came from. Support finds any swap by its order id.
- Only swaps that finish earn your fee. Refunded and failed swaps earn nothing.
- No key yet, or just want to share a link? The affiliate program pays 25% of our fee on every swap from your link, with no code to write.

