Swap API

Free token swaps for AI agents. No API keys. Returns executable transaction calldata for 40+ EVM chains.

Swap API

Executable token swap calldata in one GET request. No API keys. No accounts. No SDK bloat.

https://api.swapapi.dev

Quick Start

Swap 1 ETH for USDC on Ethereum:

curl "https://api.swapapi.dev/v1/swap/1?\
tokenIn=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&\
tokenOut=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&\
amount=1000000000000000000&\
sender=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"

That's it. The response contains everything you need to sign and broadcast.


Example Response

{
  "success": true,
  "data": {
    "status": "Successful",
    "tokenFrom": {
      "address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
      "symbol": "ETH",
      "name": "Ether",
      "decimals": 18
    },
    "tokenTo": {
      "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
      "symbol": "USDC",
      "name": "USD Coin",
      "decimals": 6
    },
    "swapPrice": 2435.12,
    "priceImpact": 0.0003,
    "amountIn": "1000000000000000000",
    "expectedAmountOut": "2435120000",
    "minAmountOut": "2422947280",
    "tx": {
      "from": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
      "to": "0x011E52E4E40CF9498c79e329EBc29ed08c8B5abB",
      "data": "0x2646478b...",
      "value": "1000000000000000000",
      "gasPrice": 30000000000,
      "gas": "250000"
    }
  },
  "timestamp": "2026-03-12T00:00:00.000Z"
}
FieldDescription
successBoolean indicating request success
data.status"Successful", "Partial", or "NoRoute"
data.tokenFrom/tokenToToken metadata (address, symbol, decimals)
data.swapPriceExchange rate
data.priceImpactSlippage impact (0.001 = 0.1%)
data.expectedAmountOutEstimated output in token's smallest unit
data.minAmountOutGuaranteed minimum (respects your maxSlippage)
data.txTransaction object ready to sign and send

API Reference

Endpoint: GET /v1/swap/{chainId}

Parameters:

ParamRequiredDescription
chainIdpathChain ID (1=Ethereum, 8453=Base, 42161=Arbitrum, etc.)
tokenInqueryInput token address. Use 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE for native ETH
tokenOutqueryOutput token address
amountqueryInput amount in smallest unit (e.g., wei for ETH)
senderqueryYour wallet address (used to build the tx)
maxSlippagequeryOptional. 0-1 (default: 0.005 = 0.5%)

Response codes:

  • 200 — Quote ready
  • 400 — Invalid params or unsupported chain
  • 429 — Rate limit exceeded (60/min per IP)
  • 502 — Upstream service error

More Curl Examples

Base (ETH → USDC)

curl "https://api.swapapi.dev/v1/swap/8453?\
tokenIn=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&\
tokenOut=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913&\
amount=500000000000000000&\
sender=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"

Arbitrum (USDC → ETH with 1% slippage)

curl "https://api.swapapi.dev/v1/swap/42161?\
tokenIn=0xaf88d065e77c8cC2239327C5EDb3A432268e5831&\
tokenOut=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&\
amount=1000000000&\
sender=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045&\
maxSlippage=0.01"

Ethereum Mainnet (DAI → USDC)

curl "https://api.swapapi.dev/v1/swap/1?\
tokenIn=0x6B175474E89094C44Da98b954EedeAC495271d0F&\
tokenOut=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&\
amount=1000000000000000000000&\
sender=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"

Polygon (MATIC → USDC)

curl "https://api.swapapi.dev/v1/swap/137?\
tokenIn=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&\
tokenOut=0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174&\
amount=10000000000000000000&\
sender=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"

Executing Swaps

The API gives you an unsigned transaction. Sign it and broadcast:

With Foundry cast

# 1. Set swap parameters
CHAIN_ID=8453
TOKEN_IN=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
TOKEN_OUT=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
AMOUNT=1000000000000000000
SENDER=0x...        # Your address
PRIVATE_KEY=0x...   # Your private key
RPC_URL=https://mainnet.base.org

# 2. Get swap quote
RESPONSE=$(curl -s "https://api.swapapi.dev/v1/swap/$CHAIN_ID?\
tokenIn=$TOKEN_IN&\
tokenOut=$TOKEN_OUT&\
amount=$AMOUNT&\
sender=$SENDER")

# 3. Parse the tx fields
TX_TO=$(echo "$RESPONSE" | jq -r '.data.tx.to')
TX_DATA=$(echo "$RESPONSE" | jq -r '.data.tx.data')
TX_VALUE=$(echo "$RESPONSE" | jq -r '.data.tx.value')
TX_GAS=$(echo "$RESPONSE" | jq -r '.data.tx.gas')

# 4. Sign and send
cast send \
  --rpc-url "$RPC_URL" \
  --private-key "$PRIVATE_KEY" \
  "$TX_TO" \
  --value "$TX_VALUE" \
  --gas-limit "$TX_GAS" \
  --data "$TX_DATA"

With viem

import { createWalletClient, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { base } from 'viem/chains'

const account = privateKeyToAccount('0x...')

const client = createWalletClient({
  account,
  chain: base,
  transport: http()
})

const response = await fetch(
  'https://api.swapapi.dev/v1/swap/8453?' +
  'tokenIn=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&' +
  'tokenOut=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913&' +
  'amount=1000000000000000000&' +
  'sender=' + account.address
)

const { data } = await response.json()

const hash = await client.sendTransaction({
  to: data.tx.to,
  data: data.tx.data,
  value: BigInt(data.tx.value),
  gas: BigInt(data.tx.gas)
})

await client.waitForTransactionReceipt({ hash })

MCP Server

For AI agents, Claude Desktop, Cursor, Cline, and other MCP clients:

npx @swapapi/mcp

Or add to Claude Desktop config:

{
  "mcpServers": {
    "swapapi": {
      "command": "npx",
      "args": ["@swapapi/mcp"]
    }
  }
}

See mcp/README.md for full MCP documentation.


OpenAPI Spec

See openapi.json for the full OpenAPI specification.


Limits

  • Rate limit: 60 requests/minute per IP
  • No authentication required
  • Free to use

License

MIT

Serveurs connexes