All eCommunicate API errors follow a consistent JSON format with standard HTTP status codes. This guide covers the error response structure, common error scenarios, and delivery failure codes.
Every error response contains four fields:
{
"status": "ERROR",
"message": "Description of what went wrong",
"requestId": "c3a1f8e2-4b6d-11ee-be56-0242ac120002",
"timestamp": "2026-01-15T10:30:00Z"
}| Field | Type | Description |
|---|---|---|
status | string | Always "ERROR" for failed requests |
message | string | Human-readable error description |
requestId | string | Unique UUID for the request — always include this when contacting support |
timestamp | string | ISO 8601 timestamp of when the error occurred |
The requestId is your most valuable debugging tool. It allows the eCommunicate support team to trace your exact request through the system. Always log it and include it in support tickets.
| Code | Status | Description | Action |
|---|---|---|---|
200 | OK | Request succeeded | Process the response |
202 | Accepted | Message queued for delivery | Track delivery via webhooks or reports |
400 | Bad Request | Malformed request or missing required fields | Validate your request payload |
401 | Unauthorized | Missing or invalid API key | Check the Authorization header |
403 | Forbidden | Valid key but insufficient permissions | Contact support about account permissions |
404 | Not Found | Endpoint or resource does not exist | Verify the URL and resource ID |
429 | Too Many Requests | Rate limit exceeded | Implement exponential backoff — see Rate Limits |
500 | Internal Server Error | Server-side error | Retry with exponential backoff; contact support if persistent |
The most common error. Check these causes:
- Missing required fields (
sender,messages,templateNamefor notifications) - Invalid
messageTypevalue — must beNOTIFICATION,CHAT, orCONVERSATION - Template body has
{{n}}placeholders but nobodycomponent provided - Invalid phone number format when addressing by phone — international format, leading
+optional, no leading0(e.g.+27...or27...) channelfield not set toWHATSAPPorSMSon the unified endpointtemplateIddoes not match an existing approved template- Empty
recipientsarray, or a recipient with neithertonorcustomerUserId— supply at least one
customerUserId is validated against the ^[A-Z]{2}.[0-9]+$ format. A malformed BSUID is silently ignored, so a recipient sent with only a bad customerUserId (and no to) fails as though it had no recipient at all — the error won't mention the BSUID. Double-check the BSUID format before sending phone-less recipients.
| Cause | Fix |
|---|---|
| API key missing from header | Add Authorization: YOUR_API_KEY to every request |
| API key was regenerated | Use the new key — old keys are permanently invalidated |
| API key is malformed | Verify the key is a valid UUID |
| Cause | Fix |
|---|---|
| Insufficient permissions | Contact support to verify your account role and permissions |
| Wrong client context | You may be attempting to access resources belonging to a different client |
| Cause | Fix |
|---|---|
| Incorrect endpoint URL | Double-check the path against the API Reference |
| Invalid resource ID | Verify the template, webhook, conversation, or ticket ID exists |
When a message is accepted (202) but fails to deliver, the failure is reported via webhooks (in the statusUpdateURL payload) or the Message Reports API.
| Code | Meaning | Recommended action |
|---|---|---|
4 | Invalid number | Verify the phone number format and that it's a real number |
22 | Blacklisted number | The recipient has been blacklisted — check your blacklist settings |
23 | Blocked number | The recipient has blocked your number |
54 | Non-WhatsApp number | Recipient is not on WhatsApp — enable SMS fallback. SMS fallback needs a phone number, so it isn't available for a recipient addressed by customerUserId (BSUID) alone |
56 | Failed | Generic delivery failure — check the failureReason field for details |
58 | Duplicate message | This message was already sent — check your deduplication logic |
59 | Sender not connected | WhatsApp Lite sender is disconnected — reconnect via QR code |
60 | WhatsApp Lite server unavailable | The Lite server is temporarily down — retry later |
130429 | Rate limit hit | You're sending too fast — implement throttling and backoff |
131026 | Message undeliverable | Meta could not deliver the message — verify the recipient and template |
131047 | Re-engagement required | 24-hour session expired — send a template message to re-engage |
131053 | Media upload failed | The media URL is unreachable or the file is too large |
132000 | Template paused | Your template has been paused due to quality issues |
132001 | Template disabled | Your template has been permanently disabled |
Use this decision tree when a message fails:
Check the HTTP status code
4xx→ Fix the request (see scenarios above)5xx→ Retry with exponential backoff202→ Message was accepted; check delivery status below
Check delivery status via webhook or Message Reports API
DELIVERED/READ→ SuccessFAILED→ CheckfailureCodeandfailureReason
Check the failure code
- Codes
4,54→ Phone number issue - Codes
22,23→ Recipient blocked/blacklisted - Codes
59,60→ WhatsApp Lite connection issue - Codes
130xxx→ Meta Cloud API issue - Codes
132xxx→ Template issue
- Codes
If still stuck → Contact support@ecommunicate.co.za with the
requestId
For transient errors (429, 500, 502, 503), implement exponential backoff:
async function sendWithRetry(payload, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
const response = await sendMessage(payload);
if (response.status === 429 || response.status >= 500) {
throw new Error(`HTTP ${response.status}`);
}
return response;
} catch (error) {
if (attempt === maxRetries) throw error;
const delay = Math.min(1000 * Math.pow(2, attempt), 30000);
console.log(`Retry ${attempt + 1} in ${delay}ms: ${error.message}`);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}Client errors (400, 401, 403, 404) indicate a problem with your request. Retrying will produce the same result. Fix the request first.