TIMESTAMP=$(date +%s)
NONCE=$(uuidgen)
BODY=''
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/${BATCH_ID}/submit" \
-H "Authorization: Bearer ${API_KEY}" \
-H "X-StablePay-Timestamp: ${TIMESTAMP}" \
-H "X-StablePay-Nonce: ${NONCE}" \
-H "X-StablePay-Signature: ${SIGNATURE}"
{
"code": 400,
"message": "batch total amount must be at least 3 USDC/USDT",
"errorCode": "batch_amount_too_low",
"data": null
}
{
"code": 401,
"message": "authenticated merchant is required",
"errorCode": "authentication_required",
"data": null
}
{
"code": 403,
"message": "access denied",
"errorCode": "forbidden",
"data": null
}
{
"code": 404,
"message": "batch not found",
"errorCode": "batch_not_found",
"data": null
}
{
"code": 409,
"message": "another operation is in progress, please try again later",
"errorCode": "concurrent_operation",
"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
Submit Payout Batch
Submit the current merchant’s payout batch for immediate execution.
POST
/
api
/
v1
/
payout-batches
/
{batch_id}
/
submit
TIMESTAMP=$(date +%s)
NONCE=$(uuidgen)
BODY=''
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/${BATCH_ID}/submit" \
-H "Authorization: Bearer ${API_KEY}" \
-H "X-StablePay-Timestamp: ${TIMESTAMP}" \
-H "X-StablePay-Nonce: ${NONCE}" \
-H "X-StablePay-Signature: ${SIGNATURE}"
{
"code": 400,
"message": "batch total amount must be at least 3 USDC/USDT",
"errorCode": "batch_amount_too_low",
"data": null
}
{
"code": 401,
"message": "authenticated merchant is required",
"errorCode": "authentication_required",
"data": null
}
{
"code": 403,
"message": "access denied",
"errorCode": "forbidden",
"data": null
}
{
"code": 404,
"message": "batch not found",
"errorCode": "batch_not_found",
"data": null
}
{
"code": 409,
"message": "another operation is in progress, please try again later",
"errorCode": "concurrent_operation",
"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
}
API submissions do not require manual approval in the Merchant Portal. A repeated request continues a batch awaiting execution or returns the current status of a batch that has already entered execution. After a timeout or connection interruption, query the batch status first.
Submit the specified batch for immediate execution without manual approval in the Merchant Portal. On retry, a batch in pending, pending_approval, processing, partially_completed, or completed status continues execution or returns its current status. If the request times out or the connection is interrupted, query the batch status first.
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.
Only the fields defined below are allowed.
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.
Path Parameters
string
required
Minimum length: 1. Maximum length: 64.
Success Response
HTTP200, application/json. The batch has entered execution, or had already entered execution.
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 | The request is invalid or the batch does not meet submission requirements. |
| 401 | Authentication failed or a trusted merchant identity is missing. |
| 403 | The current merchant is not authorized to access or operate on this resource. |
| 404 | The specified payout batch or item does not exist. |
| 409 | Another operation on the same resource is in progress. Try again later. |
| 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
- Create 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.TIMESTAMP=$(date +%s)
NONCE=$(uuidgen)
BODY=''
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/${BATCH_ID}/submit" \
-H "Authorization: Bearer ${API_KEY}" \
-H "X-StablePay-Timestamp: ${TIMESTAMP}" \
-H "X-StablePay-Nonce: ${NONCE}" \
-H "X-StablePay-Signature: ${SIGNATURE}"
{
"code": 400,
"message": "batch total amount must be at least 3 USDC/USDT",
"errorCode": "batch_amount_too_low",
"data": null
}
{
"code": 401,
"message": "authenticated merchant is required",
"errorCode": "authentication_required",
"data": null
}
{
"code": 403,
"message": "access denied",
"errorCode": "forbidden",
"data": null
}
{
"code": 404,
"message": "batch not found",
"errorCode": "batch_not_found",
"data": null
}
{
"code": 409,
"message": "another operation is in progress, please try again later",
"errorCode": "concurrent_operation",
"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?
