Pay out from a master wallet
Sends amount of an asset from the master wallet of network to destination. Requires the Idempotency-Key header. The payout starts pending; follow payout.broadcast, payout.confirmed and payout.failed. An API key needs the payouts:write scope, which no key has unless it was granted when the key was created, and must be restricted by an IP allowlist or a payout destination allowlist (set under API keys in the dashboard): with a destination allowlist it pays only those addresses; with an IP allowlist alone it pays any address that is valid on network, and only when called from those IP addresses. A key with neither pays nobody (payout_allowlist_required).
Authorization
Section titled “Authorization”Send your API key as a bearer token in the Authorization header. Secret API key: Authorization: Bearer ctp_live_sk_…. A publishable key (ctp_…_pk_…) is accepted by these operations only, which serve reference data: getRate, listAssets, listNetworks (each marked x-publishable-key: true). Every other operation refuses it with 403 publishable_key_not_allowed, whatever Origin the request carries: that header binds browsers, not other clients, and nothing on this API relies on it.
Headers
Section titled “Headers”| Name | Type | Description |
|---|---|---|
Idempotency-Key required |
string | Required: this operation moves money, and without the header it answers 400 idempotency_key_required. Use one key per payout or refund and send the same key again when you retry: the same key with the same request returns the payout or refund that exists and never pays twice; the same key with a different request is 422 idempotency_key_reused. For 24 hours the first response is replayed as it was (Idempotent-Replayed: true); while the first request is still running, 409 idempotency_request_in_progress with Retry-After. At most 255 characters. Pattern ^[!-~]+$. |
Request body
Section titled “Request body”| Field | Type | Description |
|---|---|---|
asset required |
string | Asset symbol, e.g. USDT. At most 16 characters. |
network required |
string | Network slug, e.g. bsc. At least 2 characters, at most 32 characters. |
amount required |
string | What the destination receives, in base units of the asset. A whole number written as a string of digits. |
destination required |
string | At most 128 characters. |
memo |
string | Your own note. It is not sent to the network. At most 200 characters. |
Example request
Section titled “Example request”curl -X POST "https://api.ctpeway.com/v1/payouts" \ -H "Authorization: Bearer $CTPEWAY_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: <a-unique-key>" \ -d '{ "asset": "USDT", "network": "tron", "amount": "250000000", "destination": "<destination-address>", "memo": "Supplier 7, October"}'import { CtpeWay } from '@ctpeway/sdk';
const ctpeway = new CtpeWay(process.env.CTPEWAY_API_KEY);
const result = await ctpeway.payouts.create({ asset: 'USDT', network: 'tron', amount: '250000000', destination: '<destination-address>', memo: 'Supplier 7, October',});Response
Section titled “Response”201 Created
Section titled “201 Created”| Field | Type | Description |
|---|---|---|
id |
string | |
status |
string | One of pending, processing, included, confirmed, failed. |
network |
string | |
asset |
string | |
asset_id |
string | |
contract optional |
string | |
decimals |
integer | |
amount |
string | What the destination receives, base units of asset. A whole number written as a string of digits. |
destination |
string | |
memo optional |
string | |
tx_hash optional |
string | |
refund_id optional |
string | Set when the payout pays a refund. |
failure_code optional |
string | Why a failed payout failed. Among them: canceled (canceled before it was signed), stale (not signed within two hours of being created, so given up instead of paid late), conflict (something else used the wallet’s nonce or coins first), expired (signed bytes the network never took), reverted (included, but its execution failed), chain:insufficient_funds, destination_not_payable, signer_refused:<reason>. In every case nothing was sent; failure_message says it in a sentence. |
requested_by |
object | |
requested_by. |
string | One of user, apiKey. |
requested_by. |
string | |
created_at |
string (date-time) | |
confirmed_at optional |
string (date-time) | |
failed_at optional |
string (date-time) | |
native_asset |
string | Symbol of the coin the network fee is paid in. |
native_decimals |
integer | |
max_network_fee optional |
string | The most the transaction may cost, base units of native_asset: what was set aside for its fee when the payout was created. A whole number written as a string of digits. |
network_fee optional |
string | What the transaction actually paid for its inclusion, base units of native_asset. Present once the transaction is in a block, on networks that report it; gone again if a reorganisation takes the transaction out of its block. A whole number written as a string of digits. |
livemode |
boolean | |
failure_message optional |
string | What failure_code means, in a sentence for a person. Absent for codes that need no explanation. |
{ "id": "string", "status": "pending", "network": "string", "asset": "string", "asset_id": "string", "contract": "string", "decimals": 0, "amount": "1000000", "destination": "string", "memo": "string", "tx_hash": "string", "refund_id": "string", "failure_code": "string", "requested_by": { "type": "user", "id": "string" }, "created_at": "2026-01-01T00:00:00.000Z", "confirmed_at": "2026-01-01T00:00:00.000Z", "failed_at": "2026-01-01T00:00:00.000Z", "native_asset": "string", "native_decimals": 0, "max_network_fee": "1000000", "network_fee": "1000000", "livemode": true, "failure_message": "string"}The values are placeholders generated from the schema. They show the shape, not real data.
Errors
Section titled “Errors”A failed request answers with the error format described under Errors.
Besides the codes any endpoint can return, this endpoint can answer with these code values:
asset_disabledasset_not_foundasset_not_on_networkidempotency_key_requiredidempotency_key_reusedmaster_wallet_missingmerchant_on_holdnetwork_disablednetwork_not_foundpayout_allowlist_requiredpayout_amount_below_dustpayout_amount_invalidpayout_balance_unavailablepayout_destination_invalidpayout_destination_not_allowlistedpayout_destination_not_payablepayout_destination_own_addresspayout_insufficient_balancepayout_not_authorizedpayouts_paused

