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 Stablecoin Payouts API to send USDC or EURC onchain to a third-party
recipient, such as vendors, contractors, or customers. The flow differs by
Circle entity: Circle LLC (US) applies Travel Rule data at a $3,000
USD-equivalent threshold, while Circle Singapore (CIRCLE_SG) requires
beneficiary identity, wallet ownership, and a payment reason code on every
payout. This page documents both. For the underlying model, see
How Stablecoin Payins and Payouts Work.
Stablecoin Payouts are for third-party recipients (wallets your business does
not own or control). To move funds between wallets your business owns, see
Transfer Onchain.
Prerequisites
Before you begin:
- Stablecoin Payouts is enabled on your Circle Mint account. The product is
available through Circle LLC (US) and Circle Singapore (CIRCLE_SG). To request
activation, contact Circle Mint.
- A Circle Mint sandbox API key. See
Get started with Circle Mint.
- A source wallet ID (
source.id) with funds available for payouts.
- For CIRCLE_SG only: the Virtual Asset Service Provider (VASP) that holds the
recipient’s wallet, when the wallet is hosted.
- The destination address is on a blockchain supported by the Stablecoin Payouts
API. See
Supported chains and currencies.
For XRP destinations (chain: "XRP"), the Stablecoin Payouts API supports only
the classic-address format (for example, rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY).
The x-address format is not supported. Use the addressTag field to specify the
destination tag.
Steps
Circle LLC (US)
Circle Singapore
Step 1. Register the recipient
Add the recipient to your address book with POST /v1/addressBook/recipients.
Provide idempotencyKey, chain, and address. The metadata fields
(nickname, email, bns) are optional.curl -X POST https://api-sandbox.circle.com/v1/addressBook/recipients \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"idempotencyKey": "9352ec9e-5ee6-441f-ab42-186bc71fbdde",
"chain": "BASE",
"address": "0x65BFCf1a6289a0b77b4D3F7d12005a05949FD8C3",
"metadata": {
"nickname": "Acme Corp payout address",
"email": "ap@acme.example",
"bns": "acme.base.eth"
}
}'
{
"data": {
"id": "dff5fcb3-2e52-5c13-8a66-a5be9c7ecbe1",
"chain": "BASE",
"address": "0x65bfcf1a6289a0b77b4d3f7d12005a05949fd8c3",
"metadata": {
"nickname": "Acme Corp payout address",
"email": "ap@acme.example",
"bns": "acme.base.eth"
},
"status": "pending",
"createDate": "2026-05-01T14:16:34.985353Z",
"updateDate": "2026-05-01T14:16:34.985353Z"
}
}
The recipient transitions out of pending according to your Mint Console
Delayed withdrawals setting. When delayed withdrawals are on, new recipients
stay inactive for 24 hours before becoming active. When delayed withdrawals
are off, recipients become active in seconds.Step 1.1. Wait for active status
The recipient must be active before you submit a payout.Subscribe to addressBookRecipients notifications. Circle sends an event when
the recipient is created and when its status changes.{
"clientId": "a03a47ff-b0eb-4070-b3df-dc66752cc802",
"notificationType": "addressBookRecipients",
"version": 1,
"addressBookRecipient": {
"id": "dff5fcb3-2e52-5c13-8a66-a5be9c7ecbe1",
"chain": "BASE",
"address": "0x65bfcf1a6289a0b77b4d3f7d12005a05949fd8c3",
"status": "active",
"createDate": "2026-05-01T14:16:34.985353Z",
"updateDate": "2026-05-01T14:18:02.123456Z"
}
}
Call GET /v1/addressBook/recipients/{id} on an interval until status is
active.curl https://api-sandbox.circle.com/v1/addressBook/recipients/dff5fcb3-2e52-5c13-8a66-a5be9c7ecbe1 \
-H "Authorization: Bearer $API_KEY"
{
"data": {
"id": "dff5fcb3-2e52-5c13-8a66-a5be9c7ecbe1",
"chain": "BASE",
"address": "0x65bfcf1a6289a0b77b4d3f7d12005a05949fd8c3",
"status": "active",
"createDate": "2026-05-01T14:16:34.985353Z",
"updateDate": "2026-05-01T14:18:02.123456Z"
}
}
Step 2. Send the payout
Call POST /v1/payouts with the source wallet, the recipient id as the
destination, and the amounts.Travel Rule applies to payouts of $3,000 USD-equivalent or more. Include
source.identities[] to describe the originator (your organization or your end
customer). See
Travel Rule compliance for the
schema and failure modes. Below threshold
At or above threshold
curl -X POST https://api-sandbox.circle.com/v1/payouts \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"idempotencyKey": "ba943ff1-ca16-49b2-ba55-1057e70ca5c7",
"source": {
"type": "wallet",
"id": "12345"
},
"destination": {
"type": "address_book",
"id": "dff5fcb3-2e52-5c13-8a66-a5be9c7ecbe1"
},
"amount": {
"amount": "500.00",
"currency": "USD"
},
"toAmount": {
"currency": "USD"
}
}'
curl -X POST https://api-sandbox.circle.com/v1/payouts \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @body.json
{
"idempotencyKey": "ba943ff1-ca16-49b2-ba55-1057e70ca5c7",
"source": {
"type": "wallet",
"id": "12345",
"identities": [
{
"type": "individual",
"name": "Satoshi Nakamoto",
"addresses": [
{
"line1": "100 Money Street",
"line2": "Suite 1",
"city": "Boston",
"district": "MA",
"postalCode": "01234",
"country": "US"
}
]
}
]
},
"destination": {
"type": "address_book",
"id": "dff5fcb3-2e52-5c13-8a66-a5be9c7ecbe1"
},
"amount": {
"amount": "3000.14",
"currency": "USD"
},
"toAmount": {
"currency": "USD"
}
}
{
"data": {
"id": "b8627ae8-732b-4d25-b947-1df8f4007a29",
"sourceWalletId": "12345",
"destination": {
"type": "address_book",
"id": "dff5fcb3-2e52-5c13-8a66-a5be9c7ecbe1"
},
"amount": {
"amount": "3000.14",
"currency": "USD"
},
"toAmount": {
"amount": "3000.14",
"currency": "USD"
},
"status": "pending",
"createDate": "2026-05-01T14:20:30.000Z",
"updateDate": "2026-05-01T14:20:30.000Z"
}
}
Step 3. Confirm completion
Wait for the payout to reach status: complete.Subscribe to payouts notifications. The payload includes the payout under the
payout key.{
"clientId": "a03a47ff-b0eb-4070-b3df-dc66752cc802",
"notificationType": "payouts",
"version": 1,
"payout": {
"id": "b8627ae8-732b-4d25-b947-1df8f4007a29",
"sourceWalletId": "12345",
"destination": {
"type": "address_book",
"id": "dff5fcb3-2e52-5c13-8a66-a5be9c7ecbe1"
},
"amount": {
"amount": "3000.14",
"currency": "USD"
},
"toAmount": {
"amount": "3000.14",
"currency": "USD"
},
"fees": {
"amount": "0.00",
"currency": "USD"
},
"networkFees": {
"amount": "0.30",
"currency": "USD"
},
"status": "complete",
"createDate": "2026-05-01T14:20:30.000Z",
"updateDate": "2026-05-01T14:21:12.000Z"
}
}
Call GET /v1/payouts/{id} on an interval until status is complete.curl https://api-sandbox.circle.com/v1/payouts/b8627ae8-732b-4d25-b947-1df8f4007a29 \
-H "Authorization: Bearer $API_KEY"
{
"data": {
"id": "b8627ae8-732b-4d25-b947-1df8f4007a29",
"sourceWalletId": "12345",
"destination": {
"type": "address_book",
"id": "dff5fcb3-2e52-5c13-8a66-a5be9c7ecbe1"
},
"amount": {
"amount": "3000.14",
"currency": "USD"
},
"toAmount": {
"amount": "3000.14",
"currency": "USD"
},
"fees": {
"amount": "0.00",
"currency": "USD"
},
"networkFees": {
"amount": "0.30",
"currency": "USD"
},
"status": "complete",
"createDate": "2026-05-01T14:20:30.000Z",
"updateDate": "2026-05-01T14:21:12.000Z"
}
}
The CIRCLE_SG flow has additional requirements: beneficiary identity and
ownership on the recipient, purposeOfTransfer on the payout, and Travel Rule
applies to payouts of all amounts.Step 1. Look up the recipient’s VASP
For hosted-wallet recipients, you need the vaspId of the Virtual Asset Service
Provider (VASP) that holds the wallet. Call GET /v1/addressBook/vasps to list
the VASP records active in your jurisdiction. This endpoint is available only to
CIRCLE_SG customers.curl https://api-sandbox.circle.com/v1/addressBook/vasps \
-H "Authorization: Bearer $API_KEY"
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Anchorage Digital"
},
{
"id": "661f9511-f30c-52e5-b660-709766551111",
"name": "Coinhako"
},
{
"id": "772a0622-041d-63f6-c771-810877662222",
"name": "Paxos"
}
]
}
If the recipient self-custodies, self-hosted wallets are not yet supported on
the CIRCLE_SG flow. The recipient must hold the destination wallet at a listed
VASP.Step 2. Register the recipient with identity and ownership
Call POST /v1/addressBook/recipients with chain, address, identity, and
ownership. Use the request body that matches the recipient type. Individual recipient
Business recipient
curl -X POST https://api-sandbox.circle.com/v1/addressBook/recipients \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @body.json
{
"idempotencyKey": "9352ec9e-5ee6-441f-ab42-186bc71fbdde",
"chain": "BASE",
"address": "0x65BFCf1a6289a0b77b4D3F7d12005a05949FD8C3",
"metadata": {
"nickname": "Ada Lovelace"
},
"identity": {
"type": "individual",
"firstName": "Ada",
"lastName": "Lovelace"
},
"ownership": {
"type": "third_party",
"custody": {
"type": "hosted",
"vaspId": "550e8400-e29b-41d4-a716-446655440000"
}
}
}
curl -X POST https://api-sandbox.circle.com/v1/addressBook/recipients \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @body.json
{
"idempotencyKey": "9352ec9e-5ee6-441f-ab42-186bc71fbdde",
"chain": "BASE",
"address": "0x65BFCf1a6289a0b77b4D3F7d12005a05949FD8C3",
"metadata": {
"nickname": "Acme Corp payout address"
},
"identity": {
"type": "business",
"businessName": "Acme Corp"
},
"ownership": {
"type": "third_party",
"custody": {
"type": "hosted",
"vaspId": "550e8400-e29b-41d4-a716-446655440000"
}
}
}
{
"data": {
"id": "8755d0ea-14f9-4259-b092-de23c14b6568",
"chain": "BASE",
"address": "0x65bfcf1a6289a0b77b4d3f7d12005a05949fd8c3",
"metadata": {
"nickname": "Ada Lovelace"
},
"status": "pending",
"identity": {
"type": "individual",
"firstName": "Ada",
"lastName": "Lovelace"
},
"ownership": {
"type": "third_party",
"custody": {
"type": "hosted",
"vaspId": "550e8400-e29b-41d4-a716-446655440000"
}
},
"createDate": "2026-05-01T14:16:34.985353Z",
"updateDate": "2026-05-01T14:16:34.985353Z"
}
}
The recipient transitions from pending to active after risk review.You cannot modify identity (error 2036) or ownership (error 2037) on an
existing recipient through PATCH. To change either, register a new recipient.
Step 2.1. Wait for active status
Wait for the recipient status to become active.Subscribe to addressBookRecipients notifications. Circle sends an event when
the recipient is created and when its status changes.{
"clientId": "a03a47ff-b0eb-4070-b3df-dc66752cc802",
"notificationType": "addressBookRecipients",
"version": 1,
"addressBookRecipient": {
"id": "8755d0ea-14f9-4259-b092-de23c14b6568",
"chain": "BASE",
"address": "0x65bfcf1a6289a0b77b4d3f7d12005a05949fd8c3",
"status": "active",
"identity": {
"type": "individual",
"firstName": "Ada",
"lastName": "Lovelace"
},
"ownership": {
"type": "third_party",
"custody": {
"type": "hosted",
"vaspId": "550e8400-e29b-41d4-a716-446655440000"
}
},
"createDate": "2026-05-01T14:16:34.985353Z",
"updateDate": "2026-05-01T14:18:02.123456Z"
}
}
Call GET /v1/addressBook/recipients/{id} on an interval until status is
active.curl https://api-sandbox.circle.com/v1/addressBook/recipients/8755d0ea-14f9-4259-b092-de23c14b6568 \
-H "Authorization: Bearer $API_KEY"
{
"data": {
"id": "8755d0ea-14f9-4259-b092-de23c14b6568",
"chain": "BASE",
"address": "0x65bfcf1a6289a0b77b4d3f7d12005a05949fd8c3",
"status": "active",
"identity": {
"type": "individual",
"firstName": "Ada",
"lastName": "Lovelace"
},
"ownership": {
"type": "third_party",
"custody": {
"type": "hosted",
"vaspId": "550e8400-e29b-41d4-a716-446655440000"
}
},
"createDate": "2026-05-01T14:16:34.985353Z",
"updateDate": "2026-05-01T14:18:02.123456Z"
}
}
Step 3. Send the payout
Call POST /v1/payouts with the originator identities, the destination, the
amounts, and purposeOfTransfer. Travel Rule applies on every CIRCLE_SG payout
regardless of amount, so source.identities[] is always required.
purposeOfTransfer is one of PMT000 to PMT030 except PMT006. See
payment reason codes.curl -X POST https://api-sandbox.circle.com/v1/payouts \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @body.json
{
"idempotencyKey": "ba943ff1-ca16-49b2-ba55-1057e70ca5c7",
"source": {
"type": "wallet",
"id": "12345",
"identities": [
{
"type": "business",
"name": "Example Pte. Ltd.",
"addresses": [
{
"line1": "1 Raffles Place",
"line2": "#20-01",
"city": "Singapore",
"district": "Singapore",
"postalCode": "048616",
"country": "SG"
}
]
}
]
},
"destination": {
"type": "address_book",
"id": "8755d0ea-14f9-4259-b092-de23c14b6568"
},
"amount": {
"amount": "500.00",
"currency": "USD"
},
"toAmount": {
"currency": "USD"
},
"purposeOfTransfer": "PMT001"
}
{
"data": {
"id": "b8627ae8-732b-4d25-b947-1df8f4007a29",
"sourceWalletId": "12345",
"destination": {
"type": "address_book",
"id": "8755d0ea-14f9-4259-b092-de23c14b6568"
},
"amount": {
"amount": "500.00",
"currency": "USD"
},
"toAmount": {
"amount": "500.00",
"currency": "USD"
},
"purposeOfTransfer": "PMT001",
"status": "pending",
"createDate": "2026-05-01T14:20:30.000Z",
"updateDate": "2026-05-01T14:20:30.000Z"
}
}
Step 4. Confirm completion
Wait for the payout to reach status: complete.Subscribe to payouts notifications. The payload includes the payout under the
payout key.{
"clientId": "a03a47ff-b0eb-4070-b3df-dc66752cc802",
"notificationType": "payouts",
"version": 1,
"payout": {
"id": "b8627ae8-732b-4d25-b947-1df8f4007a29",
"sourceWalletId": "12345",
"destination": {
"type": "address_book",
"id": "8755d0ea-14f9-4259-b092-de23c14b6568"
},
"amount": {
"amount": "500.00",
"currency": "USD"
},
"toAmount": {
"amount": "500.00",
"currency": "USD"
},
"fees": {
"amount": "0.00",
"currency": "USD"
},
"networkFees": {
"amount": "0.30",
"currency": "USD"
},
"purposeOfTransfer": "PMT001",
"status": "complete",
"createDate": "2026-05-01T14:20:30.000Z",
"updateDate": "2026-05-01T14:21:12.000Z"
}
}
Call GET /v1/payouts/{id} on an interval until status is complete.curl https://api-sandbox.circle.com/v1/payouts/b8627ae8-732b-4d25-b947-1df8f4007a29 \
-H "Authorization: Bearer $API_KEY"
{
"data": {
"id": "b8627ae8-732b-4d25-b947-1df8f4007a29",
"sourceWalletId": "12345",
"destination": {
"type": "address_book",
"id": "8755d0ea-14f9-4259-b092-de23c14b6568"
},
"amount": {
"amount": "500.00",
"currency": "USD"
},
"toAmount": {
"amount": "500.00",
"currency": "USD"
},
"fees": {
"amount": "0.00",
"currency": "USD"
},
"networkFees": {
"amount": "0.30",
"currency": "USD"
},
"purposeOfTransfer": "PMT001",
"status": "complete",
"createDate": "2026-05-01T14:20:30.000Z",
"updateDate": "2026-05-01T14:21:12.000Z"
}
}
Failure modes
Failures fall into two categories. Synchronous validation errors return HTTP
4xx, so you fix the request body and retry. Asynchronous risk evaluation accepts
the request with HTTP 201, then transitions the payout to status: failed.
Resubmit with a new idempotencyKey after correcting the underlying data.
| Code | Type | Cause | Resolution |
|---|
transaction_denied | Asynchronous | Travel Rule data is missing or invalid. The response carries riskEvaluation.decision: denied and riskEvaluation.reason: 3220. | Review source.identities, the recipient’s identity and ownership (CIRCLE_SG), the vaspId (CIRCLE_SG), and purposeOfTransfer (CIRCLE_SG). Resubmit with a new idempotencyKey. |
insufficient_funds | Asynchronous | The source wallet does not have enough balance for amount plus fees. | Fund the source wallet, then resubmit with a new idempotencyKey. |
5020 | Synchronous (HTTP 400) | purposeOfTransfer is missing or invalid on a CIRCLE_SG payout. | Provide a valid PMT code other than PMT006. |
2024 to 2037 | Synchronous (HTTP 400) | Address Book validation failures on CIRCLE_SG: missing identity, missing ownership, missing or disallowed vaspId, or PATCH attempted on identity or ownership. | Add the missing or corrected field on the initial create call. For 2036 and 2037 PATCH errors, register a new recipient instead. |
See Travel Rule compliance for
schema details and API errors for the
full error code reference.
See also