> ## Documentation Index
> Fetch the complete documentation index at: https://developers.circle.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Before reading these docs, install the relevant Circle Skill to get pre-loaded context — skills are LLM-optimized and cover architecture decisions, correct flows, and common pitfalls. In Claude Code: run /plugin marketplace add circlefin/skills then /plugin install circle-skills@circle. With Vercel Skills CLI: run npx skills add circlefin/skills. Available skills: use-usdc https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-usdc/SKILL.md (balances, transfers, approvals on EVM and Solana); EURC has no skill — see https://developers.circle.com/stablecoins/what-is-eurc.md; bridge-stablecoin https://github.com/circlefin/skills/blob/master/plugins/circle/skills/bridge-stablecoin/SKILL.md (crosschain transfers via CCTP, USDC, EURC, and third-party assets); use-arc https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-arc/SKILL.md (Arc chain config, contract deployment, USDC bridging — Arc docs: https://docs.arc.io/llms.txt); use-circle-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-circle-wallets/SKILL.md (choose wallet type); use-developer-controlled-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-developer-controlled-wallets/SKILL.md (custodial wallets for payouts and treasury); use-user-controlled-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-user-controlled-wallets/SKILL.md (embedded wallets with Web2 login); use-modular-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-modular-wallets/SKILL.md (smart contract wallets with passkeys and ERC-4337); use-gateway https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-gateway/SKILL.md (unified USDC balance, nanopayments); use-smart-contract-platform https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-smart-contract-platform/SKILL.md (deploy, interact, monitor contracts). Pair any skill with the Circle MCP server for live SDK signatures, contract addresses, and chain IDs: {"mcpServers":{"circle":{"url":"https://api.circle.com/v1/codegen/mcp"}}}.
> Read the product overview first. Each product has an overview explaining when and why to use it. Read it before quickstarts.
> Pick the right wallet type. Developer-controlled (you hold keys), user-controlled (end user holds keys via PIN/social login), or modular (smart contract wallets with passkeys). See https://developers.circle.com/wallets.md.
> Use CCTP V2 for crosschain transfers. CCTP natively transfers USDC and EURC via burn-and-mint, and supports permissionless wrapping of third-party assets via lock-and-mint. V1 is legacy; always use V2 unless V1 is specified or the chain requires it (Noble, Sui, and Aptos still require V1). Migration guide: https://developers.circle.com/cctp/migration-from-v1-to-v2.md.
> Use Bridge Kit for frontend bridging. Wraps CCTP with a simpler SDK for user-facing apps. Use CCTP directly for backend transfers.
> Gas Station vs Paymaster. Gas Station sponsors gas for Circle Wallet transactions. Paymaster lets users pay gas in USDC. Different use cases — read both overviews.
> Gateway Nanopayments for sub-cent payments. Gasless USDC micropayments down to $0.000001 via x402 and batched settlement. For pay-per-request APIs, AI agent payments, streaming.
> Look up USDC addresses per chain. Never hardcode — use https://developers.circle.com/stablecoins/usdc-contract-addresses.md.
> Prefer SDKs over raw API calls. Node.js and Python SDKs handle auth, retries, and errors.
> API key required. Bearer token in Authorization header. Testnet and mainnet use separate keys and may use different base URLs depending on the product.
> Set up webhooks when available. Most operations are async. Webhooks deliver transaction confirmations and state changes.
> When calling list endpoints, paginate using pageSize and pageAfter until no nextPageAfter cursor is returned—stopping at the first page silently misses records.
> Building an AI agent? Start with the Agent Stack—Circle CLI, agent wallets, and nanopayments built for autonomous use cases: https://developers.circle.com/agent-stack.md.

# How-to: Exchange currencies

> Use the Mint Exchange API to exchange local fiat for USDC or swap between USDC and EURC through a quote, trade, and settlement flow.

Use the Mint Exchange API to exchange a supported local fiat currency for USDC
or to swap between USDC and EURC. This guide walks the full quote, trade, and
settle flow for every supported pair as variants of the same procedure. For the
conceptual model behind quotes, trades, settlement batches, and
delivery-versus-payment settlement, see
[Cross-currency exchange](/circle-mint/concepts/cross-currency-exchange).

## Prerequisites

Before you begin, make sure that you've:

* Contacted your Circle representative to activate Cross-Currency Exchange on
  your Circle Mint account.
* Linked a bank account to Circle Mint for the local fiat side of the trade (not
  required for USDC and EURC swaps).
* Configured API authentication per the
  [Getting Started quickstart](/circle-mint/quickstarts/getting-started). The
  examples use a `$API_KEY` environment variable for the bearer token and the
  sandbox base URL, `https://api-sandbox.circle.com`.

## Step 1. Register a fiat trading account

For BRL or MXN pairs, register the linked fiat account as the settlement account
for that currency by sending a `PUT` request to
[`/v1/exchange/fxConfigs/accounts`](/api-reference/circle-mint/cross-currency/create-fx-account).
This is a one-time setup per currency. Skip this step for USDC and EURC swaps
and for HKD trades whose fiat account is configured offline.

The `fiatAccountId` is the `id` of the fiat bank account you link to Circle
Mint. If you haven't linked one for this currency yet, create it first:

* BRL: create a PIX account with
  [`POST /v1/businessAccount/banks/pix`](/api-reference/circle-mint/account/create-business-pix-account).
  PIX accounts take Brazil-specific fields that wire accounts don't: `ispb`,
  `branchCode`, `taxId`, and `accountType`.
* MXN: create a wire account with
  [`POST /v1/businessAccount/banks/wires`](/api-reference/circle-mint/account/create-business-wire-account).

In both cases, the `id` returned in the response is the `fiatAccountId` used
when registering the account. For example, create the BRL PIX account:

```bash theme={null}
curl -X POST https://api-sandbox.circle.com/v1/businessAccount/banks/pix \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "idempotencyKey": "6b3d1b3a-1e2c-4b5a-9c6d-2f0a8b7c4d5e",
    "name": "CIRCLE INTERNET FINANCIAL INC",
    "accountNumber": "322286803",
    "ispb": "68033222",
    "branchCode": "123",
    "taxId": "57112345675712",
    "accountType": "checking"
  }'
```

Expected response:

```json theme={null}
{
  "data": {
    "id": "b8627ae8-732b-4d25-b947-1df8f4007a29",
    "status": "pending",
    "description": "BTG Pactual ****0010",
    "trackingRef": "CIR13FB13A"
  }
}
```

Then register that account as the settlement account for its currency:

```bash theme={null}
curl -X PUT https://api-sandbox.circle.com/v1/exchange/fxConfigs/accounts \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "fiatAccountId": "763a80d8-9bbb-4876-a67d-e8089389b016",
    "currency": "MXN"
  }'
```

Expected response:

```json theme={null}
{
  "data": {
    "currency": "MXN",
    "fiatAccountId": "763a80d8-9bbb-4876-a67d-e8089389b016",
    "createDate": "2026-04-10T17:50:09.452Z",
    "updateDate": "2026-04-10T17:50:09.452Z"
  }
}
```

To register a Brazilian real account instead, set `currency` to `BRL` and use
the `id` returned when you created the PIX account.

## Step 2. Check the daily limit

Verify that the trade you plan to create has enough daily headroom by calling
[`GET /v1/exchange/fxConfigs/dailyLimits`](/api-reference/circle-mint/cross-currency/get-daily-fx-limits).
The endpoint returns the per-currency limit, the amount used so far in the
current day, and the amount still available. Trades that would exceed the
available amount are rejected at submission.

```bash theme={null}
curl https://api-sandbox.circle.com/v1/exchange/fxConfigs/dailyLimits \
  -H "Authorization: Bearer $API_KEY"
```

Expected response:

```json theme={null}
{
  "data": {
    "dailyLimits": {
      "EURC": {
        "limit": "1000000.00",
        "usage": "0.00",
        "available": "1000000.00"
      },
      "MXN": {
        "limit": "1000000.00",
        "usage": "0.00",
        "available": "1000000.00"
      },
      "USDC": {
        "limit": "1000000.00",
        "usage": "0.00",
        "available": "1000000.00"
      },
      "BRL": {
        "limit": "1000000.00",
        "usage": "0.00",
        "available": "1000000.00"
      }
    }
  }
}
```

## Step 3. Request a tradable quote

Send a `POST` request to
[`/v1/exchange/quotes`](/api-reference/circle-mint/cross-currency/get-quote)
with `type` set to `tradable` to lock a rate for 3 seconds. Reference quotes are
indicative only and cannot be accepted in Step 4; see the
[quote types section](/circle-mint/concepts/cross-currency-exchange#quote-types)
for the distinction.

```bash theme={null}
curl -X POST https://api-sandbox.circle.com/v1/exchange/quotes \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "tradable",
    "from": {
      "currency": "MXN",
      "amount": "100.00"
    },
    "to": {
      "currency": "USDC"
    }
  }'
```

Expected response:

```json theme={null}
{
  "data": {
    "id": "17e1ad29-a223-4ba0-bfb1-cebe861bfed1",
    "rate": 0.0597,
    "from": {
      "currency": "MXN",
      "amount": "100.00"
    },
    "to": {
      "currency": "USDC",
      "amount": "5.97"
    },
    "expiry": "2026-04-10T14:37:23.804Z",
    "type": "tradable",
    "estimatedSettlementTime": "2026-04-10T17:37:23.804Z"
  }
}
```

To request a quote for a USDC and EURC swap, use the same endpoint with `from`
and `to` set to `USDC` and `EURC` (in either direction) and the `tradable` quote
type.

## Step 4. Accept the quote by creating a trade

Lock the quoted rate by sending a `POST` request to
[`/v1/exchange/trades`](/api-reference/circle-mint/cross-currency/create-fx-trade)
with the `quoteId` from Step 3 and a new `idempotencyKey`. Only `tradable`
quotes are accepted; submitting a `reference` quote returns an error.

```bash theme={null}
curl -X POST https://api-sandbox.circle.com/v1/exchange/trades \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "idempotencyKey": "7a6cba1e-6b8d-4bb8-b236-5c20a12e88f6",
    "quoteId": "17e1ad29-a223-4ba0-bfb1-cebe861bfed1"
  }'
```

Expected response:

```json theme={null}
{
  "data": {
    "id": "7a6cba1e-6b8d-4bb8-b236-5c20a12e88f6",
    "from": {
      "currency": "MXN",
      "amount": "100.00"
    },
    "to": {
      "currency": "USDC",
      "amount": "5.97"
    },
    "status": "pending",
    "createDate": "2026-04-10T14:37:20.804Z",
    "updateDate": "2026-04-10T14:37:20.804Z",
    "quoteId": "17e1ad29-a223-4ba0-bfb1-cebe861bfed1"
  }
}
```

Record the trade `id`. You use it in Step 6 to poll the trade status.

## Step 5. Retrieve settlement instructions and send funds

This step applies to fiat pairs. For USDC and EURC swaps, no inbound transfer is
required; see the note at the end of this step.

Fetch the per-currency beneficiary details by sending a `GET` request to
[`/v1/exchange/trades/settlements/instructions/{currency}`](/api-reference/circle-mint/cross-currency/get-settlement-instructions).
The endpoint accepts `BRL` and `MXN` as path parameters. Settlement instructions
are static for a given currency and can be cached and reused across trades.

```bash theme={null}
curl https://api-sandbox.circle.com/v1/exchange/trades/settlements/instructions/MXN \
  -H "Authorization: Bearer $API_KEY"
```

For MXN, the response returns wire-style instructions. Send the inbound peso
transfer on the SPEI rail using these details and include the `trackingRef` in
the wire reference field so Circle can match the inbound transfer to the trade.

```json theme={null}
{
  "data": {
    "currency": "MXN",
    "fiatAccountType": "wire",
    "instruction": {
      "beneficiary": {
        "name": "CIRCLE INTERNET FINANCIAL INC",
        "address1": "99 HIGH STREET",
        "address2": "BOSTON MA 02110"
      },
      "beneficiaryBank": {
        "name": "CIRCLE BANKING PARTNER",
        "swiftCode": "BANKMXMMXXX",
        "routingNumber": "322286803",
        "accountNumber": "127180987654321012",
        "currency": "MXN",
        "address": "AVENIDA INSURGENTES SUR 3579",
        "postalCode": "14020",
        "country": "MX"
      },
      "trackingRef": "ezBrwN2nP5Bz18Lu"
    }
  }
}
```

For BRL, the response returns PIX instructions. After the trade reaches
settlement, call
[`GET /v1/exchange/trades/settlements`](/api-reference/circle-mint/cross-currency/get-settlements)
and read `reference` from the payable entry in `details[]`. Send the inbound
transfer on the PIX rail using that value as the payment reference and the
`accountNumber` from the instructions as the destination.

```json theme={null}
{
  "data": {
    "currency": "BRL",
    "fiatAccountType": "pix",
    "instruction": {
      "ispb": "87654321",
      "branchCode": "0001",
      "accountNumber": "12345678",
      "name": "Circle Internet Financial LLC",
      "accountType": "checking",
      "taxId": "12.345.678/0001-90",
      "bankName": "Banco Example S.A.",
      "compeCode": "000"
    }
  }
}
```

For HKD↔USDC trades, settlement instructions are exchanged out of band and
follow a similar wire-based pattern using the CHATS rail. Confirm the inbound
transfer details with Circle before sending HKD.

<Tip>
  In the sandbox, simulate the inbound BRL leg with
  [`POST /v1/mocks/payments/pix`](/api-reference/circle-mint/cross-currency/create-mock-pix-payment).
  After the trade reaches settlement:

  1. Call
     [`GET /v1/exchange/trades/settlements`](/api-reference/circle-mint/cross-currency/get-settlements).
  2. Read `reference` from the payable entry in `details[]`, for example
     `FXR3T6YSTY`.
  3. Use that value as `trackingRef` in the mock request, along with the
     `accountNumber` from the settlement instructions.

  Note that `GET /v1/exchange/trades/settlements/instructions/BRL` does not
  include the per-trade reference in sandbox; it only appears in the settlements
  batch returned by `GET /v1/exchange/trades/settlements`.

  ```bash theme={null}
  curl -X POST https://api-sandbox.circle.com/v1/mocks/payments/pix \
    -H "Authorization: Bearer $API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "trackingRef": "FXR3T6YSTY",
      "amount": {
        "amount": "100.00",
        "currency": "BRL"
      },
      "accountNumber": "12345678"
    }'
  ```

  Expected response:

  ```json theme={null}
  {
    "data": {
      "trackingRef": "FXR3T6YSTY",
      "amount": {
        "amount": "100.00",
        "currency": "BRL"
      },
      "beneficiaryAccountNumber": "12345678",
      "status": "pending"
    }
  }
  ```
</Tip>

<Note>
  USDC and EURC swaps do not require an inbound transfer. Both legs are debited
  and credited against the Mint balance per the settlement schedule configured
  offline with Circle. See
  [delivery-versus-payment settlement](/circle-mint/concepts/cross-currency-exchange#delivery-versus-payment-settlement)
  for details.
</Note>

## Step 6. Poll the trade status

Send a `GET` request to
[`/v1/exchange/trades/{id}`](/api-reference/circle-mint/cross-currency/get-fx-trade-id)
to track the trade as it moves toward settlement. The trade transitions through
`pending`, `confirmed`, `pending_settlement`, and `complete` (or `failed`) as it
progresses. See the
[trade and settlement lifecycle](/circle-mint/concepts/cross-currency-exchange#trade-and-settlement-lifecycle)
for the full state machine.

```bash theme={null}
curl https://api-sandbox.circle.com/v1/exchange/trades/7a6cba1e-6b8d-4bb8-b236-5c20a12e88f6 \
  -H "Authorization: Bearer $API_KEY"
```

Expected response:

```json theme={null}
{
  "data": {
    "id": "7a6cba1e-6b8d-4bb8-b236-5c20a12e88f6",
    "from": {
      "currency": "MXN",
      "amount": "100.00"
    },
    "to": {
      "currency": "USDC",
      "amount": "5.97"
    },
    "status": "complete",
    "createDate": "2026-04-10T14:37:20.804Z",
    "updateDate": "2026-04-10T14:55:00.000Z",
    "quoteId": "17e1ad29-a223-4ba0-bfb1-cebe861bfed1",
    "settlementId": "67276b7d-7ea5-4f22-a231-09e2d2891c36",
    "rate": "0.0597",
    "expectedBatchTime": "2026-04-10T15:00:00.000Z",
    "estimatedSettlementTime": "2026-04-10T17:00:00.000Z"
  }
}
```

## Step 7. Retrieve the settlement batch

Once the trade reaches `complete`, retrieve the settlement batch that holds the
trade's legs by sending a `GET` request to
[`/v1/exchange/trades/settlements`](/api-reference/circle-mint/cross-currency/get-settlements).
Use the `type` query parameter to filter for the inbound (`account_receivable`)
or outbound (`account_payable`) side. Each batch lists its legs in the `details`
array, marked as `payable` and `receivable`.

```bash theme={null}
curl "https://api-sandbox.circle.com/v1/exchange/trades/settlements?type=account_receivable" \
  -H "Authorization: Bearer $API_KEY"
```

Expected response:

```json theme={null}
{
  "data": [
    {
      "id": "67276b7d-7ea5-4f22-a231-09e2d2891c36",
      "entityId": "c5692eb6-33f9-431d-9481-2eee38f02081",
      "status": "settled",
      "createDate": "2026-04-10T14:45:04.729Z",
      "updateDate": "2026-04-10T14:55:00.000Z",
      "details": [
        {
          "id": "02bd22dc-b40f-49b8-b2d8-6e69f82cfca0",
          "type": "payable",
          "status": "completed",
          "reference": "ezBrwN2nP5Bz18Lu",
          "amount": {
            "currency": "MXN",
            "amount": "100.00"
          },
          "createDate": "2026-04-10T14:45:04.728Z",
          "updateDate": "2026-04-10T14:55:00.000Z"
        },
        {
          "id": "afbd8d53-34ea-42fa-9691-4a5c0dd96c53",
          "type": "receivable",
          "status": "completed",
          "amount": {
            "currency": "USDC",
            "amount": "5.97"
          },
          "createDate": "2026-04-10T14:45:04.728Z",
          "updateDate": "2026-04-10T14:55:00.000Z"
        }
      ]
    }
  ]
}
```

Repeat the request with `type=account_payable` to retrieve the outbound leg.

* [Getting Started](/circle-mint/quickstarts/getting-started): Authenticate to
  the Mint API and set up an API key.
