No authentication
A raw HTTP GET is all you need. No headers, no tokens, no state. Any process that can make an HTTP request can use this API.
Last updated:
swapapi is the only DEX aggregator API that AI agents can use without API keys. A single GET request returns executable calldata — no authentication, no SDK, no state management.
The problem
AI agents — built with ChatGPT, Claude, LangChain, AutoGPT, and similar frameworks — increasingly need to interact with DeFi protocols. But every major DEX aggregator API requires API key registration.
This creates a fundamental bottleneck. The agent can reason about trades, analyze market conditions, and decide when to swap — but it can't execute without human-provisioned API keys.
The solution
A raw HTTP GET is all you need. No headers, no tokens, no state. Any process that can make an HTTP request can use this API.
One GET request returns everything: quote, calldata, RPC URLs. No multi-step flows, no session management.
Same URL structure, same response format, every time. No versioning surprises, no breaking changes to tool definitions.
No need to configure RPC providers. The response includes up to 5 ranked public RPCs for the target chain.
All large numbers are strings. No precision loss in JSON parsing — critical for agents that process amounts programmatically.
Machine-readable error codes (INVALID_PARAMS, UNSUPPORTED_CHAIN, RATE_LIMITED). Agents can branch on error type without parsing messages.
Integration patterns
swapapi serves /.well-known/ai-plugin.json — the standard ChatGPT plugin manifest. The OpenAPI spec at /openapi.json enables function calling out of the box.
{ "schema_version": "v1", "name_for_human": "Token Swap API", "name_for_model": "swap_tokens", "description_for_model": "Swap ERC-20 tokens on 46 EVM chains. No API key needed.", "auth": { "type": "none" }, "api": { "type": "openapi", "url": "https://api.swapapi.dev/openapi.json" } }
Define swapapi as a tool in Claude's tool use format. The agent can call it directly with structured parameters.
{ "name": "swap_tokens", "description": "Swap ERC-20 tokens on any of 46 EVM chains. Returns executable calldata.", "input_schema": { "type": "object", "properties": { "chainId": { "type": "number", "description": "EVM chain ID (e.g., 1 for Ethereum)" }, "tokenIn": { "type": "string", "description": "Input token address" }, "tokenOut": { "type": "string", "description": "Output token address" }, "amount": { "type": "string", "description": "Amount in smallest unit" }, "sender": { "type": "string", "description": "Wallet address" } }, "required": ["chainId", "tokenIn", "tokenOut", "amount", "sender"] } }
A simple Python tool definition that any LangChain or LlamaIndex agent can call directly.
from langchain.tools import tool import requests @tool def swap_tokens(chain_id: int, token_in: str, token_out: str, amount: str, sender: str) -> dict: """Swap ERC-20 tokens on any EVM chain. No API key needed.""" response = requests.get( f"https://api.swapapi.dev/v1/swap/{chain_id}", params={"tokenIn": token_in, "tokenOut": token_out, "amount": amount, "sender": sender} ) return response.json()
Safety
When AI agents execute swaps without human oversight, safety checks are critical. Build these into your agent's logic.
priceImpact — reject swaps where price impact is below -0.05 (-5%)eth_call before submitting the transaction on-chainminAmountOut as your safety net — the transaction reverts if slippage exceeds toleranceComplete example
A complete TypeScript function that gets a quote, validates safety constraints, and returns the transaction ready to sign.
async function executeSwap(params: { chainId: number; tokenIn: string; tokenOut: string; amount: string; sender: string; maxPriceImpact?: number; }) { const url = `https://api.swapapi.dev/v1/swap/${params.chainId}?` + new URLSearchParams({ tokenIn: params.tokenIn, tokenOut: params.tokenOut, amount: params.amount, sender: params.sender, }); const res = await fetch(url); const { success, data } = await res.json(); if (!success) throw new Error("API request failed"); if (data.status === "NoRoute") throw new Error("No swap route found"); if (data.status === "Partial") throw new Error("Only partial fill available"); // Safety check: reject high price impact const maxImpact = params.maxPriceImpact ?? -0.05; if (data.priceImpact < maxImpact) { throw new Error(`Price impact ${data.priceImpact} exceeds limit ${maxImpact}`); } return { tx: data.tx, expectedOutput: data.expectedAmountOut, minOutput: data.minAmountOut, priceImpact: data.priceImpact, rpcUrl: data.rpcUrl, }; }
See also: full integration tutorial, supported chains, why no API key, slippage guide.