POST /swap, approve the exact input amount, estimate gas, send the transaction from the wallet and wait for the receipt. Olympex is non-custodial: it returns calldata and never signs or broadcasts the transaction.
You need API credentials and the signing helper from Sign requests, plus a wallet that holds the input token and native token for gas. If you haven’t quoted yet, start with Get a swap quote.
Prerequisites
OLYMPEX_API_KEY_ID,OLYMPEX_SECRET_KEYandOLYMPEX_PASSPHRASEin your server’s environment, andsign-request.tssaved next to your code.- Node.js 22.18 or later, which runs
.tsfiles directly, in an ES module project (npm pkg set type=module), and viem 2 (npm install viem). The same wallet steps with ethers v6 follow the steps. - An RPC URL for the chain, as
POLYGON_RPC_URLin this guide. - A wallet funded on that chain with the input token (10 USDT here) and POL for gas. The script reads its private key from
WALLET_PRIVATE_KEY.
Steps
1
Set up the clients and get a fresh quote
The snippets in these steps form one script, Quote right before you build with
execute-swap.ts. Run it with node execute-swap.ts.In a dApp, split the work. Your server signs the Olympex requests and returns the
POST /swap response to the browser; the user’s wallet approves and sends the transaction, for example through createWalletClient({ transport: custom(window.ethereum) }). Your API credentials never reach the browser.POST /quotes: a quote is not reserved, and prices move. See Slippage and price impact.2
Build the transaction with POST /swap
Send the same pair, amount, slippage and gas price hint as the quote, plus two fields:The same request from cURL or Python:A response looks like this, with the calldata shortened:
account: the wallet that sends the transaction and receives the output. The calldata is bound to it.aggregatorId: the liquidity source to build with.buildSwaptries the quote’s winner first and moves downaggregatorOrderwhen a source returns422 NO_ROUTEor500 SWAP_ERROR, or when its calldata reverts in the gas estimate (step 4).
fees object you sent with the quote.Response
Security model lists every check to run before a wallet signs.
3
Approve the exact input amount
For ERC-20 input, the wallet must allow
contractToApprove to spend the input amount. Approve exactly that amount, in base units of the input token, and never an unlimited amount. An approval takes at least a block, so build the swap again once it confirms: the calldata’s expiry window then starts after the approval.ensureAllowance resets any non-zero allowance to 0 before it approves, which costs one extra transaction on tokens that don’t need it. If you keep a list of tokens that require the reset, reset only for those. approveInput also checks the balance first, so a gas estimate that reverts in the next step points at the route itself.Native-token input. To sell the chain’s native token, set inTokenAddress to 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE. There is nothing to approve: the swap response sets value, in wei, and the transaction carries it. Keep extra native token in the wallet for gas. The uniswapV3Hermes source doesn’t support native-token input.4
Estimate gas, and fall back if the calldata reverts
Always run An estimate that reverts means the transaction would revert, so never send it.
eth_estimateGas on the exact transaction before you send it, and add a buffer (20% here). A 200 from POST /swap doesn’t guarantee that the calldata executes: a source can build calldata that reverts. Don’t size the gas limit from the quote’s estimatedGas either: it covers only the source’s part of the route, not the Olympex contracts. Use gasLimit from the response only when your RPC can’t produce an estimate, and never when it’s "0".approveInput has checked the balance and the allowance, and the calldata is seconds old, so the route as built can’t execute: the source built calldata that reverts, a market maker’s quote inside the route has already expired, or the price moved past your slippage. The loop builds the swap with the next source in aggregatorOrder, approves its spender if it differs, and estimates again. When no source is left, buildSwap throws: request a new quote and start again. A fallback source can return less, so show the user the new outAmount and minOutAmount before they sign. Gas and fees explains why gasLimit is only a fallback.5
Send the transaction right away
account, and another Olympex swap from the same account can invalidate it. Don’t queue or cache calldata; build it for each transaction.6
Wait for the receipt
GET /transactions/{hash}: it reports the same result, success or reverted. Track a swap to finality covers confirmations, timeouts and replaced transactions.Wallet steps with ethers v6
Wallet steps with ethers v6
This replaces steps 3 to 6 for a wallet built with ethers v6 (
npm install ethers). It reuses trade, isNative, swap, aggregatorId, revertedSources and buildSwap from steps 1 and 2. Unlike the viem version, it doesn’t fall back to gasLimit when the node returns an error: ethers reports any node error on eth_estimateGas as CALL_EXCEPTION, so it treats every such error as a revert and moves to the next source, and the gasLimit fallback runs only on network or HTTP errors.Verify
receipt.statusis"success", and the transaction appears on the chain’s block explorer (Polygonscan for Polygon) withtoset to thetofromPOST /swap.- The wallet received at least
minOutAmountof the output token. For ERC-20 output, add up the token’sTransferevents toaccountin the receipt:
Transfer event; compare the wallet’s native balance before and after instead, allowing for the gas you paid.
Common pitfalls
What’s next
Track a swap to finality
Confirmations, timeouts and replaced transactions.
Cross-chain swap end-to-end
The same flow across two chains.
Build a swap
Every field of
POST /swap.Security model
Approvals, calldata binding and the checks to run before signing.
