cryptoinfraDocs

#Swaps and exchange

A swap and an exchange share one order shape and one fee, and differ in where the money lands:

Open as MarkdownFor AI assistants
SwapExchange
Sell sideone of our assets, from the user's balancethe same
Buy sideone of our assets — named by our asset_idany of thousands of coins — named by the exchange's own identifier
Where it landscredited to the user's balancepaid out to an address you supply
Amounts on the buy sideexact, with *_base twinsdecimal estimates only — no *_base
EndpointsPOST /v1/swap/quote, POST /v1/swap/ordersPOST /v1/exchange/quote, POST /v1/exchange/orders

Both are read with GET /v1/swap/orders/{id}, and neither emits a webhook. Poll.

#Swap

  1. Quote. POST /v1/swap/quote with sell_asset_id, buy_asset_id and amount. It is indicative: no reservation, no hold, re-quoted at create time — expires_at is when to ask again, not a price lock. receive_estimate is the estimate, receive_minimum the floor this route guarantees; the user is credited what actually arrives, which is why both are published.
  2. Create. POST /v1/swap/orders with the same fields plus user_id (and an idempotency_key, optional but recommended). Answers 201 with the order.
  3. Poll GET /v1/swap/orders/{id} while status is not terminal: pending → sent → swapping → completed, or refunded / failed. GET /v1/swap/orders/{id}/detail adds the addresses, the send leg and a timeline.

The output lands on the user's own static wallet address and is credited to their balance; there is no destination to supply and none to validate.

USDT ⇄ TRX is traded on-chain, on TRON itself. The trade is signed by the user's own address and pays back to it, so it prices small amounts at the market rate — a few dollars swap as well as thousands. Its order goes pending → sent → completed within a minute or two; there is no swapping step. receive_minimum is a hard floor: if the market moves further before the trade lands, the trade reverts, the order ends failed and the held amount returns to the balance in full — nothing is traded and nothing is charged. received is what arrived, to the unit.

#Exchange

  1. Read the catalogue. GET /v1/exchange/assets lists what can be bought — thousands of coins, refreshed hourly — and GET /v1/exchange/chains where they can be paid to. asset there is the exchange's identifier (SOL.SOL, ETH.USDC-0xa0b8…), and it is exactly what buy_asset expects. Take it from the catalogue; a value we cannot route is refused outright.
  2. Quote. POST /v1/exchange/quote with sell_asset_id, buy_asset, amount and destination_address — the quote validates the address for that coin's chain.
  3. Create. POST /v1/exchange/orders with the same fields plus user_id. 201.
  4. Poll GET /v1/swap/orders/{id} — the same read, the same statuses. GET /v1/swap/orders lists both kinds.

Treat the buy-side numbers of an exchange as display estimates: the platform does not model that coin's chain, so it publishes the decimal it was given and stops rather than inventing a base-unit scale. The authoritative outcome is the settled order, not the quote.

#The fee

A percentage of the amount, with a dollar minimum, plus the order's own network cost, on the sell side. It is taken out of amount — send_amount = amount − fee − merchant_fee is published so the numbers add up — and fee already includes the network part, shown on its own as network_fee. Today's figures are on the price sheet; your own fee, if you set one, is merchant_fee on the quote and the order.

An amount the fee would swallow is refused with 400 invalid_amount, and the message says where swaps start right now.

#What can go wrong

AnswerMeaning
400 invalid_pairone side is not swappable — swappable: false on GET /v1/assets; leave it out of your picker
400 no_routethe exchange cannot carry this pair right now
400 invalid_amountmore decimal places than the sell asset supports, or too small to cover the fee — the message names today's smallest amount
409 insufficient_balancethe balance cannot cover amount
503 swap_disabled, swap_unavailable, exchange_errora dependency is down; retry later, unchanged

#Checklist

  • [ ] Buy-side identifiers for an exchange taken from GET /v1/exchange/assets, never constructed
  • [ ] receive_minimum shown as the floor, receive_estimate as the estimate
  • [ ] Orders polled on GET /v1/swap/orders/{id} — no webhook exists
  • [ ] Exchange buy-side amounts treated as display estimates until the order settles