Skip to main content
Use the Mint Exchange API to exchange a supported local fiat currency for USDC or to swap between USDC and EURC. The following steps use an MXN to USDC trade as the worked example. Every supported pair follows the same quote, trade, and settle flow, so you can adapt the requests by changing the currency codes and the fiat account type. For the conceptual model and the current list of supported pairs, see Cross-currency exchange.

Prerequisites

Before you begin, ensure that you’ve:
  • Confirmed with Circle that Cross-Currency Exchange is enabled on your Circle Mint account. Activation requires a signed Cross-Currency MSA and a contracting entity that supports your pair, as listed in the supported currency pairs table. For example, SGD to USDC is available only to accounts contracted with Circle SG. To request activation, contact your Circle representative.
  • 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 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 a fiat pair, register the linked bank account as the trading account for the fiat 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. The fiatAccountId is the id of the fiat bank account you link to Circle Mint. For MXN, link a wire account with POST /v1/businessAccount/banks/wires if you haven’t already, and use the id from the response. Other currencies may need a different account type; see supported currency pairs. Register the account, setting currency to the fiat leg of the pair:
Expected response:

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.
Expected response:

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.
Expected response:
For another pair, replace MXN with the currency you’re exchanging. Exactly one of from and to must be USDC. For a USDC and EURC swap, set from and to to USDC and EURC in either direction.

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.
Expected response:
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 beneficiary details for the fiat leg by sending a GET request to /v1/exchange/trades/settlements/instructions/{currency}, with the currency code of the fiat you’re sending as the path parameter. The shape of the instructions depends on the payment rail. Settlement instructions are static for a given currency and can be cached and reused across trades.
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.
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.
Expected response:

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.
Expected response:
Repeat the request with type=account_payable to retrieve the outbound leg.