Create payout
POST/v1/payouts
Sends USDT or USDC from your balance to a player's wallet. Use a unique request_id so retries are always safe.
Request body
| Field | Type | Description |
|---|---|---|
request_id | string · required | Your unique id for this payout (idempotency key). 1–128 characters from A–Z a–z 0–9 _ . : -. |
chain | string · required | Chain id, for example tron or bsc. |
token | string · required | USDT or USDC, as enabled for your account. |
to | string · required | Destination wallet address. EVM addresses must have a valid checksum if mixed-case. |
amount | string · required | Integer in the token's smallest unit, greater than 0. |
player_ref | string · optional | Your id for the player, echoed back in responses and webhooks. |
Example
const { status, body } = await icn("POST", "/v1/payouts", { request_id: "wd-1001", chain: "tron", token: "USDT", to: "TXyZ4k...9kP", amount: "50000000", // 50 USDT (6 decimals) player_ref: "player_1024", });
status, body = icn("POST", "/v1/payouts", { "request_id": "wd-1001", "chain": "tron", "token": "USDT", "to": "TXyZ4k...9kP", "amount": "50000000", # 50 USDT (6 decimals) "player_ref": "player_1024", })
201 Created
{
"id": "0b8e6d2a-5f3c-4b7e-8d1a-2c9f4e6a7b30",
"request_id": "wd-1001",
"status": "queued",
"asset": "tron:USDT",
"chain": "tron",
"to": "TXyZ4k...9kP",
"amount": "50000000",
"fee": "2000000",
"fee_mode": "on_top",
"send_amount": "50000000",
"total": "52000000",
"player_ref": "player_1024",
"tx_hash": null,
"reason": null,
"created_at": "2026-10-10T08:05:00.000Z",
"completed_at": null
}Fees
fee_mode is set per account. With on_top (default), the player receives the full amount and your balance is charged total = amount + fee. With deducted, the fee comes out of the amount: the player receives send_amount = amount − fee and total = amount.
Idempotency
- First request with a new
request_id:201 Created. - Same
request_idwith the same parameters:200 OKwith the existing payout. Nothing is sent twice. - Same
request_idwith different parameters:409 request_id_conflict.
If a request times out, retry it with the same
request_id (and a fresh signature). You will either create the payout or get back the one that already exists.Status
| status | Meaning |
|---|---|
pending_approval | Above your approval threshold; waiting for manual approval. |
queued | Accepted and waiting to be sent. Also used while your vault is short of funds: it is sent as soon as they arrive. |
broadcast | Sent to the network, waiting for finality. |
completed | Confirmed on-chain. tx_hash is set. Final. |
failed | Could not be sent, for example it would exceed your vault's on-chain limits. reason explains why; the reserved amount is released. Final. |
rejected | Rejected during approval. reason explains why. Final. |
Status changes are sent as payout.* webhooks. Checks run in this order and return an error without creating a payout: paused, asset enabled, vault configured, minimum, per-transaction limit, daily limit, balance.
Get payout
GET/v1/payouts/{id}
GET/v1/payouts?request_id={request_id}
Returns the payout object above. Look up by our id or by your request_id. Unknown ids return 404 not_found.
const { body } = await icn("GET", "/v1/payouts?request_id=wd-1001"); console.log(body.status, body.tx_hash);
status, body = icn("GET", "/v1/payouts?request_id=wd-1001") print(body["status"], body["tx_hash"])