Response format
The envelope
Every response — success or failure, on every endpoint — is a JSON object with exactly three fields:
JSON
{ "code": "SUCCESS", "message": "Order created", "data": { "orderId": "acme-1042" } }
| Field | Meaning |
|---|---|
code | A string. SUCCESS when the call worked; otherwise one of the error codes. |
message | Human-readable English. Show it or log it. |
data | The payload on success. null on error. |
Branch on code, not on message or the status
code is the stable part of the contract. message is prose written for a human and may be
reworded at any time — never match on it. The HTTP status is a transport hint derived from code,
so it is coarser than the code is: several distinct failures share HTTP 400.
JavaScript
const {code, message, data} = await res.json();
switch (code) {
case 'SUCCESS':
return data;
case 'PARTNER_INSUFFICIENT_BALANCE':
return topUpFundAndRetry();
case 'DUPLICATE_TRANSACTION_ID':
return existingOrder(orderId); // already created — not an error for you
default:
throw new Error(`${code}: ${message}`);
}
HTTP status semantics
| Status | Meaning |
|---|---|
200 / 201 | Success — writes and submissions return 201. Treat any 2xx as success and read code. |
400 | The request was invalid, or a business rule rejected it. This is the default for business errors. |
401 | Missing or invalid identity. |
402 | Your fund balance is insufficient. |
403 | Your partner account is locked, or the caller IP is not allowlisted. |
404 | The requested resource — order, partner, KYC profile — was not found. |
409 | Duplicate orderId. |
500 | Unexpected server error, or an order was created but its payout failed. |
503 | The service is disabled, under maintenance, or temporarily unavailable. |
Amounts
- Fiat amounts are decimals in the currency's major unit — dollars, not cents; đồng, not hundredths of a đồng — each rounded to that currency's standard precision.
- Crypto amounts are decimals in the token's native precision.
Timestamps
- Order
createdAtandexpiresAtare ISO-8601 in UTC:2026-07-06T05:00:00.000Z. - The access token's
expiresAtis a number — a Unix timestamp in seconds. It is the one exception, and it catches people.