Documentation Index
Fetch the complete documentation index at: https://docs.akka.finance/llms.txt
Use this file to discover all available pages before exploring further.
Slippage
Slippage is the maximum price difference you’re willing to accept between the quoted rate and the executed rate. It protects against price movement during the time between quoting and on-chain execution.
Choosing a slippage value
| Slippage | When to use |
|---|
| 0.1–0.5% | Stablecoins or high-liquidity pairs (e.g., USDC → USDT) |
| 0.5–1% | Standard pairs with good liquidity (e.g., HYPE → USDC) |
| 1–3% | Lower-liquidity tokens or volatile markets |
| 3–5% | Very low liquidity or fast-moving prices |
| > 5% | Generally not recommended — consider splitting into smaller trades |
Pass slippage as a percentage (not a fraction) to the /swap endpoint:
# 1% slippage
curl -H "apikey: YOUR_API_KEY" \
"https://api.akka.finance/swap/v1/999/swap?src=0x...&dst=0x...&amount=1000000000000000000&from=0x...&slippage=1"
The allowed range is 0 to 50. Up to 4 decimal places are supported (e.g., 0.5, 1.25).
What happens when slippage is exceeded
The on-chain transaction reverts. You pay gas but no tokens are swapped and no tokens are lost. The user keeps their full balance.
Quote-then-swap timing
The quote endpoint returns an estimated output amount. The swap endpoint returns the transaction to execute. Between these two calls (and before the transaction confirms), pool prices can move.
Best practice: Keep the gap between /quote and /swap as short as possible. In a frontend, fetch the swap data only when the user clicks “Swap” — don’t pre-fetch it while they’re still reviewing.
// Good: quote for display, swap on click
const quote = await getQuote(src, dst, amount); // show to user
// ... user reviews and clicks "Swap" ...
const swap = await getSwap(src, dst, amount, from, slippage); // fetch right before execution
await sendTransaction(swap.tx);
Handling reverts
If a swap transaction reverts on-chain, it’s usually one of these:
| Cause | Solution |
|---|
| Price moved beyond slippage tolerance | Increase slippage or retry immediately with a fresh quote |
| Stale quote (too much time between quote and execution) | Re-fetch the swap data and retry |
| Insufficient gas | Let the API set gas automatically (don’t override gas and gasPrice unless you have a reason) |
| Insufficient balance | Check the user’s balance before initiating the swap |
| Insufficient allowance | The token wasn’t approved, or the approval transaction hasn’t confirmed yet |
Retry pattern
async function swapWithRetry(
src: string, dst: string, amount: string,
from: string, slippage: number, maxRetries = 2,
) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const { tx } = await getSwap(src, dst, amount, from, slippage);
const hash = await sendTransaction(tx);
return hash;
} catch (err) {
console.error(`Attempt ${attempt} failed:`, err);
if (attempt === maxRetries) throw err;
// Bump slippage slightly on retry
slippage = Math.min(slippage * 1.5, 5);
}
}
}
Gas on HyperEVM
HyperEVM has low and stable gas prices. The API returns gasPrice and gas (limit) in the swap response — use them as-is unless you have a specific reason to override.
const { tx } = await getSwap(src, dst, amount, from, slippage);
// Use the gas values from the API directly
await walletClient.sendTransaction({
to: tx.to as `0x${string}`,
data: tx.data as `0x${string}`,
value: BigInt(tx.value),
gasPrice: BigInt(tx.gasPrice),
gas: BigInt(tx.gas),
});
If you need to override gas, set a higher limit — never lower:
const gasWithBuffer = BigInt(tx.gas) * 130n / 100n; // 30% buffer
Rate limiting
The API allows 20 requests per 60 seconds per IP. Tips to stay within limits:
- Cache quotes — Don’t re-fetch on every keystroke. Use debouncing (see React Hooks guide).
- Poll at reasonable intervals — For price feeds, 15–30 seconds is sufficient. Prices refresh every ~5 seconds on the backend.
- Batch token lookups — Use
GET /{chainId}/tokens to fetch all tokens in one call instead of fetching individually.
If you hit the rate limit, the API returns HTTP 429. Back off and retry:
async function fetchWithBackoff<T>(url: string, headers: Record<string, string>): Promise<T> {
const res = await fetch(url, { headers });
if (res.status === 429) {
await new Promise((r) => setTimeout(r, 5000)); // wait 5 seconds
return fetchWithBackoff(url, headers);
}
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
Approval best practices
- Approve once, swap many times — The default approval sets an unlimited allowance. You only need to approve once per token.
- Check before approving — Always call
/approve/allowance first. Sending an unnecessary approval wastes gas.
- Wait for confirmation — Don’t call
/swap until the approval transaction is confirmed on-chain.
- Native tokens skip approval — HYPE (
0xeeee...eeee) doesn’t need approval. Skip the allowance check for native tokens.
const NATIVE = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee';
if (src.toLowerCase() !== NATIVE) {
const { allowance } = await checkAllowance(src, walletAddress);
if (BigInt(allowance) < BigInt(amount)) {
const approveTx = await getApproveTransaction(src);
const hash = await sendTransaction(approveTx);
await waitForReceipt(hash); // wait before swapping
}
}
Amounts and decimals
All amounts in the API are in wei (the token’s smallest unit). Each token has its own decimals value.
| Token | Decimals | 1.0 in wei |
|---|
| HYPE | 18 | 1000000000000000000 |
| USDC | 6 | 1000000 |
| UBTC | 18 | 1000000000000000000 |
Use viem’s parseUnits and formatUnits to convert:
import { parseUnits, formatUnits } from 'viem';
// Human → wei
const amountWei = parseUnits('1.5', 18).toString(); // "1500000000000000000"
// Wei → human
const amountHuman = formatUnits(BigInt('1500000000000000000'), 18); // "1.5"
Always use the token’s actual decimals value from the API — don’t hardcode 18. Some tokens use 6, 8, or other values.