DEX Aggregator API

The HyperFlow DEX Aggregator API gives you the same routing engine that powers hyperflow.fun: quote the best route across 30+ HyperEVM liquidity sources, then execute through the HyperFlow router contract.

Base URL: https://ag-api.hyperflow.fun/v1/hyperevm — all endpoints serve mainnet only; there is no public testnet environment.

Authentication & rate limits

Requests can be authenticated with an API key passed in the x-api-key header:

AccessRate limit
Without API key5 requests/second
With API key15 requests/second

To obtain an API key, reach out to the HyperFlow team on Discord.

Get a quote

GET /quote

Retrieves the optimal trading route and price quote between two tokens.

Parameters

ParameterRequiredDescription
tokenInYesInput token address
tokenOutYesOutput token address
amountInYesInput amount, in wei
exchangesNoComma-separated DEX ids to restrict routing; blank routes across all available sources
gasPriceNoCustom gas price, in wei

Response

FieldDescription
tokenIn / tokenOutToken addresses of the quoted pair
amountIn / amountInUsdInput amount in wei / USD
amountOut / amountOutUsdOutput amount in wei / USD
minAmountOutOutput floor after slippage, in wei
priceImpactPercentEstimated price impact of the route
totalGas / totalGasUsdEstimated gas for the route
gasPriceGas price used for the estimate, in wei
splits[]Route splits — each with amountIn, amountOut, and the detailed swaps path (pool, exchange, type per hop)
requestIdIdentifier of this quote

Get swap data

GET /swap

Generates the transaction data needed to execute the swap through the router contract.

Parameters

All Quote parameters, plus:

ParameterRequiredDescription
receiverYesRecipient address for the output token
slippageNoMaximum acceptable slippage, 0–1 (e.g. 0.01 = 1%). Defaults to 0.01
minAmountOutNoCustom minimum acceptable output amount
deadlineNoTransaction deadline in Unix seconds (default: now + 20 minutes)

Response

/swap wraps the quote:

1{
2 "quote": { "...": "all /quote fields" },
3 "tx": {
4 "router": "0x980B9271A33c4B31214301fAE584B18dBB9731eC",
5 "data": "0xf970cf64…"
6 },
7 "requestId": "2b493058b2cf36f39de8d4c41589b9cc"
8}

Approve tx.router for tokenIn (ERC-20 inputs), then send tx.data to tx.router — attaching value = amountIn for native-token input.

Code example

1import {ethers} from 'ethers'; // ^6.13.4
2import type {TransactionRequest} from 'ethers';
3
4const routerApiUrl = 'https://ag-api.hyperflow.fun/v1/hyperevm';
5const rpcUrl = 'network-RPC'; // Replace with your network RPC
6const privateKey = 'your-private-key-here'; // Replace with your private key
7const apiKey = process.env.HYPERFLOW_API_KEY; // Optional: raises the rate limit
8const apiHeaders = apiKey ? {'x-api-key': apiKey} : undefined;
9
10const wallet = new ethers.Wallet(privateKey);
11const provider = new ethers.JsonRpcProvider(rpcUrl);
12
13async function signAndSendTransaction(tx: TransactionRequest) {
14 const signer = wallet.connect(provider);
15
16 if (!tx.gasLimit) {
17 const estimatedGas = await signer.estimateGas(tx);
18 tx.gasLimit = estimatedGas * BigInt(120) / BigInt(100);
19 }
20
21 const txResponse = await signer.sendTransaction(tx);
22 console.log('Transaction Hash:', txResponse.hash);
23
24 const receipt = await txResponse.wait();
25 console.log('Transaction Mined:', receipt);
26 return receipt;
27}
28
29type Address = `0x${string}`;
30
31export const EtherAddress = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE';
32
33const erc20Abi = [
34 {
35 "constant": true,
36 "inputs": [{"name": "_owner", "type": "address"}, {"name": "_spender", "type": "address"}],
37 "name": "allowance",
38 "outputs": [{"name": "remaining", "type": "uint256"}],
39 "payable": false,
40 "stateMutability": "view",
41 "type": "function"
42 },
43 {
44 "constant": false,
45 "inputs": [{"name": "_spender", "type": "address"}, {"name": "_value", "type": "uint256"}],
46 "name": "approve",
47 "outputs": [],
48 "payable": false,
49 "stateMutability": "nonpayable",
50 "type": "function"
51 }
52];
53
54async function approve(token: Address, spender: Address, amount: string | bigint) {
55 const contract = new ethers.Contract(token, erc20Abi, provider);
56 const allowance = await contract.allowance(wallet.address, spender);
57
58 if (allowance < BigInt(amount)) {
59 const data = contract.interface.encodeFunctionData('approve', [spender, amount]);
60 return signAndSendTransaction({to: token, data});
61 }
62 return Promise.resolve(true);
63}
64
65function serializeParameters(params: Record<string, any>) {
66 const searchParams = new URLSearchParams(
67 Object.fromEntries(Object.entries(params).filter(([_, v]) => v !== undefined && v !== null && v !== ''))
68 );
69 return searchParams.toString();
70}
71
72interface QuoteParameters {
73 tokenIn: Address;
74 tokenOut: Address;
75 amountIn: string | bigint;
76 exchanges?: string[];
77}
78
79// Retrieves the optimal trading route and price quote between two tokens
80export async function quote(args: QuoteParameters) {
81 const params = {
82 ...args,
83 amountIn: args.amountIn.toString(),
84 exchanges: args.exchanges?.join(','),
85 };
86 const quoteResponse = await fetch(`${routerApiUrl}/quote?${serializeParameters(params)}`, {headers: apiHeaders});
87 return quoteResponse.json();
88}
89
90interface SwapParameters extends QuoteParameters {
91 slippage?: number;
92 receiver?: Address;
93}
94
95// Generates the transaction data needed to execute the swap through the router
96export async function swap(args: SwapParameters) {
97 const params = {
98 ...args,
99 amountIn: args.amountIn.toString(),
100 exchanges: args.exchanges?.join(','),
101 slippage: args?.slippage?.toString(),
102 receiver: args.receiver || wallet.address,
103 };
104 const encodingResponse = await fetch(`${routerApiUrl}/swap?${serializeParameters(params)}`, {headers: apiHeaders});
105 const encodingResult = await encodingResponse.json();
106
107 const tokenInIsNative = args.tokenIn.toLowerCase() === EtherAddress.toLowerCase();
108
109 if (!tokenInIsNative) {
110 await approve(args.tokenIn, encodingResult.tx.router, args.amountIn);
111 }
112
113 return await signAndSendTransaction({
114 to: encodingResult.tx.router,
115 value: tokenInIsNative ? args.amountIn : undefined,
116 data: encodingResult.tx.data,
117 });
118}

Errors

Errors are returned as {"error": "<message>"}. Note that the API returns HTTP 500 for ordinary client errors as well — don’t treat 500 as a retryable server failure without reading the body:

ResponseMeaning
500 {"error":"no path found"}No route exists for the pair/amount
500 with a field-validation messageA required parameter is missing (e.g. receiver)

Resources