Payout Errors
Every error on the merchant API has the same body:
{ "code": "INSUFFICIENT_BALANCE", "message": "…", "requestId": "…" }code is the contract. message is prose for humans, may be reworded at any time, and must never be parsed. requestId identifies the request in our logs — quote it when reporting a 5xx.
Adding a code is not a breaking change. Changing or removing one is.
Shared auth and HTTP envelope: Errors.
Codes
| Status | code | Meaning / action |
|---|---|---|
| 400 | VALIDATION_FAILED | The body failed schema validation — e.g. both or neither of beneficiaryId / beneficiary. message lists the offending fields. |
| 400 | INVALID_REQUEST | Missing or malformed Idempotency-Key, an inline account that failed bank verification, or an amount that falls under the RM1 minimum once the fee is deducted. |
| 400 | INSUFFICIENT_BALANCE | Fund your prefund (dashboard top-up or bank transfer) before retrying. |
| 400 | UNKNOWN_BENEFICIARY | beneficiaryId doesn't match an active beneficiary on your account, or the inline bankCode isn't in your /v1/payouts/active-banks list. |
| 400 | LIMIT_EXCEEDED | You hit a configured daily or monthly payout limit. |
| 403 | LIMIT_EXCEEDED | You hit the cap on active beneficiaries (1,000 by default). Only a new destination trips this — repeat payouts to a destination you have already used reuse the existing record. Delete beneficiaries you no longer pay, or ask BLOX to raise the cap. |
| 401 | UNAUTHORIZED | Missing/unknown API key, missing signature headers, or a signature that failed or fell outside ±300s. Re-sign with a fresh created over the current body digest. |
| 403 | FEATURE_DISABLED | Payouts aren't enabled on the account. Contact BLOX. |
| 403 | ACCOUNT_FROZEN / ACCOUNT_SUSPENDED / ACCOUNT_PENDING_VERIFICATION | Your account's status blocks money out. Reads stay open. Contact BLOX. |
| 403 | ACCOUNT_TERMINATED | Every route is blocked, reads included. |
| 404 | NOT_FOUND | Unknown payoutId, or it belongs to another account. |
| 422 | VALIDATION_FAILED | The Idempotency-Key was already used with a different body. |
| 429 | RATE_LIMITED | Over 300 creates per minute. Back off and retry. |
| 503 | SERVICE_UNAVAILABLE | Payout creation is paused on our side. Nothing was created or debited — retry later, reusing the same Idempotency-Key. |
| 5xx | INTERNAL_ERROR | Something broke on our side. message is deliberately generic; quote requestId. |
Retry guidance
| Response | Retry with | Why |
|---|---|---|
401 | Don't retry | Fix your signing or API key first |
4xx | A new Idempotency-Key | A rejection replays as the same rejection for 24 hours |
429 | The same key | The request never ran |
500, 503, timeout | The same key | The key is what stops one create from becoming two transfers |