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.