TIMESTAMP=$(date +%s)
NONCE=$(uuidgen)
BODY='{"currency":"USDT","description":"October contractor payouts","items":[{"real_name":"Example Recipient","network":"trc20","address":"TExampleAddressReplaceBeforeUse","amount":"125.00"}]}'
IDEMPOTENCY_KEY='payout-create-example-001'
SIGNATURE=$(printf '%s' "${TIMESTAMP}.${NONCE}.${BODY}" | openssl dgst -sha256 -hmac "${SECRET_KEY}" | awk '{print $NF}')
curl --request POST "https://api.stablepay.co/api/v1/payout-batches" \
-H "Authorization: Bearer ${API_KEY}" \
-H "X-StablePay-Timestamp: ${TIMESTAMP}" \
-H "X-StablePay-Nonce: ${NONCE}" \
-H "X-StablePay-Signature: ${SIGNATURE}" \
-H "Idempotency-Key: ${IDEMPOTENCY_KEY}" \
-H "Content-Type: application/json" \
--data-raw "${BODY}"
{
"code": 400,
"message": "Idempotency-Key header is required",
"errorCode": "invalid_request",
"data": null
}
{
"code": 401,
"message": "authenticated merchant is required",
"errorCode": "authentication_required",
"data": null
}
{
"code": 403,
"message": "access denied",
"errorCode": "forbidden",
"data": null
}
{
"code": 500,
"message": "payout request failed",
"errorCode": "payout_error",
"data": null
}
{
"code": 503,
"message": "payout service is temporarily unavailable",
"errorCode": "service_unavailable",
"data": null
}
Payouts API
Create Payout Batch
Create a payout batch containing 1 to 200 items.
POST
/
api
/
v1
/
payout-batches
TIMESTAMP=$(date +%s)
NONCE=$(uuidgen)
BODY='{"currency":"USDT","description":"October contractor payouts","items":[{"real_name":"Example Recipient","network":"trc20","address":"TExampleAddressReplaceBeforeUse","amount":"125.00"}]}'
IDEMPOTENCY_KEY='payout-create-example-001'
SIGNATURE=$(printf '%s' "${TIMESTAMP}.${NONCE}.${BODY}" | openssl dgst -sha256 -hmac "${SECRET_KEY}" | awk '{print $NF}')
curl --request POST "https://api.stablepay.co/api/v1/payout-batches" \
-H "Authorization: Bearer ${API_KEY}" \
-H "X-StablePay-Timestamp: ${TIMESTAMP}" \
-H "X-StablePay-Nonce: ${NONCE}" \
-H "X-StablePay-Signature: ${SIGNATURE}" \
-H "Idempotency-Key: ${IDEMPOTENCY_KEY}" \
-H "Content-Type: application/json" \
--data-raw "${BODY}"
{
"code": 400,
"message": "Idempotency-Key header is required",
"errorCode": "invalid_request",
"data": null
}
{
"code": 401,
"message": "authenticated merchant is required",
"errorCode": "authentication_required",
"data": null
}
{
"code": 403,
"message": "access denied",
"errorCode": "forbidden",
"data": null
}
{
"code": 500,
"message": "payout request failed",
"errorCode": "payout_error",
"data": null
}
{
"code": 503,
"message": "payout service is temporarily unavailable",
"errorCode": "service_unavailable",
"data": null
}
The request must include
Only the fields defined below are allowed.
Idempotency-Key. Reusing the same key for the same merchant returns the previously created batch. Ensure the same key is associated with the same request content.
Create a payout batch in draft status. Reusing the same Idempotency-Key for the same merchant returns the previously created batch.
Merchant identity is determined by authentication through stablepay-auth. Do not include merchant_id in request parameters. Batch statuses and business rules are determined by the StablePay Payout service.
Authentication and Headers
Authenticate with a Bearer API Key and the three signing headers below. Compute HMAC-SHA256 over{timestamp}.{nonce}.{requestBody} with the API Secret, then encode the result as lowercase hex. Sign the exact request body bytes; use an empty string when no body is sent. See Authentication and Signing.
string
required
Bearer API Key:
Bearer sk_live_xxx.string
required
Unix timestamp in seconds, within 5 minutes of the server time.
string
required
Random string for replay protection. Use a new nonce for each request. Minimum length: 16. Maximum length: 64.
string
required
Request signature encoded as lowercase hexadecimal.
string
required
Idempotency key for batch creation, scoped to the merchant. Maximum length: 128 characters. Minimum length: 1. Maximum length: 128.
Request Body
application/json (required).
Only the fields defined below are allowed.
string
required
Allowed values:
USDT, USDC.string
object[]
required
Minimum items: 1. Maximum items: 200.
Show Fields
Show Fields
Only the fields defined below are allowed.
string
string
required
Allowed values:
erc20, trc20, spl.string
required
Minimum length: 1. Maximum length: 256.
string
Maximum length: 128.
string
required
Decimal amount greater than zero, represented as a string with at most two decimal places. Pattern:
^(?:0\.(?:0[1-9]|[1-9][0-9]?)|[1-9][0-9]*(?:\.[0-9]{1,2})?)$.Success Response
HTTP200, application/json. Created successfully.
Only the fields defined below are allowed.
string
required
string
required
Allowed values:
draft, needs_fix, pending, pending_approval, processing, partially_completed, completed, failed, canceled, rejected.string
required
Allowed values:
USDT, USDC.string
required
Allowed values:
erc20, trc20, spl.integer
required
Minimum: 0.
integer
required
Minimum: 0.
integer
required
Minimum: 0.
integer
required
Minimum: 0.
integer
required
Minimum: 0.
string
required
Nonnegative decimal amount represented as a string, with at most two decimal places. Pattern:
^(0|[1-9][0-9]*)(\.[0-9]{1,2})?$.string
required
Nonnegative decimal amount represented as a string, with at most two decimal places. Pattern:
^(0|[1-9][0-9]*)(\.[0-9]{1,2})?$.string
required
Nonnegative decimal amount represented as a string, with at most two decimal places. Pattern:
^(0|[1-9][0-9]*)(\.[0-9]{1,2})?$.string
required
Nonnegative decimal amount represented as a string, with at most two decimal places. Pattern:
^(0|[1-9][0-9]*)(\.[0-9]{1,2})?$.string
required
Nonnegative decimal amount represented as a string, with at most two decimal places. Pattern:
^(0|[1-9][0-9]*)(\.[0-9]{1,2})?$.boolean
Whether the batch can currently be submitted. This field is omitted when status is canceled.
object[]
required
string | null
integer
required
Format:
int64.integer | null
Format:
int64.integer | null
Format:
int64.Response Headers
| Header | Description |
|---|---|
X-Request-ID | Request tracing ID. |
Cache-Control | The response must not be cached. Allowed values: no-store. |
Error Responses
| HTTP | Description |
|---|---|
| 400 | Invalid HTTP request format or parameters, or the payout request failed business validation. Possible business error codes include address_risk_rejected, batch_amount_limit_exceeded, batch_amount_too_low, batch_cannot_submit, batch_empty_items, custody_balance_insufficient, insufficient_balance, and quota_blocked. |
| 401 | Authentication failed or a trusted merchant identity is missing. |
| 403 | The current merchant is not authorized to access or operate on this resource. |
| 500 | A payout business error that is not currently classified more specifically. |
| 503 | The payout service timed out or is temporarily unavailable. If this occurs during a write request, query the resource status before retrying. |
integer
required
string
required
string
required
null
required
Related Endpoints
- Submit Payout Batch
- Cancel Payout Batch
- Get Payout Batch
- List Payout Batches
- List Batch Items
- Get Payout Item
Set
API_KEY and SECRET_KEY before running this example. Set BATCH_ID or ITEM_ID when required by the endpoint.Replace the example recipient address before use. Reuse the same idempotency key and request content when retrying the same creation request.
TIMESTAMP=$(date +%s)
NONCE=$(uuidgen)
BODY='{"currency":"USDT","description":"October contractor payouts","items":[{"real_name":"Example Recipient","network":"trc20","address":"TExampleAddressReplaceBeforeUse","amount":"125.00"}]}'
IDEMPOTENCY_KEY='payout-create-example-001'
SIGNATURE=$(printf '%s' "${TIMESTAMP}.${NONCE}.${BODY}" | openssl dgst -sha256 -hmac "${SECRET_KEY}" | awk '{print $NF}')
curl --request POST "https://api.stablepay.co/api/v1/payout-batches" \
-H "Authorization: Bearer ${API_KEY}" \
-H "X-StablePay-Timestamp: ${TIMESTAMP}" \
-H "X-StablePay-Nonce: ${NONCE}" \
-H "X-StablePay-Signature: ${SIGNATURE}" \
-H "Idempotency-Key: ${IDEMPOTENCY_KEY}" \
-H "Content-Type: application/json" \
--data-raw "${BODY}"
{
"code": 400,
"message": "Idempotency-Key header is required",
"errorCode": "invalid_request",
"data": null
}
{
"code": 401,
"message": "authenticated merchant is required",
"errorCode": "authentication_required",
"data": null
}
{
"code": 403,
"message": "access denied",
"errorCode": "forbidden",
"data": null
}
{
"code": 500,
"message": "payout request failed",
"errorCode": "payout_error",
"data": null
}
{
"code": 503,
"message": "payout service is temporarily unavailable",
"errorCode": "service_unavailable",
"data": null
}
Last modified on October 19, 2026
Was this page helpful?
