Crypto Payouts
Send USDT payouts to any crypto wallet.
Open the interactive version or read this guide as markdown.
Tags: Payouts, Balance, Webhooks
Paste this prompt into Claude, ChatGPT, or any AI tool. It works best with the CoinCircuit MCP server connected: https://mcp.coincircuit.io
You are helping me add crypto payouts to my existing application using CoinCircuit. I have the CoinCircuit MCP server connected.
If you have access to the CoinCircuit MCP server, call these tools for the most accurate and detailed schema outputs:
- Call
get_endpointwith methodpostand path/api/v1/recipientsfor the recipient creation schema. - Call
get_endpointwith methodpostand path/api/v1/payoutsfor the payout creation schema. - Call
get_schemawith namePayoutSuccessWebhookDtofor the payout.success webhook payload. - Call
get_schemawith namePayoutFailedWebhookDtofor the payout.failed webhook payload.
Use the live MCP data as your source of truth. The details below are a guide, but if the MCP returns something different, trust the MCP.
API Basics
- Base URL:
https://api.coincircuit.io - Auth:
x-api-keyheader on every request.
Project Context
I have an application that needs to pay users in crypto (USDT) from my CoinCircuit merchant balance to their wallet addresses. Use cases: vendor payments, creator payouts, rewards, or any disbursement to external wallets.
What I Need You to Implement
1. Save a payout recipient
Before you can send a payout, the recipient wallet address must be saved.
Endpoint: POST /api/v1/recipients
(Call get_endpoint with method post, path /api/v1/recipients in the CoinCircuit MCP for the full request/response schema.)
Required fields:
type(string) -"crypto_address"for a wallet, or"ngn_bank_account"for a bank accountdetails(object) - forcrypto_address:{ chain, address }.chainis one of"bsc","tron","solana","base", or"ethereum";addressis the wallet address.
Optional fields:
label(string) - friendly name, e.g. "Alice's BSC wallet"isDefault(boolean) - make this the default recipient for its type
Example request body:
{
"type": "crypto_address",
"label": "Alice's BSC wallet",
"details": { "chain": "bsc", "address": "0xRecipientAddress" }
}
Response (201): Returns the saved recipient with an id (UUID). You'll use this id as the recipientId when creating payouts. If a matching recipient already exists, the existing one is returned instead of a duplicate.
Errors: 400 if the details are invalid or the type is unsupported.
2. Create crypto payout
Endpoint: POST /api/v1/payouts
(Call get_endpoint with method post, path /api/v1/payouts, section request in the CoinCircuit MCP for the exact request body with all field validations.)
Required fields:
method(string) -"crypto"(or"fiat"for bank transfers)currency(string) -"USDT"or"NGN"amount(string) - amount to send as a string, e.g."100.00"recipientId(string, UUID) - the saved crypto address ID from step 1
Optional fields:
narration(string) - description, e.g. "Creator payout - March"reference(string) - your unique idempotency reference. Duplicate references are rejected. If omitted, CoinCircuit generates one.
Example request body:
{
"method": "crypto",
"currency": "USDT",
"amount": "100.00",
"recipientId": "addr_123456789_abcdef",
"narration": "Creator payout - March 2026",
"reference": "PAYOUT-MARCH-ALICE-001"
}
Response (201): Returns the payout object:
data.id- payout UUIDdata.status- starts as"pending", transitions to"processing","success", or"failed"data.amount- amount the recipient getsdata.fee- fee chargeddata.total- total debited from your balance (amount + fee)data.currency-"USDT"data.reference- your reference or auto-generateddata.txHash- blockchain transaction hash (populated after success)data.recipient- object withtype: "crypto_address"anddetails: { chain, address }data.conversion- if cross-currency, includesfrom,to,rate,convertedAmount. Null if same currency.data.failureReason- populated if failed
(Call get_endpoint with method post, path /api/v1/payouts, section success in the CoinCircuit MCP for the complete response schema.)
Errors: 400 (validation error, insufficient balance, daily limit exceeded), 404 (recipient address not found)
3. Track payout status via webhooks
Payouts are async. The API returns immediately with "pending" status. Wait for webhooks:
(Call get_schema with name PayoutSuccessWebhookDto in the CoinCircuit MCP for the full payout.success webhook payload. Call get_schema with name PayoutFailedWebhookDto for the failure payload.)
Payout events (envelope: { event: string, data: { payout: PayoutObject } }):
payout.created- payout submitted and processingpayout.success- funds delivered on-chain.data.payout.txHashhas the transaction hash,data.payout.completedAthas the timestamp.payout.failed- payout failed.data.payout.failureReasonexplains why. Funds are returned to your balance.
Constraints
amountis a string (e.g."100.00")- Duplicate
referencevalues are rejected. Use unique references for idempotency. - Crypto payouts support USDT (on Tron, BSC) and USDC (on Base).
- Payouts are async. Never assume success from the API response. Always wait for webhooks.
- Fiat payouts go only to the merchant's own bank account. Use crypto payouts for third-party disbursements.