# Get All Blockchains Source: https://docs.uatu.dev/api-reference/catalogue/get-all-blockchains /api-reference/openapi.json get /blockchains Returns every chain the catalogue knows about, each with its embedded token definitions. # Get All Tokens Source: https://docs.uatu.dev/api-reference/catalogue/get-all-tokens /api-reference/openapi.json get /blockchains/tokens Returns the known tokens. Omit chainId to list tokens across every chain. # Get DEXes Source: https://docs.uatu.dev/api-reference/catalogue/get-dexes /api-reference/openapi.json get /blockchains/dex Returns the seeded DEXes, including the router, factory, quoter and settlement addresses used to price and encode a swap. Filter by chainId, by slug, or by both; omit both to list every DEX. A slug identifies a DEX only within one chain, so pass chainId alongside it for a single result. # Get Pools for a Chain Source: https://docs.uatu.dev/api-reference/catalogue/get-pools-for-a-chain /api-reference/openapi.json get /blockchains/pools Returns the liquidity pools discovered by the seeder for the given chain, optionally filtered to a single DEX. Unlike the token endpoint, chainId is required here. # Compare same-chain DEX quotes Source: https://docs.uatu.dev/api-reference/quotes/compare-same-chain-dex-quotes /api-reference/openapi.json post /quotes/routes Returns the best acceptable quote per DEX, sorted by output amount descending. Both chain IDs must match. Estimates are not saved and contain no transaction steps. Use `POST /quotes` to get a fresh executable quote; prices and the selected route may change. Input `amount` uses whole-token units; response amounts use integer strings in each token's smallest units. # Create a swap or bridge quote Source: https://docs.uatu.dev/api-reference/quotes/create-a-swap-or-bridge-quote /api-reference/openapi.json post /quotes Returns the best available DEX route for matching chain IDs, or a bridge route for different chains. Returns a saved, pending quote with ordered transaction steps. Submit the steps yourself before the five-minute deadline (Unix seconds). Input `amount` uses whole-token units; response amounts use integer strings in each token's smallest units. # Catalogue Source: https://docs.uatu.dev/concepts/catalogue Chains, tokens, DEXes and pools, and how they're discovered. The catalogue is uatu's view of what is swappable where. It is populated by the seeding CLI and read back through the `/blockchains` endpoints. ## The four objects A network uatu supports. Carries `name`, `slug`, `chainId`, `symbol`, `nativeToken`, `blockExplorer`, `rpcUrl`, `ecosystem` and `blockChainLogo`, plus the `tokens` array embedded within it. The chain object does **not** carry its DEXes. Use `GET /blockchains/dex` for those. `ecosystem` says which virtual machine the chain runs: `evm`, `tvm` for TRON or `svm` for Solana. It is what tells you how to read the chain's addresses. `rpcUrl` comes back empty from the hosted API. The endpoint a deployment prices against is its own configuration, not public data. An ERC-20 or native asset: `address`, `symbol`, `name`, `slug`, `decimals`, `logo` and the `blockchainId` it belongs to. `decimals` is what converts between the integer and display amounts on a quote. A protocol deployment on one chain. Beyond `name`, `slug` and `version`, it holds the contract addresses uatu prices and encodes against: `v2FactoryAddress`, `v2RouterAddress`, `v3FactoryAddress`, `v3RouterAddress`, `v3QuoterAddress`, `universalRouterAddress`, `permit2Address` and `settlementAddress`. A discovered liquidity pool: `pairAddress`, `poolType`, `poolFee`, `tickSpacing`, the `baseToken` / `quoteToken` pair with their balances, `liquidity` and `liquidityInUsd` breakdowns, `marketCap` and `isActivePool`. ## Reading the catalogue | Endpoint | Returns | `chainId` filter | | ------------------------- | ---------------------------------------- | ---------------------- | | `GET /blockchains` | Chains, with embedded tokens | optional, as is `slug` | | `GET /blockchains/tokens` | Tokens; omit the filter for all chains | optional | | `GET /blockchains/pools` | Pools, optionally filtered by `dex` slug | required | | `GET /blockchains/dex` | DEXes and their contract addresses | optional, as is `slug` | `GET /blockchains` filters by `chainId`, by `slug`, or by both, and omitting both lists every chain. Either one identifies a single chain on its own. `GET /blockchains/dex` takes the same two filters, but there you want both: a slug identifies a DEX only within a single chain, so `uniswap` on Ethereum and `uniswap` on Base are different deployments with different addresses. The result is always an array, and a protocol appears once per version, so `chainId=1&slug=uniswap` returns two entries: Uniswap v2 and v3. ## The response envelope Every endpoint wraps its payload in the same shape: ```json theme={null} { "code": 200, "message": "Blockchains fetched successfully", "data": [] } ``` `message` is always present and describes what was fetched, such as `Tokens fetched successfully` or `Pools fetched successfully`. `data` holds the result, an object or an array depending on the endpoint, and is absent on errors, where `message` carries the reason and `code` mirrors the HTTP status. ## How pools get there Chains, tokens and DEXes are declared in JSON definitions embedded into the binary at build time. Pools are not: the `seed` command walks each chain's token list, queries the v2 and v3 factories over RPC to find pools that actually exist, and persists what it finds. That means the catalogue reflects the last seed run, so what you can quote is what the seeder found on-chain at that point. # Supported chains Source: https://docs.uatu.dev/concepts/chains Every network in the catalogue, with its chain ID, native token and token count. uatu supports 21 networks across EVM, Solana and TRON. ## Query the API `GET /blockchains` returns the definitions your deployment is actually running, each chain with its embedded tokens: ```sh theme={null} curl https://api.uatu.dev/blockchains ``` ## Chain reference A snapshot of the shipped definitions: | Chain | Native | VM | Tokens | Chain ID | | --------------- | ------ | --- | ------ | ---------------- | | Arbitrum | ETH | EVM | 7 | `42161` | | Avalanche | AVAX | EVM | 7 | `43114` | | Base | ETH | EVM | 6 | `8453` | | BNB Smart Chain | BNB | EVM | 7 | `56` | | Celo | CELO | EVM | 5 | `42220` | | Ethereum | ETH | EVM | 6 | `1` | | Gnosis | XDAI | EVM | 7 | `100` | | Ink | ETH | EVM | 5 | `57073` | | Linea | ETH | EVM | 6 | `59144` | | Mantle | MNT | EVM | 6 | `5000` | | Monad | MON | EVM | 5 | `143` | | Optimism | ETH | EVM | 7 | `10` | | Plasma | XPL | EVM | 4 | `9745` | | Polygon | POL | EVM | 8 | `137` | | Robinhood Chain | ETH | EVM | 4 | `4663` | | Solana | SOL | SVM | 4 | `34268394551451` | | Stable | STABLE | EVM | 5 | `988` | | Tempo Mainnet | USDT0 | EVM | 3 | `4217` | | TRON | TRX | TVM | 9 | `728126428` | | Unichain | ETH | EVM | 8 | `130` | | World Chain | ETH | EVM | 5 | `480` | # Quotes Source: https://docs.uatu.dev/concepts/quotes Understand quote requests, amounts, slippage, and executable steps. `POST /quotes` finds the best available DEX route when the origin and destination chain IDs match, or a bridge route when they differ. It returns the transactions needed to execute the quote. uatu prepares the route and calldata; your wallet signs and broadcasts each transaction. A quote does not reserve liquidity. Use it promptly and request a new one after its `deadline` passes. ## Request a quote Chain ID of the input token, for example `1` for Ethereum. Chain ID of the output token. Use the same value as `originChainId` for a swap on one chain, or a different value to request a bridge route. Address of the token being sold on the origin chain. Address of the token being received on the destination chain. Amount of `tokenIn` to sell, supplied as a decimal string in display units, such as `"1.5"`. Address that receives `tokenOut`. Maximum price movement you will accept, in basis points. If omitted, the server default applies. See [Slippage](#slippage). Missing, malformed, or incompatible values return a `400` response. See [Errors](/guides/errors) for the response format. Quote requests use `originChainId` and `destinationChainId` in place of `chain` and `chainId`. The catalogue endpoints still use `chainId` as a query filter. `POST /quotes/routes` accepts the same request fields, but both chain IDs must match. ## Read the response The quote is returned in the response's `data` object. These are the fields most integrations use: | Field | Meaning | | ------------------ | ------------------------------------------------------- | | `quoteId` | Unique ID for the persisted quote | | `route` | DEX selected for the swap | | `amountIn` | Input amount in the token's smallest unit | | `amountOut` | Quoted output in the token's smallest unit | | `amountOutMinimum` | Lowest output the swap is allowed to return | | `slippageBps` | Slippage tolerance applied to the quote | | `steps` | Ordered transactions to sign and submit | | `deadline` | Unix timestamp after which the quote should not be used | | `status` | Quote status; a new quote starts as `pending` | ## Amounts Input and output amounts are each represented in two forms: | Fields | Format | Use | | --------------------------------- | -------------------------------------------- | --------------------- | | `amountIn`, `amountOut` | Integer strings in the token's smallest unit | On-chain calculations | | `amountInFloat`, `amountOutFloat` | Decimal strings in display units | User interfaces | Keep both forms as strings. Token amounts can exceed JavaScript's safe integer range, and converting them to JSON numbers can silently lose precision. ## Execute the steps `steps` contains the transactions required to execute the quote. Depending on the input token and its existing allowances, a quote can include token approval, Permit2 approval, and swap steps. Human-readable description of the step, such as a token approval. Address that initiates the transaction. Exexuting address/contract. encoded calldata for the transaction. Native-token value to attach to the transaction, when required. Amount moved or approved by the step, in the token's smallest unit. Contract receiving an allowance on approval steps, when provided. Chain on which the transaction must be submitted. Submit the steps in their returned order and wait for each transaction to confirm before submitting the next one. Before asking the user to sign, verify that: * the wallet is connected to the step's `chainId`; * the connected account matches `from`; * the quote's `deadline` has not passed; and * the transaction includes `value` when one is provided. Treat every step as an untrusted transaction request: show the destination, value, and action to the user before signing. uatu never signs or broadcasts transactions. ## Slippage Pool prices can change between quote creation and execution. `slippageBps` controls how much movement the swap accepts, where `100` basis points equals `1%`. | Field | Meaning | | ---------------------- | ------------------------------------------------------ | | Request `slippageBps` | Optional tolerance requested by your client | | Response `slippageBps` | Tolerance actually applied to the quote | | `amountOutMinimum` | Minimum acceptable output in the token's smallest unit | The swap calldata enforces `amountOutMinimum`. If the available output falls below that value, the transaction reverts instead of completing at a worse price. The default tolerance and maximum accepted value are configured per deployment. A request above the configured maximum is rejected. ## Expiration Each quote includes a `deadline` Unix timestamp, currently set five minutes after the quote is created. If the deadline has passed, discard the steps and request a fresh quote. Always read `deadline` from the response instead of hard-coding the quote lifetime. Request a quote and execute its transaction steps. # Create your first quote Source: https://docs.uatu.dev/concepts/quotes/create-your-first-quote Discover a token pair and request an executable swap quote. Use the hosted API to find a token pair and create an executable WETH-to-USDC quote on Ethereum. The catalogue endpoints are public; quote endpoints require an API key. ## Before you start Create an API key in the [uatu console](/console), then store it in an environment variable: ```sh theme={null} export UATU_API_KEY="uatu_live_..." ``` Keep your API key on the server. Do not commit it or expose it in browser or mobile application code. All requests below use the hosted API at `https://api.uatu.dev`. ## 1. Choose a chain `GET /blockchains` returns every supported chain and its token definitions. This endpoint does not require authentication. ```sh theme={null} curl https://api.uatu.dev/blockchains ``` Every response uses the same envelope: `code` mirrors the HTTP status, `message` describes the result, and `data` contains the payload. Here is the Ethereum entry, shortened for clarity: ```json theme={null} { "code": 200, "message": "Blockchains fetched successfully", "data": [ { "name": "Ethereum", "slug": "ethereum", "chainId": 1, "symbol": "ETH", "nativeToken": "ETH", "ecosystem": "evm", "blockExplorer": "https://etherscan.io" } ] } ``` Save the chain's `chainId`. For this Ethereum swap, use `1` for both `originChainId` and `destinationChainId` in the quote request. ## 2. Choose the tokens Filter the token catalogue by the selected chain. Omit `chainId` to list tokens on every chain. ```sh theme={null} curl "https://api.uatu.dev/blockchains/tokens?chainId=1" ``` The response's `data` field is an array: ```json theme={null} { "code": 200, "message": "Tokens fetched successfully", "data": [ { "name": "Wrapped Ether", "symbol": "WETH", "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "decimals": 18, "slug": "weth", "blockchainId": 1 }, { "name": "USD Coin", "symbol": "USDC", "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "decimals": 6, "slug": "usdc", "blockchainId": 1 } ] } ``` You need each token's `address` for the quote. Keep `decimals` as well: raw amounts in the response use the token's smallest unit. ## 3. Request a quote `POST /quotes` prices the pair across the available DEX routes and returns the best route with ready-to-sign transaction data. Replace `0xYourRecipientAddress` with the address that will receive USDC: ```sh theme={null} curl -X POST https://api.uatu.dev/quotes \ -H "Authorization: Bearer ${UATU_API_KEY}" \ -H "Content-Type: application/json" \ -d '{ "originChainId": 1, "destinationChainId": 1, "tokenIn": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "tokenOut": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "amount": "1", "recipientAddress": "0xYourRecipientAddress", "slippageBps": 50 }' ``` The first six fields are required. `amount` is a decimal string in the input token's display units, so `"1"` means 1 WETH—not 1 wei. `slippageBps` is optional; `50` allows 0.5% slippage. If omitted, the server default applies. See [Slippage](/concepts/quotes#slippage) for details. ## 4. Read and execute the quote The response includes the chosen route, the minimum acceptable output, an expiry, and the transactions your wallet must submit. This representative response is shortened: ```json theme={null} { "code": 200, "message": "Quote created successfully", "data": { "quoteId": "4d4cb5b4-6d7a-48ed-a7fd-b2e20c556fd8", "amountIn": "1000000000000000000", "amountOut": "2493777615", "amountOutMinimum": "2481308726", "amountInFloat": "1", "amountOutFloat": "2493.777615", "slippageBps": 50, "route": { "dex": "uniswap", "name": "Uniswap", "fees": "42207128027132" }, "steps": [ { "message": "Permit2 approval", "from": "0x...", "to": "0x...", "amount": "1000000000000000000", "data": "0x...", "chainId": 1 }, { "message": "Swap WETH to USDC", "from": "0x...", "to": "0x...", "amount": "1000000000000000000", "data": "0x...", "chainId": 1 } ], "deadline": 1787624479, "status": "pending" } } ``` Before submitting anything: * Display `amountOutFloat`, but use the integer amount fields for on-chain logic. * Make sure the current Unix time is earlier than `deadline`; otherwise, request a new quote. * Submit every item in `steps` in order with the wallet in `from`, waiting for each transaction to confirm before sending the next. * Include a step's `value` when present. Native-token swaps use it to carry the transaction's native value. The swap calldata enforces `amountOutMinimum`. If the market moves below that floor, the transaction reverts instead of filling at a worse price. Send quote steps with viem or ethers.js and handle common edge cases. Review every endpoint, parameter, and response schema. # Console Source: https://docs.uatu.dev/console Create, secure, rotate, and monitor API keys. Use the [uatu console](https://console.uatu.dev) to manage your organization's API keys and members from one place. Go to console.uatu.dev ## Create an API key Open [console.uatu.dev](https://console.uatu.dev) and sign in to your organization. The **API keys** page lists your organization's keys, including their status, creator, creation date, and last-used time. Give the key a descriptive name, such as `checkout-production` or `quotes-staging`. You can also set an optional expiration date; a key without one does not expire automatically. Keys start with `uatu_live_`. Copy the new key directly into your secret manager or deployment environment. The complete key is shown only once. The console stores a hash and cannot reveal the value later. If you lose it, revoke the key and create a new one. ## Authenticate a request Load the key from an environment variable instead of placing it directly in source code: ```sh theme={null} export UATU_API_KEY="uatu_live_..." ``` Send it as a bearer token when requesting a quote: ```sh theme={null} curl -X POST https://api.uatu.dev/quotes \ -H "Authorization: Bearer ${UATU_API_KEY}" \ -H "Content-Type: application/json" \ -d '{ "chain": "ethereum", "chainId": 1, "tokenIn": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "tokenOut": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "amount": "1", "recipientAddress": "0xYourRecipientAddress" }' ``` ## Which endpoints need a key? Creating an executable quote requires an API key. The catalogue is public. | Endpoint | Authentication | | ------------------------- | -------------- | | `POST /quotes` | **Required** | | `GET /blockchains` | Not required | | `GET /blockchains/tokens` | Not required | | `GET /blockchains/pools` | Not required | | `GET /blockchains/dex` | Not required | Public catalogue requests let you discover chains, tokens, DEXes, and pools before signing up. ## Rotate or revoke a key Rotate a key without interrupting traffic: Give the replacement a name that identifies the same service and environment. Update your secret manager or deployment environment and verify that requests are using the new key. Wait until the old key's **Last used** value shows that traffic has moved. Allow at least one minute for reporting to catch up. Revocation takes effect immediately. A revoked key remains in the console for audit history but can no longer authenticate requests. ## Keep keys safe * Keep keys in server-side secret storage. Anything in a browser bundle or mobile application can be extracted. * Use a separate key for each service and environment to limit the impact of a leak and make rotation or revocation more precise. * Set an expiration date when a key is only needed temporarily. * Revoke keys you no longer recognize or use. * Never commit a key to version control or include it in logs and error messages. # Build with AI agents Source: https://docs.uatu.dev/guides/ai-agents Give coding agents accurate uatu context through Markdown, MCP, or OpenAPI. uatu publishes its documentation in formats that coding agents can read directly. Use a Markdown page for a focused task, `llms.txt` for documentation discovery, MCP for ongoing search, or the OpenAPI document to generate a typed client. The documentation is public. Your application still needs an [API key](/console) to request a quote from `https://api.uatu.dev`. Do not paste an API key into a prompt or send it to the documentation MCP server. Keep the key in server-side secret storage and load it at runtime. ## Choose a context source | Need | Source | | ---------------------------------------------- | ------------------------------------------------------------------ | | Find the relevant documentation | [`llms.txt`](https://docs.uatu.dev/llms.txt) | | Provide the complete documentation in one file | [`llms-full.txt`](https://docs.uatu.dev/llms-full.txt) | | Explain the quote-to-transaction flow | [`integration.md`](https://docs.uatu.dev/guides/integration.md) | | Generate types or a client | [`openapi.json`](https://docs.uatu.dev/api-reference/openapi.json) | | Search the docs throughout a task | [uatu docs MCP](https://docs.uatu.dev/mcp) | Start with `llms.txt` for most tasks. It is an index that lets the agent find and read only the pages it needs. Use `llms-full.txt` when the agent cannot fetch linked pages or when you need a single offline snapshot. You can also append `.md` to an individual documentation URL to retrieve that page as plain Markdown: ```text theme={null} https://docs.uatu.dev/guides/integration.md https://docs.uatu.dev/concepts/quotes.md https://docs.uatu.dev/concepts/quotes/create-your-first-quote.md ``` A concise starting instruction is often enough: ```text theme={null} Read https://docs.uatu.dev/llms.txt. Find the pages relevant to implementing a uatu swap with viem, then follow those pages as the source of truth. ``` ## Connect the documentation MCP server Connect MCP when an agent needs to search and revisit the docs throughout a longer task. The server is public and read-only with respect to the uatu API: ```text theme={null} https://docs.uatu.dev/mcp ``` ```sh theme={null} claude mcp add --transport http uatu-docs https://docs.uatu.dev/mcp ``` Add this server to `~/.cursor/mcp.json`: ```json theme={null} { "mcpServers": { "uatu-docs": { "url": "https://docs.uatu.dev/mcp" } } } ``` Add this server to `.vscode/mcp.json`: ```json theme={null} { "servers": { "uatu-docs": { "type": "http", "url": "https://docs.uatu.dev/mcp" } } } ``` Add this server to `claude_desktop_config.json`: ```json theme={null} { "mcpServers": { "uatu-docs": { "command": "npx", "args": ["-y", "mcp-remote", "https://docs.uatu.dev/mcp"] } } } ``` Once connected, the agent can search the documentation, read pages, and report documentation feedback. The server cannot create quotes, sign transactions, or access your API key. ## Generate a typed client Use the OpenAPI document when the task is primarily about request and response types: ```text theme={null} https://docs.uatu.dev/api-reference/openapi.json ``` It defines the API endpoints and schemas consumed by tools such as `openapi-typescript` and `openapi-generator`. Generated types help prevent agents from borrowing incompatible field names from other swap APIs. ## Use a constrained implementation prompt Tell the agent what to build and which safety boundaries it must preserve. Adapt this template to your project: ```text theme={null} Read https://docs.uatu.dev/llms.txt and use the linked uatu documentation as the source of truth. Implement a server-side swap flow using the uatu API at https://api.uatu.dev and the conventions already used in this repository. Requirements: - use POST /quotes to get the best executable quote - load UATU_API_KEY from the server environment and send it as a bearer token - send `amount` as a decimal string in the input token's display units - read the quote from the response's `data` field - show `amountOutFloat` to the user and require confirmation before broadcasting - reject an expired quote by checking `deadline` against the current Unix time - submit every transaction in `steps` in order and wait for each receipt - include `value` when a step provides it - request a new quote after an expired quote or market-movement revert - never invent endpoints, request fields, or response fields Use viem. Keep signing in the wallet client; uatu only returns transaction data. Run the relevant tests and report the files changed. ``` Documentation access and transaction authority are separate. An agent may read these docs freely, but your application should still require explicit user confirmation before a wallet signs or broadcasts a quote step. # Errors Source: https://docs.uatu.dev/guides/errors Every response uses the same envelope. On success `data` carries the result; on failure it is absent and `message` explains why. ```json theme={null} { "code": 400, "message": "invalid chain id" } ``` ## Status codes | Status | Meaning | What to do | | ------ | ------------------------ | ------------------------------------------ | | `200` | Success | Check `data` is not `null` before using it | | `400` | The request was rejected | Fix the request, do not retry unchanged | | `429` | Rate limited | Back off and retry | | `500` | The service failed | Retry with backoff | ## Request validation A quote request missing fields returns every problem at once, semicolon separated, rather than failing on the first one: ```sh theme={null} curl -X POST https://api.uatu.dev/quotes/routes \ -H "Authorization: Bearer ${UATU_API_KEY}" \ -H "Content-Type: application/json" \ -d '{"originChainId":1,"destinationChainId":1}' ``` ```json theme={null} { "code": 400, "message": "amount: is required; recipientAddress: is required; tokenIn: is required; tokenOut: is required" } ``` `POST /quotes/routes` requires matching `originChainId` and `destinationChainId`. Its API reference documents a `400` response for invalid requests or when no acceptable same-chain quote is available. ## A 200 can still carry nothing An unknown `chainId` on `/blockchains/pools` returns **`200` with `data: null`**, not a `404`. Null-check every `data` before iterating, or you will crash on a request that technically succeeded. ```sh theme={null} curl "https://api.uatu.dev/blockchains/pools?chainId=999999" ``` ```json theme={null} { "code": 200, "message": "Pools fetched successfully", "data": null } ``` Omitting `chainId` entirely is a different case and does fail properly: ```json theme={null} { "code": 400, "message": "invalid chain id" } ``` ## Failures that are not HTTP errors * **The swap reverts.** `amountOutMinimum` is enforced on-chain, so a market that moved between quoting and broadcasting reverts the transaction rather than filling at a worse price. Re-quote and retry. # Integrate the API Source: https://docs.uatu.dev/guides/integration A working swap integration, from quote to execution. Base URL is `https://api.uatu.dev`. Quoting requires an API key, so create one in the [console](/console) first. The catalogue endpoints are open. ## The flow `POST /quotes` with the pair, the amount and who receives the output. The response carries a `steps` array: an ordered list of ready-to-send transactions, typically a Permit2 approval followed by the swap. Sign and broadcast with your own wallet, waiting for each to confirm. ## Write the integration ```ts theme={null} import { createWalletClient, createPublicClient, http } from "viem"; import { mainnet } from "viem/chains"; import { privateKeyToAccount } from "viem/accounts"; const UATU = "https://api.uatu.dev"; const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`); const wallet = createWalletClient({ account, chain: mainnet, transport: http() }); const publicClient = createPublicClient({ chain: mainnet, transport: http() }); // 1. quote const res = await fetch(`${UATU}/quotes`, { method: "POST", headers: { "Authorization": `Bearer ${process.env.UATU_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ originChainId: 1, destinationChainId: 1, tokenIn: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH tokenOut: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC amount: "1", recipientAddress: account.address, slippageBps: 50, // optional, 0.5% }), }); const body = await res.json(); if (!res.ok) throw new Error(body.message); const quote = body.data; // 2. check the floor and the clock before spending gas console.log(`out ${quote.amountOutFloat} USDC via ${quote.route.name}`); console.log(`min ${quote.amountOutMinimum} (raw units)`); if (Math.floor(Date.now() / 1000) >= Number(quote.deadline)) { throw new Error("quote expired, request a new one"); } // 3. send the steps in order for (const step of quote.steps) { const hash = await wallet.sendTransaction({ to: step.to as `0x${string}`, data: step.data as `0x${string}`, value: step.value ? BigInt(step.value) : 0n, }); await publicClient.waitForTransactionReceipt({ hash }); console.log(`${step.message}: ${hash}`); } ``` ```ts theme={null} import { JsonRpcProvider, Wallet } from "ethers"; const UATU = "https://api.uatu.dev"; const provider = new JsonRpcProvider(process.env.RPC_URL); const wallet = new Wallet(process.env.PRIVATE_KEY!, provider); // 1. quote const res = await fetch(`${UATU}/quotes`, { method: "POST", headers: { "Authorization": `Bearer ${process.env.UATU_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ originChainId: 1, destinationChainId: 1, tokenIn: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH tokenOut: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC amount: "1", recipientAddress: wallet.address, slippageBps: 50, // optional, 0.5% }), }); const body = await res.json(); if (!res.ok) throw new Error(body.message); const quote = body.data; // 2. check the floor and the clock before spending gas console.log(`out ${quote.amountOutFloat} USDC via ${quote.route.name}`); console.log(`min ${quote.amountOutMinimum} (raw units)`); if (Math.floor(Date.now() / 1000) >= Number(quote.deadline)) { throw new Error("quote expired, request a new one"); } // 3. send the steps in order for (const step of quote.steps) { const tx = await wallet.sendTransaction({ to: step.to, data: step.data, value: step.value ? BigInt(step.value) : 0n, }); await tx.wait(); console.log(`${step.message}: ${tx.hash}`); } ``` ## Get a read-only quote `POST /quotes/routes` takes the same body, with matching `originChainId` and `destinationChainId`, and returns the best acceptable quote per DEX, ordered by output amount. Nothing is persisted and no transaction steps are returned. Use it while a user is still choosing, then call `POST /quotes` for a fresh executable quote. ```sh theme={null} curl -X POST https://api.uatu.dev/quotes/routes \ -H "Authorization: Bearer ${UATU_API_KEY}" \ -H "Content-Type: application/json" \ -d '{ "originChainId": 1, "destinationChainId": 1, "tokenIn": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "tokenOut": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "amount": "1", "recipientAddress": "0xYourAddress" }' ``` A real response, trimmed to one route: ```json theme={null} { "code": 200, "message": "DEX quotes fetched successfully", "data": [ { "amountIn": "1000000000000000000", "amountOut": "2493777615", "amountOutMinimum": "2481308726", "slippageBps": 50, "deadline": 1787624479, "route": { "name": "CowSwap", "dex": "cowswap", "fees": "42207128027132" } } ] } ``` ## Common pitfalls `amount` on the **request** is a decimal string in display units, so `"1"` means one WETH. Amounts on the **response** are integer strings in the token's smallest unit: `amountOut` of `"2493777615"` is 2493.777615 USDC at 6 decimals. Use `amountOutFloat` for display and the raw integers for anything on-chain. `deadline` is a Unix timestamp five minutes out. Check it before broadcasting, especially if a user has been staring at a confirmation screen. A swap usually needs its Permit2 approval mined before the swap itself. Wait for each receipt rather than firing them together. It is encoded into the calldata, so a fill worse than that floor reverts rather than filling badly. A reverted swap that cost gas is usually a moved market, not a bad request. Re-quote and retry. When the input token is the chain's native asset, the step carries `value`. Send it, or the swap reverts. Every failure shape, with real responses. # Overview Source: https://docs.uatu.dev/index A multichain DEX aggregation and swap-quote API spanning EVM, Solana and TRON. Uatu aggregates tokens, DEXs, and liquidity pools across 21 blockchain networks to deliver executable swap quotes through a single API. ```sh theme={null} curl https://api.uatu.dev/blockchains ``` ## What it does Price a swap and get back the transactions your client needs to submit. Discover which chains, tokens, DEXes and pools are swappable where. See every EVM, Solana and TRON network in the catalogue and its DEXes. ## Supported protocols Uniswap v2/v3 (plus Universal Router), PancakeSwap, SushiSwap, CowSwap, Aerodrome, QuickSwap, OkuTrade, Agni Finance, Pharoah and SunSwap. Which protocols are available is configured per chain; `GET /blockchains/dex` returns the DEXes on one chain. See [Catalogue](/concepts/catalogue) for how to query them. ## Where to start Get your first quote in a few `curl` calls. Working TypeScript with viem or ethers, from quote to broadcast. Every endpoint, parameter and response shape. Connect these docs to Claude, Cursor or Copilot via MCP. Create an API key and track your usage. Amounts, steps, slippage and deadlines explained. The 21 networks and their DEXes.