Skip to navigation

Quickstart

Convert USDC into AUSD on Ethereum using the Quotes and Transactions APIs.
Transaction lifecycle: your app requests a quote through the Agora API, which relays the request to the provider for pricing; the user funds the transaction, and both the provider and Agora API report status back to your app.
1

Getting started

Your organization needs to be fully KYB-approved. Contact Agora if you don’t yet have access.

You also need an API key authorized for quotes, created in the Agora dashboard. The secret is shown once, so save it before closing the dialog; see Authentication for how keys and roles work.

Finally, you need a wallet on Ethereum holding USDC to convert, plus a small amount of ETH for gas. The same steps work for other supported tokens and chains: just adjust the request in Request quotes to match.

2

Authenticate

Exchange your API key for a session JWT: POST /v0/auth/token with the key as a bearer token. Session JWTs are short-lived, so re-exchange as needed. See Authentication for the full key-management flow.

3

Request quotes

POST /v0/quotes with a sender and receiver (each { kind: "wallet", address, chain, currency }), and exactly one of senderAmount or receiverAmount to fix that side of the conversion. The response is an array of quotes, one per enabled provider that returned a route: compare fees and pick one.

Request a quote to convert 10 USDC on Ethereum to AUSD:

curl https://api.agora.finance/v0/quotes \
-H "Authorization: Bearer $SESSION_JWT" \
-H "Content-Type: application/json" \
-d '{
"sender": {
"kind": "wallet",
"address": "0xd8dA...",
"chain": "ethereum",
"currency": "usdc"
},
"receiver": {
"kind": "wallet",
"address": "0xd8dA...",
"chain": "ethereum",
"currency": "ausd"
},
"senderAmount": "10.00"
}'
4

Execute the quote

Walk the chosen quote’s executionSteps in order on the Requestor’s client, sending each transaction as you reach it. The deposit must land onchain by the quote’s expiresAt, 180 seconds after it was priced. See Quote validity for what happens if it doesn’t.

Each step’s transaction is ready to send as-is, so no decoding is needed:

Broadcast with viem
import { createPublicClient, createWalletClient, custom, http } from "viem";
import { mainnet } from "viem/chains";
const walletClient = createWalletClient({
chain: mainnet,
transport: custom(window.ethereum),
});
const publicClient = createPublicClient({
chain: mainnet,
transport: http(),
});
const [account] = await walletClient.getAddresses();
for (const step of quote.executionSteps) {
const hash = await walletClient.sendTransaction({
account,
to: step.transaction.to as `0x${string}`,
data: step.transaction.data as `0x${string}`,
value: BigInt(step.transaction.value),
});
const receipt = await publicClient.waitForTransactionReceipt({ hash });
if (receipt.status !== "success") {
throw new Error(`Execution step ${step.action} reverted`);
}
}
5

Poll for status

Every quote carries a transactionId, but the row it points to doesn’t exist until your deposit is observed: until then, GET /v0/transactions/{txnId} returns 404 transaction_not_found. If your deposit confirmed onchain, keep polling: the row appears shortly after, and re-quoting would start a second conversion. Request a new quote only if the deposit never landed before expiresAt. Once the row appears, poll GET /v0/transactions/{txnId} until status stops changing - see Tracking execution for the full state diagram, since failed isn’t always the end of the line.

curl https://api.agora.finance/v0/transactions/{txnId} \
-H "Authorization: Bearer $SESSION_JWT"

Repeat the poll until status settles. See POST /v0/quotes for the full request/response shape, the Quotes overview for every step type, or Transactions for the full status lifecycle.