Skip to main content

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.

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.

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. The examples below 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. 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.
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:
{
  "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 PIX bank account id returned by your account setup.

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. 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.
curl https://api-sandbox.circle.com/v1/exchange/fxConfigs/dailyLimits \
  -H "Authorization: Bearer $API_KEY"
Expected response:
{
  "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 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 for the distinction.
curl -X POST https://api-sandbox.circle.com/v1/exchange/quotes \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "tradable",
    "idempotencyKey": "07c238ad-b144-4607-9b70-51d1ffbb3c7b",
    "from": {
      "currency": "MXN",
      "amount": "100.00"
    },
    "to": {
      "currency": "USDC"
    }
  }'
Expected response:
{
  "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). The request requires the same idempotencyKey and 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 with the quoteId from Step 3 and a new idempotencyKey. Only tradable quotes are accepted; submitting a reference quote returns an error.
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:
{
  "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}. 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.
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.
{
  "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. Send the inbound transfer on the PIX rail and include the trackingRef in the PIX reference field.
{
  "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"
    }
  }
}
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.
In the sandbox, simulate the inbound BRL leg with POST /v1/mocks/payments/pix. Provide the trackingRef from the settlement instructions and the destination accountNumber.
curl -X POST https://api-sandbox.circle.com/v1/mocks/payments/pix \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "trackingRef": "ezBrwN2nP5Bz18Lu",
    "amount": {
      "amount": "100.00",
      "currency": "BRL"
    },
    "accountNumber": "12345678"
  }'
Expected response:
{
  "data": {
    "trackingRef": "ezBrwN2nP5Bz18Lu",
    "amount": {
      "amount": "100.00",
      "currency": "BRL"
    },
    "beneficiaryAccountNumber": "12345678",
    "status": "pending"
  }
}
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 for details.

Step 6. Poll the trade status

Send a GET request to /v1/exchange/trades/{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 for the full state machine.
curl https://api-sandbox.circle.com/v1/exchange/trades/7a6cba1e-6b8d-4bb8-b236-5c20a12e88f6 \
  -H "Authorization: Bearer $API_KEY"
Expected response:
{
  "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. 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.
curl "https://api-sandbox.circle.com/v1/exchange/trades/settlements?type=account_receivable" \
  -H "Authorization: Bearer $API_KEY"
Expected response:
{
  "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.