Your first swap
Quote a rate and execute a swap between two currencies.
This walks the minimum API calls to swap one currency for another. It assumes you've completed Authentication and are signing requests.
1. Quote the rate
Ask what 100 USD is worth in USDC right now. Each Currency is a plain object with the amount in its smallest denomination as a string (value), an ISO/asset code, and decimals (crypto also carries a chain):
POST /quote.get
Content-Type: application/json
{
"currency_in": { "value": "100", "code": "USD", "decimals": 2 },
"currency_out": { "value": "0", "code": "USDC", "decimals": 6, "chain": "ethereum" }
}(On a quote, currency_out.value is only a placeholder — "0" asks "what's the output worth?".) Response:
{
"data": {
"bid": { "value": "998000", "code": "USDC", "decimals": 6 },
"ask": { "value": "1002000", "code": "USDC", "decimals": 6 },
"direction": "ask",
"fees": [],
"stablecoin": null
}
}Show this rate to your user, or use it server-side to estimate output.
2. Execute the swap
POST /transaction.initiateSwap
Content-Type: application/json
{
"currency_in": { "value": "1000", "code": "USD", "decimals": 2 },
"currency_out": { "value": "10000000", "code": "USDC", "decimals": 6, "chain": "ethereum" },
"external_accounts": { "from": null, "to": null }
}Pass a non-zero amount on both sides — currency_in is what you send, currency_out is the amount you expect back (take it from a recent quote.get). The engine checks that implied rate against the live market within a small tolerance, then re-quotes at execution time, so a slightly stale estimate is fine. The response is the new transaction id:
{ "data": "08a4d98b-07b1-4948-a6e7-7c0ee556d564" }This is a PENDING transaction id — poll it via transaction.get or await it via webhook. There is no client idempotency key; the swap re-quotes at execution time.
3. Wait for settlement
The swap settles asynchronously. You have two options:
- Webhook (recommended) — register a webhook and react to
transaction.updatedevents reporting a terminalstatus. See Webhook setup. - Polling — call
transaction.getwith the returned transactioniduntilstatus === "COMPLETED". Backoff aggressively.
Next steps
- Withdraw the proceeds to a bank account or wallet
- Listing balances to confirm the new
USDCbalance