# swapapi.xyz — Free Token Swap API ## What this is A free DEX aggregator API that returns executable swap calldata. No API keys, no authentication, no accounts required. ## Base URL https://api.swapapi.xyz ## Endpoint GET /v1/swap/{chainId}?tokenIn={address}&tokenOut={address}&amount={rawAmount}&sender={address}&maxSlippage={0-1} ## Parameters - chainId (path, required): Blockchain network ID. Supported: 1 (Ethereum), 42161 (Arbitrum), 8453 (Base), 10 (Optimism), 137 (Polygon), 56 (BSC), 43114 (Avalanche), 250 (Fantom), 100 (Gnosis), 59144 (Linea), 534352 (Scroll), 81457 (Blast), 5000 (Mantle), 34443 (Mode), 146 (Sonic), 80094 (Berachain), 143 (Monad), 4326 (MegaETH), 169 (Manta), 167000 (Taiko), 324 (zkSync Era), 1101 (Polygon zkEVM), 42170 (Arbitrum Nova), 42220 (Celo), 25 (Cronos), 2222 (Kava), 1088 (Metis), 314 (Filecoin), 1116 (Core), 288 (Boba), 56288 (Boba BNB), 199 (BTTC), 11235 (Haqq), 1666600000 (Harmony), 108 (ThunderCore), 7000 (ZetaChain), 2046399126 (SKALE Europa), 30 (Rootstock), 810180 (zkLink), 33139 (ApeChain), 43111 (Hemi), 129399 (Tatara), 747474 (Katana), 999 (HyperEVM), 9745 (Plasma), 196 (X Layer) - tokenIn (query, required): Input token contract address (0x format). Use 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE for native ETH. - tokenOut (query, required): Output token contract address (0x format) - amount (query, required): Amount of tokenIn in the token's smallest unit (e.g., 1 ETH = 1000000000000000000 with 18 decimals, 100 USDC = 100000000 with 6 decimals) - sender (query, required): Wallet address that will sign and send the transaction. The returned tx is only executable by this address. - maxSlippage (query, optional): Maximum slippage tolerance as a decimal 0-1 (default: 0.005 = 0.5%). Affects on-chain execution tolerance only, not the quoted expectedAmountOut. ## Notes - Addresses are case-insensitive: both checksummed (mixed-case) and lowercase are accepted. - The API does not validate on-chain balances or allowances. It always returns a quote and tx if a route exists, even if the sender cannot execute it. The transaction will revert on-chain if balance or approval is insufficient. - Fee-on-transfer (tax) tokens: the API may find a route, but expectedAmountOut will not account for the transfer tax. The actual received amount will be lower. Use higher maxSlippage for tax tokens. - For tokens not listed below, use an external token list (e.g., CoinGecko, token project docs) to find the contract address and decimals, then pass them to the API. - For RPC endpoints, see https://chainlist.org — search by chain name or ID to find public RPC URLs. - Typical API response time is 1-5 seconds. Set an HTTP timeout of 15 seconds. - This API is single-chain only. Cross-chain (bridge) swaps are not supported. ## Common Token Addresses Use 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE for the native gas token on any chain (always 18 decimals). ### Ethereum (1) — native: ETH - WETH (18 decimals): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 - USDC (6 decimals): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 - USDT (6 decimals): 0xdAC17F958D2ee523a2206206994597C13D831ec7 - DAI (18 decimals): 0x6B175474E89094C44Da98b954EedeAC495271d0F - WBTC (8 decimals): 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599 ### Base (8453) — native: ETH - WETH (18 decimals): 0x4200000000000000000000000000000000000006 - USDC (6 decimals): 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 - USDT (6 decimals): 0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2 - DAI (18 decimals): 0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb ### Arbitrum (42161) — native: ETH - WETH (18 decimals): 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1 - USDC (6 decimals): 0xaf88d065e77c8cC2239327C5EDb3A432268e5831 - USDT (6 decimals): 0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9 - DAI (18 decimals): 0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1 ### Polygon (137) — native: POL (formerly MATIC) - WPOL (18 decimals): 0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270 - USDC (6 decimals): 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359 - USDT (6 decimals): 0xc2132D05D31c914a87C6611C10748AEb04B58e8F - DAI (18 decimals): 0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063 ### BSC (56) — native: BNB - WBNB (18 decimals): 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c - USDC (18 decimals): 0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d — NOTE: 18 decimals on BSC, not 6 - USDT (18 decimals): 0x55d398326f99059fF775485246999027B3197955 — NOTE: 18 decimals on BSC, not 6 - DAI (18 decimals): 0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3 ### Optimism (10) — native: ETH - WETH (18 decimals): 0x4200000000000000000000000000000000000006 - USDC (6 decimals): 0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85 - USDT (6 decimals): 0x94b008aA00579c1307B0EF2c499aD98a8ce58e58 - DAI (18 decimals): 0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1 ### Avalanche (43114) — native: AVAX - WAVAX (18 decimals): 0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7 - USDC (6 decimals): 0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E - USDT (6 decimals): 0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7 - DAI (18 decimals): 0xd586E7F844cEa2F87f50152665BCbc2C279D8d70 ### Gnosis (100) — native: xDAI - WXDAI (18 decimals): 0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d - USDC (6 decimals): 0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83 - USDT (6 decimals): 0x4ECaBa5870353805a9F068101A40E0f32ed605C6 - WETH (18 decimals): 0x6A023CCd1ff6F2045C3309768eAd9E68F978f6e1 ### Linea (59144) — native: ETH - WETH (18 decimals): 0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f - USDC (6 decimals): 0x176211869cA2b568f2A7D4EE941E073a821EE1ff - USDT (6 decimals): 0xA219439258ca9da29E9Cc4cE5596924745e12B93 - DAI (18 decimals): 0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5 ### Scroll (534352) — native: ETH - WETH (18 decimals): 0x5300000000000000000000000000000000000004 - USDC (6 decimals): 0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4 - USDT (6 decimals): 0xf55BEC9cafDbE8730f096Aa55dad6D22d44099Df - DAI (18 decimals): 0xcA77eB3fEFe3725Dc33bccB54eDEFc3D9f764f97 ### Fantom (250) — native: FTM - WFTM (18 decimals): 0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83 - USDC (6 decimals): 0x28a92dde19D9989F39A49905d7C9C2FAc7799bDf - USDT (6 decimals): 0xcc1b99dDac1a33c201a742A1851662E87BC7f22C — Stargate bridged - DAI (18 decimals): 0x8D11eC38a3EB5E956B052f67Da8Bdc9bef8Abf3E ### zkSync Era (324) — native: ETH - WETH (18 decimals): 0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91 - USDC (6 decimals): 0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4 - USDT (6 decimals): 0x493257fD37EDB34451f62EDf8D2a0C418852bA4C ### Blast (81457) — native: ETH - WETH (18 decimals): 0x4300000000000000000000000000000000000004 - USDB (18 decimals): 0x4300000000000000000000000000000000000003 — Blast's native stablecoin (no canonical USDC/USDT on Blast) ### Mantle (5000) — native: MNT - WMNT (18 decimals): 0x78c1b0c915c4faa5fffa6cabf0219da63d7f4cb8 - USDC (6 decimals): 0x09Bc4E0D864854c6aFB6eB9A9cdF58aC190D0dF9 - USDT (6 decimals): 0x201EBa5CC46D216Ce6DC03F6a759e8E766e956aE ### Mode (34443) — native: ETH - WETH (18 decimals): 0x4200000000000000000000000000000000000006 - USDC (6 decimals): 0xd988097fb8612cc24eeC14542bC03424c656005f - USDT (6 decimals): 0xf0F161fDA2712DB8b566946122a5af183995e2eD ### Sonic (146) — native: S - wS (18 decimals): 0x039e2fb66102314ce7b64ce5ce3e5183bc94ad38 - USDC (6 decimals): 0x29219dd400f2Bf60E5a23d13Be72B486D4038894 - USDT (6 decimals): 0x6047828dc181963ba44974801ff68e538da5eaf9 ### Berachain (80094) — native: BERA - WBERA (18 decimals): 0x6969696969696969696969696969696969696969 - USDC (6 decimals): 0x549943e04f40284185054145c6E4e9568C1D3241 - USDT (6 decimals): 0x779Ded0c9e1022225f8e0630b35a9b54bE713736 ### Monad (143) — native: MON - WMON (18 decimals): 0x3bd359c1119da7da1d913d1c4d2b7c461115433a - USDC (6 decimals): 0x754704BC059F8C67012fEd69Bc8a327a5aAfB603 ### MegaETH (4326) — native: ETH - WETH (18 decimals): 0x4200000000000000000000000000000000000006 - No standard USDC/USDT. Uses USDT0 and USDm — check token project docs for addresses. ### Manta (169) — native: ETH - WETH (18 decimals): 0x0Dc808adcE2099A9F62AA87D9670745AbA741746 - USDC (6 decimals): 0xb73603C5d87fA094B7314C74ACE2e64D165016fb - USDT (6 decimals): 0xf417F5A458eC102B90352F697D6e2Ac3A3d2851f ### Taiko (167000) — native: ETH - WETH (18 decimals): 0xa51894664A773981C6C112C43ce576f315d5b1B6 - USDC (6 decimals): 0x07d83526730c7438048D55A4fc0b850e2aaB6f0b - USDT (6 decimals): 0x2DEF195713CF4a606B49D07E520e22C17899a736 - DAI (18 decimals): 0x7d02A3E0180451B17e5D7f29eF78d06F8117106C ### Polygon zkEVM (1101) — native: ETH - WETH (18 decimals): 0x4F9A0e7FD2Bf6067db6994CF12E4495Df938E6e9 - USDC (6 decimals): 0xA8CE8aee21bC2A48a5EF670afCc9274C7bbbC035 - USDT (6 decimals): 0x1E4a5963aBFD975d8c9021ce480b42188849D41d - DAI (18 decimals): 0xC5015b9d9161Dca7e18e32f6f25C4aD850731Fd4 ### Arbitrum Nova (42170) — native: ETH - WETH (18 decimals): 0x722E8BdD2ce80A4422E880164f2079488e115365 - USDC (6 decimals): 0x750ba8b76187092B0D1E87E28daaf484d1b5273b - USDT (6 decimals): 0xeD9d63a96c27f87B07115b56b2e3572827F21646 - DAI (18 decimals): 0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1 ### Celo (42220) — native: CELO - WCELO (18 decimals): 0x471EcE3750Da237f93B8E339c536989b8978a438 - USDC (6 decimals): 0xcebA9300f2b948710d2653dD7B07f33A8B32118C - USDT (6 decimals): 0x88eeC49252c8cbc039DCdB394c0c2BA2f1637EA0 - DAI (18 decimals): 0x90Ca507a5D4458a4C6C6249d186b6dCb02a5BCcd ### Cronos (25) — native: CRO - WCRO (18 decimals): 0x5C7F8A570d578ED84E63fdFA7b1eE72dEae1AE23 - USDC (6 decimals): 0xc21223249CA28397B4B6541dfFaEcC539BfF0c59 - USDT (6 decimals): 0x66e428c3f67a68878562e79A0234c1F83c208770 ### Kava (2222) — native: KAVA - WKAVA (18 decimals): 0xc86c7C0eFBD6A49B35E8714C5f59D99De09A225b - axlUSDC (6 decimals): 0xEB466342C4d449BC9f53A865D5Cb90586f405215 — Axelar-bridged USDC - USDT (6 decimals): 0x919C1c267BC06a7039e03fcc2eF738525769109c ### Metis (1088) — native: METIS - WMETIS (18 decimals): 0x75cb093E4D61d2A2e65D8e0BBb01DE8d89b53481 - USDC (6 decimals): 0xEA32A96608495e54156Ae48931A7c20f0dcc1a21 - USDT (6 decimals): 0xbB06DCA3AE6887fAbF931640f67cab3e3a16F4dC - DAI (18 decimals): 0x4c078361FC9BbB78DF910800A991C7c3DD2F6ce0 ### Filecoin (314) — native: FIL - WFIL (18 decimals): 0x60E1773636CF5E4A227d9AC24F20fEca034ee25A - USDC (6 decimals): 0xEB466342C4d449BC9f53A865D5Cb90586f405215 - DAI (18 decimals): 0x5C7e299CF531eb66f2A1dF637d37AbB78e6200C7 ### Core (1116) — native: CORE - WCORE (18 decimals): 0x40375C92d9FAf44d2f9db9Bd9ba41a3317a2404f - USDC (6 decimals): 0xa4151B2B3e269645181DcCF2D426cE75FcbDeca9 - USDT (6 decimals): 0x900101d06A7426441Ae63e9AB3B9b0F63Be145F1 ### Boba (288) — native: ETH - WETH (18 decimals): 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000 - USDC (6 decimals): 0x66a2A913e447d6b4BF33EFbec43aAeF87890FBbc - USDT (6 decimals): 0x5DE1677344D3Cb0D7D465c10b72A8f60699C062d - DAI (18 decimals): 0xf74195Bb8a5cf652411867c5C2C5b8C2a402be35 ### SKALE Europa (2046399126) — native: sFUEL (free gas) - USDC (6 decimals): 0x5F795bb52dAC3085f578f4877D450e2929D2F13d - USDT (6 decimals): 0x1c0491E3396AD6a35f061c62387a95d7218FC515 - DAI (18 decimals): 0xD05C4be5f3be302d376518c9492EC0147Fa5A718 ### Rootstock (30) — native: RBTC - WRBTC (18 decimals): 0x542fDA317318eBf1d3DeAF76E0B632741A7e677d - USDC (18 decimals): 0x1bda44fda023f2af8280a16fd1b01d1a493ba6c4 — NOTE: 18 decimals on Rootstock, not 6 - USDT (18 decimals): 0xef213441a85df4d7acbdae0cf78004e1e486bb96 — NOTE: 18 decimals on Rootstock, not 6 - DAI (18 decimals): 0x6b1a73d547f4009a26b8485b63d7015d248ad406 ### zkLink (810180) — native: ETH - WETH (18 decimals): 0x8280a4e7D5B3B658ec4580d3Bc30f5e50454F169 - USDC (6 decimals): 0x1a1A3b2ff016332e866787B311fcB63928464509 - USDT (6 decimals): 0x2F8A25ac62179B31D62D7F80884AE57464699059 - DAI (18 decimals): 0xF573fA04A73d5AC442F3DEa8741317fEaA3cDeab ### ApeChain (33139) — native: APE - WAPE (18 decimals): 0x48b62137EdfA95a428D35C09E44256A739F6B557 - No standard USDC/USDT. Uses APE_USD — check token project docs for address. ### Hemi (43111) — native: ETH - WETH (18 decimals): 0x4200000000000000000000000000000000000006 - USDC (6 decimals): 0xaD11a8Beb98bBF61dBb1AA0f6D6f2eCd87b35AFa - USDT (6 decimals): 0xBb0D083fb1be0A9f6157Ec484B6C79e0A4E31c2E ### HyperEVM (999) — native: HYPE - WHYPE (18 decimals): 0x5555555555555555555555555555555555555555 - USDT (6 decimals): 0xB8CE59Fc3717ada4c02EADF9682A9e934F625ebb - No canonical USDC on HyperEVM yet. ### Plasma (9745) — native: pETH - WXPL (18 decimals): 0x6100e367285b01f48d07953803a2d8dca5d19873 - USDT (6 decimals): 0xB8CE59Fc3717ada4c02EADF9682A9e934F625ebb ### X Layer (196) — native: OKB - WOKB (18 decimals): 0xe538905cf8410324e03a5a23c1c177a474d59b2b - USDC (6 decimals): 0x74b7F16337b8972027F6196A17a631aC6dE26d22 - USDT (6 decimals): 0x1E4a5963aBFD975d8c9021ce480b42188849D41d ### Boba BNB (56288) — native: BOBA (wrapped native) - WBOBA (18 decimals): 0xC58aaD327D6D58D979882601BA8DDa0685b505ea — wrapped native gas token - USDC (18 decimals): 0x9F98f9F312d23d078061962837042b8918E6aff2 — NOTE: 18 decimals - USDT (18 decimals): 0x1E633Dcd0d3D349126983D58988051F7c62c543D — NOTE: 18 decimals ### BTTC (199) — native: BTT - WBTT (18 decimals): 0x23181F21DEa5936e24163FFABa4Ea3B316B57f3C - USDC (6 decimals): 0xAE17940943BA9440540940DB0F1877f101D39e8b - USDT (6 decimals): 0xE887512ab8bc60BcC9224e1c3b5Be68E26048B8b ### Haqq (11235) — native: ISLM - WISLM (18 decimals): 0xeC8CC083787c6e5218D86f9FF5f28d4cC377AC54 - USDC (6 decimals): 0x80b5a32E4F032B2a058b4F29EC95EEfEEB87aDcd - USDT (6 decimals): 0xd567B3d7B8FE3C79a1AD8dA978812cfC4Fa05e75 - DAI (18 decimals): 0xC5e00D3b04563950941f7137B5afA3a534F0D6d6 ### Harmony (1666600000) — native: ONE - WONE (18 decimals): 0xcF664087a5bB0237a0BAd6742852ec6c8d69A27a - USDC (6 decimals): 0x985458E523dB3d53125813eD68c274899e9DFab4 - USDT (6 decimals): 0x3C2B8Be99c50593081EAA2A724F0B8285F5aBa8f - DAI (18 decimals): 0xEf977d2f931C1978Db5F6747666fa1eACB0d0339 ### ThunderCore (108) — native: TT - WTT (18 decimals): 0x413cEFeA29F2d07B8F2aCFA69d92466B9535f717 - USDC (6 decimals): 0x22e89898A04eaf43379BeB70bf4E38b1faf8A31e - USDT (6 decimals): 0x4f3C8E20942461e2c3Bdd8311AC57B0c222f2b82 ### ZetaChain (7000) — native: ZETA - WZETA (18 decimals): 0x5F0b1a82749cb4E2278EC87F8BF6B618dC71a8bf - USDC.ETH (6 decimals): 0x0cbe0dF132a6c6B4a2974Fa1b7Fb953CF0Cc798a - USDT.ETH (6 decimals): 0x7c8dDa80BBbe1254a7aACf3219EBE1481c6e01d7 ### Tatara (129399) — native: ETH (testnet) - AUSD (6 decimals): 0xa9012a055Bd4e0eDff8Ce09F960291C09d5322dc ### Katana (747474) — native: ETH - WETH (18 decimals): 0xeE7D8BcFB72bC1880D0cf19822Eb0a2e6577ab62 - USDC (6 decimals): 0x203a662b0Bd271A6eD5A60EdFbD04bfcE608fD36 - USDT (6 decimals): 0x2Dca96907FDE857Dd3D816880A0Df407Eeb2D2F2 ## Example Requests ### Native-to-ERC20: Swap 1 ETH for USDC on Ethereum curl "https://api.swapapi.xyz/v1/swap/1?tokenIn=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&tokenOut=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&amount=1000000000000000000&sender=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" ### ERC20-to-ERC20: Swap 1000 USDT for WETH on Optimism (requires ERC-20 approval first) curl "https://api.swapapi.xyz/v1/swap/10?tokenIn=0x94b008aA00579c1307B0EF2c499aD98a8ce58e58&tokenOut=0x4200000000000000000000000000000000000006&amount=1000000000&sender=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045&maxSlippage=0.01" ## Response Format All responses use an envelope: { success: boolean, data: {...} | undefined, error: {...} | undefined, timestamp: string } ### Success Response (200) { "success": true, "data": { "status": "Successful", "tokenFrom": { "address": "0xEeee...EeE", "symbol": "ETH", "name": "Ether", "decimals": 18 }, "tokenTo": { "address": "0xA0b8...eB48", "symbol": "USDC", "name": "USD Coin", "decimals": 6 }, "swapPrice": 0.0000000025, // raw ratio: expectedAmountOut / amountIn. Human price = (expectedAmountOut / 10^tokenTo.decimals) / (amountIn / 10^tokenFrom.decimals) "priceImpact": -0.0012, // price impact as decimal (-0.0012 = -0.12%), negative = unfavorable "amountIn": "1000000000000000000", "expectedAmountOut": "2500000000", // best-case output amount "minAmountOut": "2487500000", // minimum accepted = expectedAmountOut × (1 − maxSlippage). Tx reverts below this. "tokens": [ // ordered: tokenIn first, intermediaries (if multi-hop), tokenOut last { "address": "0xEeee...EeE", "symbol": "ETH", "name": "Ether", "decimals": 18 }, { "address": "0xA0b8...eB48", "symbol": "USDC", "name": "USD Coin", "decimals": 6 } ], "tx": { "from": "0x...sender", // same as input sender "to": "0x...router", // DEX router contract to call "data": "0x...calldata", // ABI-encoded swap calldata — treat as opaque, do not decode or modify "value": "1000000000000000000", // native token amount in wei (for native→token swaps, "0" otherwise). For Partial status, reflects the partial amount. "gasPrice": 112737152 // suggested gas price in wei (number) }, "rpcUrl": "https://cloudflare-eth.com", // recommended public RPC (same as rpcUrls[0]) "rpcUrls": ["https://cloudflare-eth.com", "https://eth.llamarpc.com", "https://rpc.ankr.com/eth", "https://ethereum-rpc.publicnode.com", "https://1rpc.io/eth"] // up to 5 ranked RPCs — use as fallback list }, "timestamp": "2026-03-12T00:00:00.000Z" } ### Error Response (400 / 429 / 502) { "success": false, "error": { "code": "INVALID_PARAMS", "message": "Human-readable error description", "details": {} }, "timestamp": "2026-03-12T00:00:00.000Z" } ### Partial Response (200) Same shape as Successful, but amountIn and expectedAmountOut reflect the partial fill, not the original request: { "success": true, "data": { "status": "Partial", "tokenFrom": { "address": "0xEeee...EeE", "symbol": "ETH", "name": "Ether", "decimals": 18 }, "tokenTo": { "address": "0xA0b8...eB48", "symbol": "USDC", "name": "USD Coin", "decimals": 6 }, "swapPrice": 0.0000000025, "priceImpact": -0.005, "amountIn": "500000000000000000", "expectedAmountOut": "1250000000", "minAmountOut": "1243750000", "tokens": [ { "address": "0xEeee...EeE", "symbol": "ETH", "name": "Ether", "decimals": 18 }, { "address": "0xA0b8...eB48", "symbol": "USDC", "name": "USD Coin", "decimals": 6 } ], "tx": { "from": "0x...sender", "to": "0x...router", "data": "0x...calldata", "value": "500000000000000000", "gasPrice": 112737152 }, "rpcUrl": "https://cloudflare-eth.com", "rpcUrls": ["https://cloudflare-eth.com", "https://eth.llamarpc.com", "https://rpc.ankr.com/eth"] }, "timestamp": "2026-03-12T00:00:00.000Z" } ### NoRoute Response (200) { "success": true, "data": { "status": "NoRoute", "rpcUrl": "https://cloudflare-eth.com", "rpcUrls": ["https://cloudflare-eth.com", "https://eth.llamarpc.com"] }, "timestamp": "2026-03-12T00:00:00.000Z" } ## Status Values All three status values return HTTP 200. Check data.status to distinguish them. rpcUrl and rpcUrls may be present on any status. - "Successful" (HTTP 200) — full route found. All fields (tokenFrom, tokenTo, swapPrice, priceImpact, amountIn, expectedAmountOut, minAmountOut, tokens, tx) are present. The tx is ready to execute. - "Partial" (HTTP 200) — only part of the requested amount can be filled. amountIn, expectedAmountOut, and tx.value reflect the partial amount (not the original request). tx is present and executable for the partial fill. Compare response amountIn to your requested amount to detect partial fills. You may: (a) execute the partial swap as-is, (b) reduce your amount to match the partial fill and re-request, or (c) try a different token pair. Do not retry the same amount in a loop — the liquidity cap won't change. - "NoRoute" (HTTP 200) — no swap route found for this pair. Only status is guaranteed present; tx, swapPrice, expectedAmountOut, and other routing fields are absent. Try a different token pair, amount, or chain. ## Error Codes - INVALID_PARAMS (400) — missing or malformed query parameters (including invalid token addresses). Do not retry — fix the request. - UNSUPPORTED_CHAIN (400) — chainId not supported. Do not retry — use a supported chain. - RATE_LIMITED (429) — too many requests. The API allows approximately 30 requests per minute per IP. Wait 5-10 seconds before retrying with exponential backoff. - UPSTREAM_ERROR (502) — routing engine temporarily unavailable. Retry after 2-5 seconds, up to 3 attempts. The error `details` field may contain additional diagnostic info (treat as opaque/optional). ## How to Use the Response 1. Check success === true 2. Check data.status === "Successful" 3. To get the human-readable output amount: divide expectedAmountOut by 10^(tokenTo.decimals). Example: expectedAmountOut "2500000000" with decimals 6 = 2500.0 USDC 4. To get the human-readable swap price: (expectedAmountOut / 10^tokenTo.decimals) / (amountIn / 10^tokenFrom.decimals). Example: (2500000000 / 10^6) / (1000000000000000000 / 10^18) = 2500.0 USDC per ETH - expectedAmountOut is the best-case output. minAmountOut is the on-chain minimum (= expectedAmountOut × (1 − maxSlippage)), already encoded in the calldata. The transaction reverts if actual output falls below minAmountOut. 5. If tokenIn is NOT the native gas token, the sender must first approve data.tx.to to spend at least amountIn of tokenIn. Call the tokenIn contract's `approve(address spender, uint256 amount)` where spender = data.tx.to and amount >= amountIn. You may use type(uint256).max for unlimited approval to avoid repeated approvals. Note: USDT on Ethereum requires setting allowance to 0 before setting a new non-zero allowance — call approve(spender, 0) first if the current allowance is non-zero. Wait for the approval transaction to be confirmed (mined) before fetching a fresh swap quote and submitting the swap transaction — the calldata is time-sensitive (30s), so fetch a new quote after approval confirms rather than reusing a stale one. 6. Check priceImpact before executing — consider rejecting swaps with priceImpact below -0.05 (-5%) to avoid excessive slippage on low-liquidity pairs. 7. data.rpcUrls is an array of up to 5 recommended public RPCs for this chain, ranked by quality (sourced from Chainlist, refreshed hourly). data.rpcUrl is the single best one (same as rpcUrls[0]) for backward compatibility. Use rpcUrls as a fallback list — if one RPC fails or times out, try the next. If you prefer your own RPCs or need more options, fetch the full list from https://chainlist.org/rpcs.json (JSON array of chains with RPC lists). If both rpcUrl and rpcUrls are absent, find RPCs at https://chainlist.org for the chain ID. 8. The caller must estimate gas using eth_estimateGas with the tx object and add a 20% buffer (multiply by 1.2) to avoid out-of-gas reverts on complex multi-hop routes. The tx object never contains a gasLimit field — you must always supply it from your own estimate. gasPrice is a suggested legacy gas price in wei — on EIP-1559 chains, most wallet libraries (ethers.js, viem, web3.py) will automatically use appropriate maxFeePerGas/maxPriorityFeePerGas if you omit gasPrice when sending. If eth_estimateGas fails, the swap would likely revert — do not submit without a successful gas estimate. 9. Submit data.tx on-chain (data.tx.to, data.tx.data, data.tx.value) using any wallet or signer library. Submit within 30 seconds — calldata includes a deadline and prices shift, so always re-fetch a fresh quote if more than 30 seconds have passed. ## Simulation & Best Practices ### Simulate with eth_call Before sending a real transaction, call eth_call with the full tx object against an RPC (use data.rpcUrls as a fallback list, or your own). If eth_call reverts, the swap would fail on-chain — do not submit. Common revert reasons: insufficient balance, missing ERC-20 approval, expired deadline (quote older than 30s). eth_call is free (no gas cost) and is the safest pre-flight check. ### Pre-flight checklist (recommended order) 1. Fetch quote from API 2. If ERC-20 input: check allowance(sender, tx.to) >= amountIn on the tokenIn contract. If insufficient, approve first, wait for confirmation, then re-fetch a fresh quote. 3. Check sender balance: native balance >= tx.value (for native input) or tokenIn.balanceOf(sender) >= amountIn (for ERC-20 input) 4. eth_estimateGas with the tx object — if it fails, the swap would revert. Do not submit. 5. eth_call with the tx object — if it reverts, do not submit. 6. Submit within 30 seconds of the original quote fetch. ## Field Types - amountIn, expectedAmountOut, minAmountOut, tx.value: string (BigInt serialized as string to avoid JavaScript precision loss) - gasPrice: number (fits safely in a JS number) - swapPrice, priceImpact: number (floating point) - rpcUrl: string (HTTPS URL, optional — same as rpcUrls[0], may be absent if no public RPC is known for the chain) - rpcUrls: string[] (array of up to 5 HTTPS URLs ranked by quality, optional — use as fallback list) - All other fields: string or number as shown in the example ## Other Endpoints - GET /health — returns { success: true, data: { status: "ok" } } - GET /v1/swap/examples — returns code examples in curl, TypeScript, Python, and Rust - GET /openapi.json — OpenAPI 3.1.0 specification - GET /docs — Swagger UI ## Links - API: https://api.swapapi.xyz - Site: https://swapapi.xyz - OpenAPI: https://api.swapapi.xyz/openapi.json - GitHub: https://github.com/swap-api/swap-api