{"openapi":"3.1.0","info":{"title":"Swapnoir API","version":"1.0.0","summary":"Free, read-only crypto exchange API: supported currencies, live estimates and order status. No API key.","description":"The Swapnoir API gives your app the same live data the swapnoir.com exchange uses: supported currencies, live estimates with all fees included, and the status of any order by its ID.\n\nFull guide with code samples, error codes and integration tips: [swapnoir.com/api](https://swapnoir.com/api).\n\n- **No API key, no account.** All endpoints are public `GET` requests and can be called from servers or from browsers (CORS is open).\n- **Amounts are strings**, for example `\"0.01\"`, so no precision is lost. Times are ISO 8601 in UTC.\n- **Errors** use [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457) problem details with a stable `code`.\n- **Rate limits** per connection: 90 estimates, 60 currency lists and 30 order lookups a minute. Every response carries `RateLimit` headers.\n- **Creating an exchange** happens on swapnoir.com: link your user to a prefilled exchange, for example `https://swapnoir.com/exchange?from=BTC&to=XMR&amount=0.01`, then follow the order with `GET /orders/{id}`.","termsOfService":"https://swapnoir.com/terms","contact":{"name":"Swapnoir support","url":"https://swapnoir.com/help#contact"}},"externalDocs":{"description":"Swapnoir API guide","url":"https://swapnoir.com/api"},"servers":[{"url":"https://swapnoir.com/api/v1","description":"Production, version 1"}],"security":[],"tags":[{"name":"Currencies","description":"Currencies and networks you can exchange.","x-scalar-order":["swapnoir-api/tag/currencies/GET/currencies"]},{"name":"Rates","description":"Live estimates with all fees included.","x-scalar-order":["swapnoir-api/tag/rates/GET/estimate"]},{"name":"Orders","description":"Status of an exchange by its order ID.","x-scalar-order":["swapnoir-api/tag/orders/GET/orders/{id}"]}],"paths":{"/currencies":{"get":{"tags":["Currencies"],"operationId":"listCurrencies","summary":"List currencies","description":"Every currency and network Swapnoir supports. A token on another network is a separate currency, for example `USDT-TRC20` and `USDT-ERC20`. The list changes rarely; cache it for a few minutes.","responses":{"200":{"description":"Supported currencies.","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrencyList"},"example":{"currencies":[{"id":"BTC","ticker":"BTC","name":"Bitcoin","network":"Bitcoin","decimals":8,"send":true,"receive":true,"memo":null,"icon_url":"https://swapnoir.com/assets/coins/btc.svg"},{"id":"BTC-LN","ticker":"BTC","name":"Bitcoin","network":"Lightning","decimals":8,"send":true,"receive":false,"memo":null,"icon_url":"https://swapnoir.com/assets/coins/btc.svg"},{"id":"XRP","ticker":"XRP","name":"XRP","network":"XRP Ledger","decimals":6,"send":true,"receive":true,"memo":"Destination tag","icon_url":"https://swapnoir.com/assets/coins/xrp.svg"}]}}}},"429":{"description":"Rate limit reached. Wait `Retry-After` seconds.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://swapnoir.com/api#error-rate_limited","title":"Too many requests","status":429,"detail":"More than 90 requests a minute to this endpoint. Please slow down.","code":"rate_limited"}}}}}}},"/estimate":{"get":{"tags":["Rates"],"operationId":"getEstimate","summary":"Get an estimate","description":"How much of `to` the user receives for `amount` of `from`, with all exchange and network fees for the payout already included. Estimates are live and are not reserved: the final amount is set when the exchange is created (fixed rate) or when the deposit is confirmed (floating rate).","parameters":[{"name":"from","in":"query","required":true,"description":"Currency the user sends.","schema":{"$ref":"#/components/schemas/CurrencyId"},"example":"BTC"},{"name":"to","in":"query","required":true,"description":"Currency the user receives. `BTC-LN` is send only.","schema":{"$ref":"#/components/schemas/ReceivableCurrencyId"},"example":"XMR"},{"name":"amount","in":"query","required":true,"description":"Amount of `from`, as a decimal with a dot and at most the currency’s `decimals`.","schema":{"$ref":"#/components/schemas/Amount"},"example":"0.01"},{"name":"rate","in":"query","required":false,"description":"`float` (default) follows the market until the deposit is confirmed. `fixed` locks the amount when the exchange is created.","schema":{"$ref":"#/components/schemas/RateType"},"example":"float"}],"responses":{"200":{"description":"Live estimate.","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Estimate"},"example":{"from":"BTC","to":"XMR","rate_type":"float","amount_from":"0.01","amount_to":"1.57166029","rate":"157.166029","usd_value":"866.32","quoted_at":"2026-10-05T12:00:00.000Z"}}}},"400":{"description":"A parameter is missing or invalid; `param` names it.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://swapnoir.com/api#error-invalid_parameter","title":"Invalid parameter","status":400,"detail":"Unknown currency `DOG`. See /api/v1/currencies.","code":"invalid_parameter","param":"from"}}}},"422":{"description":"The amount is below the minimum (`min_amount` is returned) or the pair is not offered.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://swapnoir.com/api#error-amount_too_small","title":"Amount below minimum","status":422,"detail":"The minimum for this pair is 0.00005799 BTC.","code":"amount_too_small","min_amount":"0.00005799"}}}},"429":{"description":"Rate limit reached. Wait `Retry-After` seconds.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://swapnoir.com/api#error-rate_limited","title":"Too many requests","status":429,"detail":"More than 90 requests a minute to this endpoint. Please slow down.","code":"rate_limited"}}}},"503":{"description":"No rate is available right now. Retry after `Retry-After` seconds.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://swapnoir.com/api#error-pair_unavailable","title":"Pair temporarily unavailable","status":503,"detail":"This pair is unavailable right now. Try another network or amount.","code":"pair_unavailable"}}}}}}},"/orders/{id}":{"get":{"tags":["Orders"],"operationId":"getOrder","summary":"Get an order","description":"Live status and details of an exchange. The order ID is the last part of the order page URL. Anyone with the ID can see the order, so treat it like a password. Poll at most every 10 seconds and stop when `final` is true. Orders are deleted 7 days after they finish.","parameters":[{"name":"id","in":"path","required":true,"description":"Order ID, for example `K7M2QX9PRT4B`.","schema":{"$ref":"#/components/schemas/OrderId"}}],"responses":{"200":{"description":"The order.","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimit-Policy"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"},"example":{"id":"K7M2QX9PRT4B","status":"confirming","final":false,"rate_type":"float","created_at":"2026-10-05T12:00:00.000Z","updated_at":"2026-10-05T12:06:12.000Z","from":{"currency":"BTC","amount":"0.01"},"to":{"currency":"XMR","amount":"1.57166029","amount_is_final":false},"deposit":{"address":"bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq","memo":null,"expires_at":null},"payout":{"address":"888tNkZrPN6JsEgekjMnABU4TBzc2Dt29EPAvkRxbANsAnjyPbb3iQ1YBRk1UXcdRsiKc9dhwMVgN5S9cQUiyoogDavup3H","memo":null},"refund":null,"transactions":{"deposit":{"hash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","url":"https://mempool.space/tx/e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"},"payout":null},"links":{"order_page":"https://swapnoir.com/order/K7M2QX9PRT4B","receipt":"https://swapnoir.com/order/K7M2QX9PRT4B/receipt.txt"}}}}},"404":{"description":"No order with this ID, or it was deleted.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://swapnoir.com/api#error-not_found","title":"Not found","status":404,"detail":"No order with this ID. Orders are deleted 7 days after they finish.","code":"not_found"}}}},"429":{"description":"Rate limit reached. Wait `Retry-After` seconds.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://swapnoir.com/api#error-rate_limited","title":"Too many requests","status":429,"detail":"More than 90 requests a minute to this endpoint. Please slow down.","code":"rate_limited"}}}}}}}},"components":{"schemas":{"Amount":{"type":"string","pattern":"^\\d{1,12}(\\.\\d{1,18})?$","description":"Positive decimal string with a dot.","examples":["0.01"],"title":"Amount"},"RateType":{"type":"string","enum":["float","fixed"],"default":"float","x-enumDescriptions":{"float":"Follows the market until the deposit is confirmed","fixed":"Locks the amount when the exchange is created"},"title":"Rate type"},"Estimate":{"type":"object","required":["from","to","rate_type","amount_from","amount_to","rate","usd_value","quoted_at"],"additionalProperties":false,"properties":{"from":{"$ref":"#/components/schemas/CurrencyId"},"to":{"$ref":"#/components/schemas/ReceivableCurrencyId"},"rate_type":{"$ref":"#/components/schemas/RateType"},"amount_from":{"$ref":"#/components/schemas/Amount","description":"The amount you asked about."},"amount_to":{"$ref":"#/components/schemas/Amount","description":"What the user receives, after all fees."},"rate":{"type":"string","description":"Amount of `to` per 1 `from`, after fees.","examples":["157.166029"]},"usd_value":{"type":["string","null"],"description":"Approximate US dollar value of `amount_from`, when known.","examples":["866.32"]},"quoted_at":{"type":"string","format":"date-time"}},"title":"Estimate"},"OrderId":{"type":"string","title":"Order ID","pattern":"^[A-Za-z0-9]{8,16}$","examples":["K7M2QX9PRT4B"]},"CurrencyId":{"type":"string","title":"Currency ID","description":"Currency and network.","enum":["BTC","XMR","ETH","USDT-TRC20","USDT-ERC20","USDT-SOL","USDC-ERC20","LTC","SOL","BTC-LN","TRX","BNB","DOGE","ZEC","BCH","DASH","XRP"],"x-enumDescriptions":{"BTC":"Bitcoin on Bitcoin","XMR":"Monero on Monero","ETH":"Ethereum on Ethereum","USDT-TRC20":"Tether on Tron (TRC20)","USDT-ERC20":"Tether on Ethereum (ERC20)","USDT-SOL":"Tether on Solana","USDC-ERC20":"USD Coin on Ethereum (ERC20)","LTC":"Litecoin on Litecoin","SOL":"Solana on Solana","BTC-LN":"Bitcoin Lightning on Lightning (send only)","TRX":"Tron on Tron","BNB":"BNB on BNB Smart Chain (BEP20)","DOGE":"Dogecoin on Dogecoin","ZEC":"Zcash on Zcash","BCH":"Bitcoin Cash on Bitcoin Cash","DASH":"Dash on Dash","XRP":"XRP on XRP Ledger"}},"ReceivableCurrencyId":{"type":"string","title":"Receivable currency ID","description":"Any currency except send-only ones.","enum":["BTC","XMR","ETH","USDT-TRC20","USDT-ERC20","USDT-SOL","USDC-ERC20","LTC","SOL","TRX","BNB","DOGE","ZEC","BCH","DASH","XRP"],"x-enumDescriptions":{"BTC":"Bitcoin on Bitcoin","XMR":"Monero on Monero","ETH":"Ethereum on Ethereum","USDT-TRC20":"Tether on Tron (TRC20)","USDT-ERC20":"Tether on Ethereum (ERC20)","USDT-SOL":"Tether on Solana","USDC-ERC20":"USD Coin on Ethereum (ERC20)","LTC":"Litecoin on Litecoin","SOL":"Solana on Solana","TRX":"Tron on Tron","BNB":"BNB on BNB Smart Chain (BEP20)","DOGE":"Dogecoin on Dogecoin","ZEC":"Zcash on Zcash","BCH":"Bitcoin Cash on Bitcoin Cash","DASH":"Dash on Dash","XRP":"XRP on XRP Ledger"}},"Status":{"type":"string","title":"Order status","enum":["preparing","awaiting","confirming","exchanging","sending","processing","done","expired","hold","attention","refunding","refunded","failed"],"x-enumDescriptions":{"preparing":"The deposit address is being prepared. It usually appears within minutes.","awaiting":"Waiting for the deposit. Send only while the order is in this status and before `deposit.expires_at`.","confirming":"The deposit was seen and is waiting for network confirmations.","exchanging":"The deposit is confirmed and is being exchanged.","sending":"The exchanged coins are being sent to the payout address.","processing":"In progress. Used when a more specific status is not known.","done":"Complete. The payout was sent; see `transactions.payout`.","expired":"No deposit arrived in time. A late deposit can still be completed or refunded through support.","hold":"Paused for a routine review. The user should contact support with the order ID.","attention":"Something needs checking, for example a deposit of the wrong amount. The user should contact support.","refunding":"The deposit is being returned to the refund address.","refunded":"The deposit was returned.","failed":"The exchange could not be completed. The user should contact support."}},"Currency":{"type":"object","title":"Currency","additionalProperties":false,"required":["id","ticker","name","network","decimals","send","receive","memo","icon_url"],"properties":{"id":{"$ref":"#/components/schemas/CurrencyId"},"ticker":{"type":"string","examples":["USDT"]},"name":{"type":"string","examples":["Tether"]},"network":{"type":"string","examples":["Tron (TRC20)"]},"decimals":{"type":"integer","description":"Maximum decimals accepted in amounts.","examples":[6]},"send":{"type":"boolean","description":"Can be used as `from`."},"receive":{"type":"boolean","description":"Can be used as `to`."},"memo":{"type":["string","null"],"description":"Name of the extra field some networks need with the address, such as `Destination tag`; null when not used."},"icon_url":{"type":"string","format":"uri"}}},"CurrencyList":{"type":"object","title":"Currency list","required":["currencies"],"properties":{"currencies":{"type":"array","items":{"$ref":"#/components/schemas/Currency"}}}},"Transaction":{"type":"object","title":"Transaction","required":["hash","url"],"properties":{"hash":{"type":"string"},"url":{"type":["string","null"],"format":"uri","description":"Block explorer link, when one is known."}}},"Order":{"type":"object","title":"Order","additionalProperties":false,"required":["id","status","final","rate_type","created_at","updated_at","from","to","deposit","payout","refund","transactions","links"],"properties":{"id":{"$ref":"#/components/schemas/OrderId"},"status":{"$ref":"#/components/schemas/Status"},"final":{"type":"boolean","description":"True for `done`, `expired`, `refunded` and `failed`: stop polling."},"rate_type":{"$ref":"#/components/schemas/RateType"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"from":{"type":"object","required":["currency","amount"],"properties":{"currency":{"$ref":"#/components/schemas/CurrencyId"},"amount":{"$ref":"#/components/schemas/Amount","description":"Amount to deposit."}}},"to":{"type":"object","required":["currency","amount","amount_is_final"],"properties":{"currency":{"$ref":"#/components/schemas/CurrencyId"},"amount":{"type":["string","null"],"description":"Estimated payout, or the final payout once `amount_is_final` is true."},"amount_is_final":{"type":"boolean"}}},"deposit":{"type":"object","required":["address","memo","expires_at"],"properties":{"address":{"type":["string","null"],"description":"Where the user sends the deposit; null while the status is `preparing`."},"memo":{"type":["string","null"],"description":"Memo or destination tag that must be included with the deposit, when set."},"expires_at":{"type":["string","null"],"format":"date-time","description":"Send before this time, when set."}}},"payout":{"type":"object","required":["address","memo"],"properties":{"address":{"type":"string"},"memo":{"type":["string","null"]}}},"refund":{"oneOf":[{"type":"null"},{"type":"object","required":["address","memo"],"properties":{"address":{"type":"string"},"memo":{"type":["string","null"]}}}]},"transactions":{"type":"object","required":["deposit","payout"],"properties":{"deposit":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Transaction"}]},"payout":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Transaction"}]}}},"links":{"type":"object","required":["order_page","receipt"],"properties":{"order_page":{"type":"string","format":"uri"},"receipt":{"type":"string","format":"uri"}}}}},"Problem":{"type":"object","title":"Problem (RFC 9457)","required":["type","title","status","detail","code"],"properties":{"type":{"type":"string","format":"uri","description":"Link to the documentation of this error."},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string","description":"Explanation you can show to the user."},"code":{"type":"string","enum":["invalid_parameter","same_currency","receive_not_supported","amount_too_small","pair_not_supported","pair_unavailable","not_found","rate_limited","internal_error"],"x-enumDescriptions":{"invalid_parameter":"A query parameter is missing or malformed. `param` names it.","same_currency":"`from` and `to` are the same currency.","receive_not_supported":"The `to` currency is send only (Lightning).","amount_too_small":"The amount is below the minimum for this pair. `min_amount` holds the minimum.","pair_not_supported":"This pair of currencies and networks is not offered.","pair_unavailable":"No rate is available for this pair right now. Retry later or try another amount.","not_found":"No order with this ID, or the order has been deleted.","rate_limited":"You hit the rate limit. Wait the number of seconds in `Retry-After`.","internal_error":"Something went wrong on our side. Retry later."}},"param":{"type":"string","description":"The parameter to fix, for `invalid_parameter` and similar errors."},"min_amount":{"type":"string","description":"Minimum amount of `from`, for `amount_too_small`."}}}},"headers":{"RateLimit":{"description":"Requests left in the current window, for example `limit=90, remaining=89, reset=60`.","schema":{"type":"string"}},"RateLimit-Policy":{"description":"The limit for this endpoint, for example `90;w=60` (90 requests per 60 seconds).","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}}},"x-scalar-watch-mode":true,"x-scalar-order":["swapnoir-api/description/introduction","swapnoir-api/tag/rates","swapnoir-api/tag/orders","swapnoir-api/models","swapnoir-api/tag/currencies"]}