Developers
Agent quickstart
Execute a non-custodial same-chain swap in four API calls — no API key required.
This is the minimum path for a bot or AI agent to swap tokens. The API only ever returns quotes and unsigned transactions — your code signs with the user's wallet. Never send private keys or seed phrases to the API.
1. Quote
curl -X POST https://xauconnect.com/api/swap/quote \
-H "Content-Type: application/json" \
-H "X-Client-Id: my-bot-v1" \
-H "X-Client-Source: agent" \
-d '{
"chainKey": "bsc",
"tokenIn": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",
"tokenOut": "0x55d398326f99059fF775485246999027B3197955",
"amountIn": "1000000000000000000",
"slippageBps": 50,
"taker": "0xYourWallet..."
}'Pick best (or a row from quotes[]) and derive minAmountOut from your slippage.
2. Build
curl -X POST https://xauconnect.com/api/swap/build \
-H "Content-Type: application/json" \
-d '{ "request": { ... }, "route": { ... }, "minAmountOut": "..." }'3. Sign & send
- EVM: check ERC-20 allowance via
GET /swap/allowance, approve thespenderif needed, thensendTransactionwith the returned calldata. - Solana: sign the base64 transaction, then
POST /swap/submit-solana.
4. Record (recommended)
curl -X POST https://xauconnect.com/api/swap/record \
-H "Content-Type: application/json" \
-d '{
"chainKey": "bsc",
"dexId": "1inch-bsc",
"tokenIn": "...",
"tokenOut": "...",
"amountIn": "...",
"amountOut": "...",
"protocolFee": "...",
"feeBps": 30,
"txHash": "0x...",
"address": "0xYourWallet...",
"status": "confirmed",
"source": "agent",
"clientId": "my-bot-v1"
}'End-to-end (TypeScript)
const API = "https://xauconnect.com/api";
const headers = { "Content-Type": "application/json", "X-Client-Id": "my-bot-v1", "X-Client-Source": "agent" };
// 1. quote
const q = await fetch(`${API}/swap/quote`, {
method: "POST", headers,
body: JSON.stringify({ chainKey, tokenIn, tokenOut, amountIn, slippageBps: 50, taker }),
}).then((r) => r.json());
const route = q.best;
const minAmountOut = (BigInt(route.amountOut) * 9950n / 10000n).toString(); // 0.5% buffer
// 2. (EVM) approve if needed
const { allowance } = await fetch(
`${API}/swap/allowance?chainKey=${chainKey}&token=${tokenIn}&owner=${taker}&spender=${route.spender}`,
).then((r) => r.json());
if (BigInt(allowance) < BigInt(amountIn)) { /* send ERC-20 approve(route.spender, amountIn) */ }
// 3. build + sign + broadcast
const tx = await fetch(`${API}/swap/build`, {
method: "POST", headers,
body: JSON.stringify({ request: { chainKey, tokenIn, tokenOut, amountIn, taker }, route, minAmountOut }),
}).then((r) => r.json());
// EVM: wallet.sendTransaction(tx.evm) | Solana: sign tx.solanaTransaction then POST /swap/submit-solana
// 4. record
await fetch(`${API}/swap/record`, { method: "POST", headers, body: JSON.stringify({ /* ...result... */ }) });Safety rules
- Amounts are base units (wei/lamports) unless you pass
amount+amountUnit: "human". - Always set
minAmountOut/slippageBpsso a bad price reverts instead of filling. - Verify token contract addresses against
GET /swap/tokens— tickers are not unique. - Re-quote if more than ~60s elapse before signing; quotes expire as pools move.
- On HTTP
429, back off — see rate limits.
Next: same-chain reference, cross-chain, Solana, and SDKs.