Note: It's not required to submit the funding transaction through the StableFX API. You can submit the transaction onchain using your own web3 provider or wallet by calling the appropriate maker contract methods directly.
This guide walks you through the steps to fulfill and execute a trade from the maker side on StableFX.
Before you begin this quickstart, ensure you have:
Permit2 contract. See
How-to: Grant USDC Allowance to Permit2
for more information.This quickstart provides API request examples in cURL format, along with example responses.
Query for trades with the confirmed status using the
get trades endpoint. These are trades
created by takers that are ready for maker fulfillment.
curl --request GET \
--url https://api-sandbox.circle.com/v1/exchange/stablefx/trades?type=maker&status=confirmed \
--header 'Accept: application/json' \
--header 'Authorization: Bearer ${YOUR_API_KEY}'
Response
{
"data": [
{
"id": "c2558cd1-98b5-4ccd-90b8-96891512af20",
"contractTradeId": "b4cdae0f-9285-48bf-8abf-109ae0177621",
"status": "confirmed",
"rate": "0.915",
"from": {
"currency": "USDC",
"amount": "1000.00"
},
"to": {
"currency": "EURC",
"amount": "915.00"
},
"createDate": "2025-08-07T11:01:00Z",
"updateDate": "2025-08-07T11:01:00Z",
"quoteId": "c4d1da72-111e-4d52-bdbf-2e74a2d803d5"
}
],
"pagination": {
"next": "",
"previous": ""
}
}
Choose a trade from the available confirmed trades that you want to fulfill as a maker. You'll need the trade ID for the subsequent steps.
Confirm your trade intent through the StableFX API before submitting the trade on the blockchain.
To submit the trade onchain, you must first sign the trade intent with an EIP-712 signature. To get the data to sign, call the generate trade presign data endpoint. Your request must include the ID of the trade you want to fulfill.
curl --request GET \
--url https://api-sandbox.circle.com/v1/exchange/stablefx/signatures/presign/maker/${stablefx_trade_id} \
--header 'Accept: application/json' \
--header 'Authorization: Bearer ${YOUR_API_KEY}'
Response
{
"consideration": {
"quoteId": "c4d1da72-111e-4d52-bdbf-2e74a2d803d5",
"base": "0x...",
"quote": "0x...",
"baseAmount": "100000000",
"quoteAmount": "91500000",
"maturity": 1752148800
},
"deadline": 1752149700,
"fee": "100000"
}
Using an EIP-712 compatible wallet or application, sign the data returned in the previous step.
Confirm your trade intent by submitting the signed data to the submit trade signature endpoint. This request must include the trade ID, the side of the trade that you are taking, the address of the wallet signing the payload, the data itself, and the signature on the data.
curl --request POST \
--url https://api-sandbox.circle.com/v1/exchange/stablefx/signatures \
--header 'Accept: application/json' \
--header 'Authorization: Bearer ${YOUR_API_KEY}' \
--header 'Content-Type: application/json' \
--data '
{
"tradeId": "${stablefx_trade_id}",
"type": "maker",
"address": "0xabc123...",
"details": {
"consideration": {
"quoteId": "c4d1da72-111e-4d52-bdbf-2e74a2d803d5",
"base": "0x...",
"quote": "0x...",
"baseAmount": "100000000",
"quoteAmount": "91500000",
"maturity": 1752148800
},
"deadline": 1752149700,
"fee": "100000"
},
"signature": "0xsignature"
}
'
If the signed data is accepted, the API returns a blank 200 response.
Next, you need to deliver the funds onchain to complete the trade. The StableFX
API can handle the onchain transaction for you using the Permit2 contract.
To use the StableFX API to deliver the funds onchain, you must first sign the funding typed data with an EIP-712 signature. To get the data to sign, call the generate funding presign data endpoint. Your request must include the contract ID of the trade and the side of the trade that you are taking. The following an example request:
curl --request POST \
--url https://api-sandbox.circle.com/v1/exchange/stablefx/signatures/funding/presign \
--header 'Accept: application/json' \
--header 'Authorization: Bearer ${YOUR_API_KEY}' \
--header 'Content-Type: application/json' \
--data '
{
"contractTradeIds": ["${stablefx_trade_id}"],
"type": "maker"
}
'
Response
{
"typedData": {
"domain": {
"name": "Permit2",
"chainId": 11155111,
"verifyingContract": "0xffd21ca8F0876DaFAD7de09404E0c1f868bbf1AE"
},
"types": {
"EIP712Domain": [
{
"name": "name",
"type": "string"
},
{
"name": "chainId",
"type": "uint256"
},
{
"name": "verifyingContract",
"type": "address"
}
],
"TokenPermissions": [
{
"name": "token",
"type": "address"
},
{
"name": "amount",
"type": "uint256"
}
],
"SingleTradeWitness": [
{
"name": "id",
"type": "uint256"
}
],
"PermitWitnessTransferFrom": [
{
"name": "permitted",
"type": "TokenPermissions"
},
{
"name": "spender",
"type": "address"
},
{
"name": "nonce",
"type": "uint256"
},
{
"name": "deadline",
"type": "uint256"
},
{
"name": "witness",
"type": "SingleTradeWitness"
}
]
},
"primaryType": "PermitWitnessTransferFrom",
"message": {
"permitted": {
"token": "0xTOKEN",
"amount": "1000"
},
"spender": "0xffd21ca8F0876DaFAD7de09404E0c1f868bbf1AE",
"nonce": "42",
"deadline": "1735689600",
"witness": {
"id": "10"
}
}
}
}
Using a Permit2-compliant EIP-712 compatible wallet or application, sign the
data returned in the previous step.
To deliver the funds onchain, you must submit the maker-specific Permit2 data
along with your signature to the
fund trade endpoint. The endpoint
allows you to submit either a single object or a batch of objects along with the
required signatures.
The following is an example request for a single trade:
curl --request POST \
--url https://api-sandbox.circle.com/v1/exchange/stablefx/fund \
--header 'Accept: application/json' \
--header 'Authorization: Bearer ${YOUR_API_KEY}' \
--header 'Content-Type: application/json' \
--data '
{
"type": "maker",
"signature": "0xsignature",
"permit2": {
"permitted": {
"token": "0xTOKEN1",
"amount": "915"
},
"spender": "0xTOKEN1",
"nonce": "123456",
"deadline": 1752149700,
"witness": {
"id": "123456"
}
}
}
'
If the signed data is accepted, the API returns a blank 200 response.
Note: It's not required to submit the funding transaction through the StableFX API. You can submit the transaction onchain using your own web3 provider or wallet by calling the appropriate maker contract methods directly.