Skip to main content

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

SlippageWhen 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:
CauseSolution
Price moved beyond slippage toleranceIncrease 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 gasLet the API set gas automatically (don’t override gas and gasPrice unless you have a reason)
Insufficient balanceCheck the user’s balance before initiating the swap
Insufficient allowanceThe 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.
TokenDecimals1.0 in wei
HYPE181000000000000000000
USDC61000000
UBTC181000000000000000000
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.