> For a complete index of Agora Finance documentation, fetch https://docs.agora.finance/llms.txt

# Quickstart

![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.](/_fern-img/41759890b8f850deab4d0b7d07558dac24347536f404a8e8c410db350a7d2e0a.webp)

## 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](/api/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](#request-quotes) to match.

## Authenticate

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

## Request quotes

[`POST /v0/quotes`](/api/endpoints/quotes/create) 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`**

```curl title="cURL"
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"
  }'
```

**`TypeScript`**

```typescript title="TypeScript"
const response = await fetch("https://api.agora.finance/v0/quotes", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${sessionJwt}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    sender: {
      kind: "wallet",
      address,
      chain: "ethereum",
      currency: "usdc",
    },
    receiver: {
      kind: "wallet",
      address,
      chain: "ethereum",
      currency: "ausd",
    },
    senderAmount: "10.00",
  }),
});
const { quotes } = await response.json();
const quote = quotes[0];
```

## Execute the quote

Walk the chosen quote's [`executionSteps`](/api/endpoints/quotes/overview#executing-a-quote) 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](/api/guides/convert-stablecoins/overview#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`**

```typescript title="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`);
  }
}
```

## 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}`](/api/endpoints/transactions/getbyid) until `status` stops changing - see [Tracking execution](/api/guides/convert-stablecoins/overview#tracking-execution) for the full state diagram, since `failed` isn't always the end of the line.

**`cURL`**

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

**`TypeScript`**

```typescript title="TypeScript"
const status = await fetch(
  `https://api.agora.finance/v0/transactions/${quote.transactionId}`,
  { headers: { Authorization: `Bearer ${sessionJwt}` } },
).then((r) => r.json());
```

Repeat the poll until `status` settles. See [`POST /v0/quotes`](/api/endpoints/quotes/create) for the full request/response shape, the [Quotes overview](/api/endpoints/quotes/overview#executing-a-quote) for every step type, or [Transactions](/api/endpoints/transactions/overview#status) for the full `status` lifecycle.