Skip to main content

Getting Started

swapapi is a free token swap API that returns executable calldata. No API key, no account, no SDK — just a GET request and you get back a transaction ready to submit on-chain.

Base URL: https://api.swapapi.dev


Your first request

Swap 1 ETH for USDC on Ethereum mainnet:

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

That's it. There is no step 2.


The 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",
"tx": {
"from": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
"to": "0x011E52E4E40CF9498c79e329EBc29ed08c8B5abB",
"data": "0x2646478b...",
"value": "1000000000000000000",
"gasPrice": 30000000000,
"gas": "250000"
}
},
"timestamp": "2026-03-12T00:00:00.000Z"
}

Field reference

FieldTypeDescription
successbooleantrue if the request succeeded
data.statusstring"Successful", "Partial", or "NoRoute"
data.tokenFromobjectInput token metadata (address, symbol, name, decimals)
data.tokenToobjectOutput token metadata (address, symbol, name, decimals)
data.swapPricenumberExchange rate (output per input token)
data.priceImpactnumberPrice impact as a decimal (0.001 = 0.1%)
data.amountInstringInput amount in wei (same as your request)
data.expectedAmountOutstringGuaranteed minimum output amount in token's smallest unit
data.tx.fromstringYour sender address
data.tx.tostringRouter contract address
data.tx.datastringEncoded calldata — submit this on-chain
data.tx.valuestringNative token value to send (non-zero for native ETH swaps)
data.tx.gasPricenumberSuggested gas price in wei
data.tx.gasstringEstimated gas limit
timestampstringISO 8601 response timestamp

Submit the swap (curl + JSON-RPC)

You can go from quote to on-chain execution with nothing but curl. No libraries, no SDKs.

1. Get the quote

curl -s "https://api.swapapi.dev/v1/swap/8453?\
tokenIn=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&\
tokenOut=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913&\
amount=1000000000000000000&\
sender=0xYOUR_ADDRESS" | jq .

2. Sign the transaction locally

You need to sign the tx object from the response. Use cast (from Foundry):

# Using the tx fields from the response:
cast send \
--rpc-url https://mainnet.base.org \
--private-key 0xYOUR_PRIVATE_KEY \
0x011E52E4E40CF9498c79e329EBc29ed08c8B5abB \
--value 1000000000000000000 \
--gas-limit 250000 \
--data 0x2646478b...

3. Or use raw JSON-RPC

If you don't have cast, you can sign with any tool and broadcast the raw signed transaction via RPC:

# eth_sendRawTransaction — broadcast a signed transaction
curl -X POST https://mainnet.base.org \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_sendRawTransaction",
"params": ["0xSIGNED_TX_HEX"],
"id": 1
}'
{
"jsonrpc": "2.0",
"id": 1,
"result": "0xtransaction_hash..."
}

4. Check the result

# eth_getTransactionReceipt — check if it confirmed
curl -X POST https://mainnet.base.org \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_getTransactionReceipt",
"params": ["0xYOUR_TX_HASH"],
"id": 1
}'
The signing step

The API gives you unsigned transaction data. You must sign it with the sender's private key before broadcasting. This is the one step that requires a tool — cast, a wallet library, or any ECDSA signer. The API never touches your private key.

Full script (bash + cast)

A complete swap in one script, zero dependencies beyond curl and cast:

#!/bin/bash
set -e

RPC_URL="https://mainnet.base.org"
SENDER="0xYOUR_ADDRESS"
PRIVATE_KEY="0xYOUR_PRIVATE_KEY"

# 1. Get swap quote
RESPONSE=$(curl -s "https://api.swapapi.dev/v1/swap/8453?\
tokenIn=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&\
tokenOut=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913&\
amount=1000000000000000000&\
sender=$SENDER")

# 2. 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')
EXPECTED_OUT=$(echo "$RESPONSE" | jq -r '.data.expectedAmountOut')

echo "Swapping 1 ETH for minimum $(echo "scale=2; $EXPECTED_OUT / 1000000" | bc) USDC"

# 3. 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"

Quick reference

Endpoint: GET https://api.swapapi.dev/v1/swap/{chainId}
Auth: None
Rate limit: 60 requests/minute per IP
Chains: Ethereum (1), Base (8453), Arbitrum (42161), Polygon (137), Optimism (10), and more
OpenAPI spec: api.swapapi.dev/openapi.json