- Get swap quotes from multiple DEX aggregators in a single call
- Receive ready-to-sign transaction data — no separate quote/execute steps
- Handle token approvals before swapping
- Bridge assets across chains
Prerequisites
- A Zerion API key (get one here)
- A wallet address with tokens to swap
How it works
Unlike most swap APIs that require separate quote and execute endpoints, the Zerion API combines both into a single call:- Call
GET /v1/swap/offers/with the input token, output token, and amount - Receive multiple offers from providers (1inch, ParaSwap, 0x, etc.), each including a quote and a complete transaction object
- Pick the best offer and sign the transaction with your wallet
Use the swap offers endpoint to get quotes with ready-to-sign transactions.
estimation — expected output amount (output_quantity) and gas cost (gas)output_quantity_max — minimum guaranteed output after slippagetransaction — complete transaction object (to, from, data, value, gas, chain_id) ready to signliquidity_source — provider name and icon (1inch, ParaSwap, 0x, etc.)preconditions_met — whether the wallet has sufficient balance and token approvalfee — breakdown of protocol and integrator feesconst bestOffer = data[0]; // offers are sorted by best output amount
const { preconditions_met, asset_spender } = bestOffer.attributes;
if (!preconditions_met.enough_balance) {
console.log("Insufficient balance");
process.exit(1);
}
if (!preconditions_met.enough_allowance) {
// Token approval needed — see next step
console.log(`Approval needed for spender: ${asset_spender}`);
}
Native assets (ETH, MATIC, etc.) don’t require approvals. This step only applies when swapping ERC-20 tokens.
If
preconditions_met.enough_allowance is false, you need to approve the asset_spender contract to spend your tokens before submitting the swap transaction.import { ethers } from "ethers";
const ERC20_ABI = ["function approve(address spender, uint256 amount) returns (bool)"];
async function approveIfNeeded(offer, signer) {
const { preconditions_met, asset_spender } = offer.attributes;
if (preconditions_met.enough_allowance) return; // already approved
const tokenAddress = "0x6B175474E89094C44Da98b954EedeAC495271d0F"; // DAI
const token = new ethers.Contract(tokenAddress, ERC20_ABI, signer);
const tx = await token.approve(asset_spender, ethers.MaxUint256);
await tx.wait();
console.log("Approval confirmed");
}
import { ethers } from "ethers";
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
const bestOffer = data[0];
const { transaction } = bestOffer.attributes;
// Approve token if needed (skip for native assets like ETH)
await approveIfNeeded(bestOffer, signer);
// Sign and send the swap transaction
const tx = await signer.sendTransaction({
to: transaction.to,
data: transaction.data,
value: transaction.value,
gas: transaction.gas,
chainId: transaction.chain_id,
});
console.log(`Transaction sent: ${tx.hash}`);
const receipt = await tx.wait();
console.log(`Confirmed in block ${receipt.blockNumber}`);
To bridge tokens between chains, use the same endpoint — just set different
input[chain_id] and output[chain_id] values.# Bridge USDC from Ethereum to Polygon
curl -g -u "YOUR_API_KEY:" \
"https://api.zerion.io/v1/swap/offers/?input[from]=YOUR_WALLET&input[chain_id]=ethereum&input[asset_address]=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&input[amount]=1000000000&output[chain_id]=polygon&output[asset_address]=0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"
Use the List fungibles available for bridging endpoint to discover which tokens can be bridged between two specific chains before requesting offers.
Key parameters
| Parameter | Description |
|---|---|
input[from] | Your wallet address |
input[chain_id] | Source chain (e.g., ethereum, polygon, optimism) |
input[asset_address] | Token contract address to sell. Use 0xEeee...eEEeE for native assets |
input[amount] | Amount in the token’s smallest unit (e.g., wei for ETH) |
output[chain_id] | Destination chain (same as input for swaps, different for bridges) |
output[asset_address] | Token contract address to buy |
slippage_percent | Max slippage tolerance, 0–3%. Default: 2 |
liquidity_source_id | Filter to a specific provider, or all (default) |