By EcoCash
Errors
Every error code the sandbox returns, what causes it and what to do about it.
Overview
All errors return a JSON body with responseCode and message. Match on responseCode, not on the message text.
Checks run in a fixed order and stop at the first failure: client credentials, then the channel API user, then the request body, then the channel code, then the customer number. A request with two faults returns only the first.
Error codes
| HTTP | Code | Cause | What to do |
|---|---|---|---|
| 401 | SBX40100 | Client Id or Client Secret is missing or does not match. | Check both headers are present and match your credentials page. |
| 401 | TP40101 | The username or the decrypted password does not match your API user. | Check the username, and check you encrypted against the right key. |
| 400 | SBX40000 | A missing field, an unrecognised serviceType, a malformed number, a non-positive amount or an unsupported currency. | Read the message. It names the offending field. |
| 400 | TP40288 | The channelCode does not belong to your API user. | Use the channel code for that service. |
| 400 | IC50103 | The customer number is not on your whitelist. | Add and verify it on the Test Numbers page. |
| 400 | 888803 | No transaction exists for the externalTransactionId supplied. | Check the reference. Failed transactions are not stored. |
HTTP status codes
| Code | Meaning |
|---|---|
| 200 | Request accepted. Check the status field for the outcome |
| 400 | Invalid request parameters or a business rule failure |
| 401 | Unauthorized. Check your client credentials and API user |
| 500 | Internal server error |
Error bodies
SBX40100
{
"status": 401,
"responseCode": "SBX40100",
"message": "Invalid or missing sandbox credentials."
}TP40101
{
"status": 401,
"responseCode": "TP40101",
"exception": "AuthenticationException",
"message": "Invalid channel user credentials.",
"timestamp": "2026-08-26T14:12:08.114Z"
}SBX40000
{
"status": 400,
"responseCode": "SBX40000",
"exception": "ValidationException",
"message": "Unsupported currency: EUR. Accepted values are USD and ZWG.",
"timestamp": "2026-08-26T14:12:08.114Z"
}The message is generated per failure and names the offending field wherever possible. “Missing required field: amount.” is the other pattern. Read the message rather than the code.
TP40288
{
"status": 400,
"responseCode": "TP40288",
"exception": "ProcessingException",
"message": "The specified number does not exist",
"timestamp": "2026-08-26T14:12:08.114Z"
}The message does not describe the condition. TP40288 is returned when the channelCode is invalid, not when a number does not exist. The wording is published exactly as the API returns it, because a developer matching on the body needs the real string. Match on responseCode.
IC50103
{
"status": 400,
"responseCode": "IC50103",
"exception": "ProcessingException",
"message": "Invalid receiver in transaction. Recipient has to be registered with CPS in order to receive funds. For more information call Customer Services on 114.",
"timestamp": "2026-08-26T14:12:08.114Z"
}888803
{
"serviceType": "EXTERNALTRANSACTIONLOOKUP",
"externalReference": "1786088200",
"status": "400",
"responseCode": "888803",
"timestamp": "2026-08-26T12:48:40.107Z",
"message": "No Transaction Found"
}This body returns status as a string and carries no exception field, unlike the five above. Parse it accordingly.