What you’ll build:Documentation Index
Fetch the complete documentation index at: https://developers.zerion.io/llms.txt
Use this file to discover all available pages before exploring further.
- Get swap quotes from multiple liquidity sources in a single call
- Receive ready-to-sign approve and swap transactions — no separate quote/execute steps
- Bridge assets across chains (EVM ↔ EVM, EVM ↔ Solana)
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/quotes/with the sender, recipient, input asset, output asset, and amount - Receive multiple quotes — each includes the expected output, fees, and (when executable) ready-to-sign
transaction_approveandtransaction_swappayloads - Pick a quote and sign the transactions with your wallet
output_amount_after_fees.
Use the swap and bridge quotes endpoint.
liquidity_source — provider id, display name, and iconinput_amount / output_amount — what you’re sending and the estimated amount you’ll receive before slippage (quantity is the human-readable decimal; value / usd_value are fiat conversions when available)minimum_output_amount — guaranteed output after slippageoutput_amount_after_fees — net output once protocol, bridge, and network fees are subtracted; this is the field quotes are ranked byslippage_percent — actual slippage applied (the slippage_percent query parameter when provided, otherwise auto-chosen)protocol_fee / bridge_fee / network_fee — fee breakdown; each carries amount and an included_in_rate flag (whether already deducted from the rate)transaction_approve — ERC-20 approve transaction to sign first. Absent when not needed (Solana, EVM native-asset input, or sufficient allowance already granted)transaction_swap — swap transaction to sign. Absent when the quote is informational only (e.g. error is set)error — present when the quote can’t be executed as-is (e.g. not_enough_input_asset_balance)estimated_time_seconds — typically present on bridge routesQuotes are returned best-first. Before signing, check whether the chosen quote has an
error and a transaction_swap.const quote = data[0]; // best by output_amount_after_fees
const { error, transaction_approve, transaction_swap } = quote.attributes;
if (error) {
console.log(`Cannot execute: ${error.code} (hint: ${error.hint})`);
process.exit(1);
}
if (!transaction_swap) {
console.log("No transaction payload — informational quote only");
process.exit(1);
}
error.hint is a machine-readable next step (topup, increase_input_amount, unspecified) you can surface in your UI to guide the user.If
transaction_approve is present, sign and confirm it before submitting the swap. It’s a complete EVM transaction — no manual approve(spender, amount) call needed.import { ethers } from "ethers";
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
async function sendEVM(payload) {
// EVM numeric fields are hex strings — ethers accepts them directly
const tx = await signer.sendTransaction({
type: parseInt(payload.type, 16),
to: payload.to,
data: payload.data,
value: payload.value,
gasLimit: payload.gas,
nonce: parseInt(payload.nonce, 16),
chainId: parseInt(payload.chain_id, 16),
...(payload.max_fee
? { maxFeePerGas: payload.max_fee, maxPriorityFeePerGas: payload.max_priority_fee }
: { gasPrice: payload.gas_price }),
});
return tx.wait();
}
if (transaction_approve?.evm) {
console.log("Sending approval...");
await sendEVM(transaction_approve.evm);
console.log("Approval confirmed");
}
transaction_approve is omitted for Solana, for EVM swaps where the input is the chain’s native asset (ETH, MATIC, etc.), and when the wallet already has sufficient allowance.const receipt = await sendEVM(transaction_swap.evm);
console.log(`Confirmed in block ${receipt.blockNumber}`);
For Solana quotes,
transaction_swap.solana.raw is a base64-encoded raw transaction that you decode and sign with the Solana wallet of your choice (e.g. @solana/web3.js).To bridge tokens between chains, set a different
output[chain_id]. The to parameter is the recipient on the destination chain — set it to your wallet on that chain (use a base58 Solana address when bridging to Solana).# Bridge 1 USDC from Ethereum to Polygon
curl -g -u "YOUR_API_KEY:" \
"https://api.zerion.io/v1/swap/quotes/?from=YOUR_WALLET&to=YOUR_WALLET&input[chain_id]=ethereum&input[fungible_id]=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&input[amount]=1&output[chain_id]=polygon&output[fungible_id]=0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"
Use the List fungibles available for bridging endpoint to discover which tokens can be bridged between two specific chains before requesting quotes.
Key parameters
| Parameter | Description |
|---|---|
from | Wallet performing the swap. Must match the chain type of input[chain_id] (EVM hex or Solana base58). Required. |
to | Recipient of the output asset. Must match the chain type of output[chain_id]. For a same-chain swap to the same wallet, set equal to from. Required. |
input[chain_id] | Source chain (e.g., ethereum, polygon, solana). Required. |
input[fungible_id] | Input asset’s fungible ID — either a Zerion fungible ID (e.g., eth) or the token contract address. Required. |
input[amount] | Human-readable input amount as a decimal string (e.g., "0.05"), not the smallest unit. Required. |
output[chain_id] | Destination chain. Defaults to input[chain_id] (same-chain swap). |
output[fungible_id] | Output asset’s fungible ID or token contract address. Required. |
slippage_percent | Maximum acceptable slippage in percent. Auto-chosen when omitted. |
currency | Currency for fiat values in the response (e.g., usd). Defaults to usd. |