TIMESTAMP=$(date +%s)
NONCE=$(uuidgen)
SIGNATURE=$(printf '%s' "${TIMESTAMP}.${NONCE}." | openssl dgst -sha256 -hmac "${SECRET_KEY}" | awk '{print $NF}')
curl --get 'https://api.stablepay.co/api/v1/bills/1234567890/download_url' \
-H "Authorization: Bearer ${API_KEY}" \
-H "X-StablePay-Timestamp: ${TIMESTAMP}" \
-H "X-StablePay-Nonce: ${NONCE}" \
-H "X-StablePay-Signature: ${SIGNATURE}"
{
"bill_id": "1234567890",
"filename": "payment-2026-09-01.csv",
"content_type": "text/csv",
"download_url": "https://example.com/bills/payment-2026-09-01.csv?signature=example",
"expires_in": 600
}
{
"error": {
"code": "invalid_parameter",
"message": "Invalid request parameters"
},
"request_id": "req_example",
"timestamp": 1790812800
}
{
"status": "error",
"error": "Authentication failed"
}
Bills API
Get Bill Download URL
Issue a temporary download URL for one existing bill file belonging to the current merchant.
GET
/
api
/
v1
/
bills
/
{bill_id}
/
download_url
TIMESTAMP=$(date +%s)
NONCE=$(uuidgen)
SIGNATURE=$(printf '%s' "${TIMESTAMP}.${NONCE}." | openssl dgst -sha256 -hmac "${SECRET_KEY}" | awk '{print $NF}')
curl --get 'https://api.stablepay.co/api/v1/bills/1234567890/download_url' \
-H "Authorization: Bearer ${API_KEY}" \
-H "X-StablePay-Timestamp: ${TIMESTAMP}" \
-H "X-StablePay-Nonce: ${NONCE}" \
-H "X-StablePay-Signature: ${SIGNATURE}"
{
"bill_id": "1234567890",
"filename": "payment-2026-09-01.csv",
"content_type": "text/csv",
"download_url": "https://example.com/bills/payment-2026-09-01.csv?signature=example",
"expires_in": 600
}
{
"error": {
"code": "invalid_parameter",
"message": "Invalid request parameters"
},
"request_id": "req_example",
"timestamp": 1790812800
}
{
"status": "error",
"error": "Authentication failed"
}
Verify that the bill belongs to the current merchant, then issue a temporary download URL for its existing file. The URL is valid for 600 seconds. Download the file directly from OSS using the returned URL.
Use the string
The download URL is valid for 600 seconds. This endpoint only issues URLs for existing files; it does not generate, merge, or recalculate bills.
Authentication and Headers
Authenticate with a Bearer API Key and include the signing headers below. GET requests use an emptyrequestBody, so the signature payload is {timestamp}.{nonce}.. Compute HMAC-SHA256 with the merchant API Secret and encode the result as lowercase hex. See Authentication and Signing.
string
required
Bearer API Key in the format
Bearer sk_live_xxx.string
required
Unix timestamp in seconds. It must be within 5 minutes of the server time.
string
required
Random string for replay protection, 16–64 characters long. Use a new UUID for each request. Minimum length: 16 characters. Maximum length: 64 characters.
string
required
HMAC-SHA256 of
{timestamp}.{nonce}.{requestBody} using the merchant API Secret, encoded as lowercase hex. For GET requests, requestBody is an empty string.Path Parameters
string
required
Bill ID. Use the string value returned by the List Bills endpoint. Pattern:
^[1-9][0-9]*$.Success Response
HTTP200, application/json. Download URL issued successfully.
string
required
Bill ID.
string
required
Download filename.
string
required
Media type of the file, such as
text/csv.string
required
Temporary signed OSS download URL. This URL contains access credentials; do not publish it or store it for long periods. Format:
uri.integer
required
Remaining validity of the download URL, in seconds. Value:
600.Error Responses
| HTTP Status | Description |
|---|---|
| 400 | Invalid bill ID or request parameters. |
| 401 | Authentication failed. |
| 404 | The bill does not exist, belongs to another merchant, or its file does not exist. |
| 410 | The historical bill file does not meet the current merchant isolation rules and cannot be downloaded. |
| 422 | The bill record exists, but its file is not yet available. |
| 503 | BillProd, OSS, or another dependent service is temporarily unavailable. |
Service Error Structure
object
required
string
required
Request ID.
integer
required
Time of the error, as a Unix timestamp in seconds. Format:
int64.Gateway Authentication Error Structure
Before a request reaches PaymentProd, the API gateway may return an HTTP401 response with the following structure.
string
required
Value:
error.string
required
Reason for the authentication failure.
bill_id returned by List Bills. The download URL contains access credentials; do not publish it or store it for long periods.
TIMESTAMP=$(date +%s)
NONCE=$(uuidgen)
SIGNATURE=$(printf '%s' "${TIMESTAMP}.${NONCE}." | openssl dgst -sha256 -hmac "${SECRET_KEY}" | awk '{print $NF}')
curl --get 'https://api.stablepay.co/api/v1/bills/1234567890/download_url' \
-H "Authorization: Bearer ${API_KEY}" \
-H "X-StablePay-Timestamp: ${TIMESTAMP}" \
-H "X-StablePay-Nonce: ${NONCE}" \
-H "X-StablePay-Signature: ${SIGNATURE}"
{
"bill_id": "1234567890",
"filename": "payment-2026-09-01.csv",
"content_type": "text/csv",
"download_url": "https://example.com/bills/payment-2026-09-01.csv?signature=example",
"expires_in": 600
}
{
"error": {
"code": "invalid_parameter",
"message": "Invalid request parameters"
},
"request_id": "req_example",
"timestamp": 1790812800
}
{
"status": "error",
"error": "Authentication failed"
}
Last modified on October 19, 2026
Was this page helpful?
