1inch Swap API Integration Guide for Crypto Traders
Learn how to integrate the 1inch Swap API to access DEX aggregation, get best swap rates, and automate trades across DeFi protocols with real code examples.
Learn how to integrate the 1inch Swap API to access DEX aggregation, get best swap rates, and automate trades across DeFi protocols with real code examples.
The 1inch Swap API is one of the most powerful tools in a DeFi trader's arsenal. Instead of manually comparing rates across Uniswap, Curve, Balancer, and dozens of other DEXes, 1inch does it automatically — splitting your order across multiple liquidity sources to get you the best possible execution price. If you've spent time trading on centralized platforms like Binance or OKX and want to bring that same efficiency to on-chain trading, this API is your bridge.
This guide walks through the full integration: authentication, fetching quotes, building swap transactions, and handling the edge cases that will bite you in production. By the end you'll have working code you can drop into a bot or trading dashboard.
1inch exposes a REST API that sits on top of its Pathfinder routing algorithm. The core flow is simple: you request a quote, get back an optimized route, then submit the transaction to your wallet. The API handles all the complexity of splitting orders across liquidity pools.
There are two main API versions in active use. v5 is stable and widely documented. v6 introduced Fusion mode — a gasless swap mechanism using Dutch auction orders. For most programmatic trading use cases, v5 gets you where you need to go. Fusion is worth exploring once you're comfortable with the basics.
Always use the /approve/spender endpoint to get the correct token approval address before sending any allowance transaction. Hardcoding contract addresses will break when 1inch upgrades their router contracts.
Start by registering at the 1inch Developer Portal to get your API key. The free tier is enough for development and low-frequency bots. For production systems handling real volume, the Pro tier removes rate limits and adds priority routing.
import requests
import os
from typing import Optional
API_KEY = os.environ.get("ONEINCH_API_KEY")
BASE_URL = "https://api.1inch.dev/swap/v6.0"
headers = {
"Authorization": f"Bearer {API_KEY}",
"accept": "application/json"
}
def get_quote(
chain_id: int,
src_token: str,
dst_token: str,
amount: str,
slippage: float = 1.0
) -> Optional[dict]:
"""Fetch a swap quote from 1inch API."""
url = f"{BASE_URL}/{chain_id}/quote"
params = {
"src": src_token,
"dst": dst_token,
"amount": amount, # in token's smallest unit (wei for ETH)
}
try:
response = requests.get(url, headers=headers, params=params, timeout=10)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
print(f"HTTP error: {e.response.status_code} - {e.response.text}")
return None
except requests.exceptions.RequestException as e:
print(f"Request failed: {e}")
return None
# Example: quote for 1 ETH -> USDC on Ethereum mainnet
ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"
USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
ONE_ETH = "1000000000000000000" # 1 ETH in wei
quote = get_quote(chain_id=1, src_token=ETH, dst_token=USDC, amount=ONE_ETH)
if quote:
usdc_out = int(quote["dstAmount"]) / 1e6
print(f"1 ETH = {usdc_out:.2f} USDC")
print(f"Estimated gas: {quote.get('gas', 'N/A')}")
Getting a quote is just the first step. To actually execute a swap you need to build the transaction data and submit it on-chain. The /swap endpoint returns everything your wallet needs: to, data, value, gas, and gasPrice. You sign and broadcast this through web3.py or ethers.js.
from web3 import Web3
RPC_URL = os.environ.get("ETH_RPC_URL") # Infura, Alchemy, or your own node
WALLET_ADDRESS = os.environ.get("WALLET_ADDRESS")
PRIVATE_KEY = os.environ.get("PRIVATE_KEY")
w3 = Web3(Web3.HTTPProvider(RPC_URL))
def build_swap_tx(
chain_id: int,
src_token: str,
dst_token: str,
amount: str,
from_address: str,
slippage: float = 1.0
) -> Optional[dict]:
"""Build swap transaction data from 1inch API."""
url = f"{BASE_URL}/{chain_id}/swap"
params = {
"src": src_token,
"dst": dst_token,
"amount": amount,
"from": from_address,
"slippage": slippage,
"disableEstimate": False,
"allowPartialFill": False
}
try:
response = requests.get(url, headers=headers, params=params, timeout=15)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
error_body = e.response.json()
print(f"Swap build failed: {error_body.get('description', e)}")
return None
def execute_swap(swap_data: dict) -> Optional[str]:
"""Sign and broadcast the swap transaction."""
tx = swap_data["tx"]
tx["nonce"] = w3.eth.get_transaction_count(WALLET_ADDRESS)
tx["chainId"] = 1
tx["gas"] = int(tx["gas"] * 1.25) # add 25% gas buffer
tx["value"] = int(tx["value"])
signed = w3.eth.account.sign_transaction(tx, private_key=PRIVATE_KEY)
tx_hash = w3.eth.send_raw_transaction(signed.rawTransaction)
return tx_hash.hex()
# Full swap execution
swap = build_swap_tx(
chain_id=1,
src_token=ETH,
dst_token=USDC,
amount=ONE_ETH,
from_address=WALLET_ADDRESS,
slippage=0.5
)
if swap:
tx_hash = execute_swap(swap)
print(f"Swap submitted: https://etherscan.io/tx/{tx_hash}")
Always add a gas buffer (15-25%) on top of the API's gas estimate. DeFi transactions touching multiple liquidity pools can fail at estimate time if pool state changes between quote and execution.
Swapping ERC-20 tokens (anything that's not native ETH) requires a token approval before the 1inch router can spend your tokens. Skip this step and your transactions will revert every time. The API provides a dedicated endpoint to get the exact router address and build the approval calldata.
const axios = require('axios');
const { ethers } = require('ethers');
const API_KEY = process.env.ONEINCH_API_KEY;
const BASE_URL = 'https://api.1inch.dev/swap/v6.0';
const apiClient = axios.create({
baseURL: BASE_URL,
headers: { Authorization: `Bearer ${API_KEY}` }
});
async function checkAndApproveToken(chainId, tokenAddress, amount, provider, signer) {
// Step 1: get the correct spender address
const { data: spenderData } = await apiClient.get(`/${chainId}/approve/spender`);
const spenderAddress = spenderData.address;
// Step 2: check current allowance
const erc20Abi = ['function allowance(address,address) view returns (uint256)',
'function approve(address,uint256) returns (bool)'];
const tokenContract = new ethers.Contract(tokenAddress, erc20Abi, signer);
const walletAddress = await signer.getAddress();
const currentAllowance = await tokenContract.allowance(walletAddress, spenderAddress);
if (currentAllowance.lt(ethers.BigNumber.from(amount))) {
console.log('Insufficient allowance, approving...');
// Use MaxUint256 to avoid repeated approvals
const approveTx = await tokenContract.approve(
spenderAddress,
ethers.constants.MaxUint256
);
await approveTx.wait();
console.log(`Approved: ${approveTx.hash}`);
} else {
console.log('Allowance sufficient, no approval needed');
}
}
// Usage example
const USDT = '0xdAC17F958D2ee523a2206206994597C13D831ec7';
const AMOUNT = ethers.utils.parseUnits('1000', 6).toString(); // 1000 USDT
const provider = new ethers.providers.JsonRpcProvider(process.env.ETH_RPC_URL);
const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
checkAndApproveToken(1, USDT, AMOUNT, provider, signer)
.then(() => console.log('Ready to swap'))
.catch(console.error);
The real power of the 1inch API shows up when you combine it with a signal layer. Platforms like VoiceOfChain stream real-time order flow signals — large buy walls appearing, whale accumulation patterns, sudden volume spikes. When you get a signal on a token, your bot can immediately fetch a 1inch quote, check if the price impact is acceptable, and execute within seconds.
Traders who stick to centralized platforms like Binance or Bybit miss the entire DeFi liquidity layer. Tokens listed on Uniswap and Curve often move 10-20 minutes before they show volume on Binance. By the time a token pumps on OKX or Coinbase, early DeFi buyers are already managing their exits. An automated pipeline — signal → quote check → on-chain execution — closes that window.
The workflow looks like this: VoiceOfChain detects unusual accumulation in a token's on-chain order flow. Your bot receives the signal via webhook or WebSocket, calls the 1inch quote endpoint to assess price impact and available liquidity, validates that slippage is within tolerance, then fires the swap. End to end, this can execute in under two seconds.
The 1inch API returns structured error responses. Common errors you'll hit in production: insufficient liquidity (code 1), cannot estimate (code 2 — usually means the swap would fail on-chain), and rate limit exceeded (HTTP 429). Build retry logic for transient failures but fail fast on structural errors like bad token addresses or zero liquidity.
Never submit a swap transaction without first re-fetching a fresh quote within the last 10-15 seconds. Quotes go stale fast in volatile markets and you can execute at a significantly worse price than expected.
The 1inch Swap API gives you programmatic access to the best DEX liquidity across every major chain. The integration is straightforward once you understand the quote → approve → swap flow, and the error surface is manageable with proper retry logic and fresh-quote discipline.
The real edge comes from pairing execution with good signal sources. Tools like VoiceOfChain surface on-chain order flow patterns before they become obvious on platforms like Binance or Coinbase. When your bot can detect a signal and execute an optimized on-chain swap within seconds, you're operating at a speed and efficiency that manual traders on KuCoin or Gate.io simply can't match. Start with the quote endpoint on testnet, validate your approval logic, then move to mainnet with small amounts until your error handling proves out.