Knowledge Base Help Center
API Error Codes and Troubleshooting Guide
Understanding API Errors
The Coext External API uses a consistent error format across all endpoints. Understanding these errors will help you build robust integrations that handle failures gracefully.
Standard Error Response Format
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable description of the error",
"details": {
// Additional context (varies by error type)
}
},
"meta": {
"request_id": "req_abc123def456ghi789"
}
}
Key Fields:
success: Alwaysfalsefor errorserror.code: Machine-readable error identifier (use this for programmatic handling)error.message: Human-readable descriptionerror.details: Additional context specific to the error typemeta.request_id: Unique ID for this request (helpful for support)
Authentication Errors (HTTP 401)
These errors occur when the API cannot verify your identity.
| Error Code | Description | Resolution |
|---|---|---|
INVALID_API_KEY | API key not found in the system or has invalid format |
|
EXPIRED_API_KEY | API key has passed its expiration date | Create a new API key or remove the expiration date from the existing key |
REVOKED_API_KEY | API key was manually revoked by an administrator | Create a new API key; revoked keys cannot be reactivated |
SUSPENDED_API_KEY | API key is temporarily suspended due to abuse or billing issues | Contact support to resolve the suspension |
IP_NOT_ALLOWED | Request originates from an IP address not in the whitelist | Add your server’s IP to the allowed list in key settings |
INVALID_SIGNATURE | HMAC signature verification failed (only when using enhanced auth) | Review signature generation algorithm; ensure JSON serialization matches |
TIMESTAMP_EXPIRED | Request timestamp is more than 5 minutes old or in the future | Sync your server clock with NTP; use fresh timestamps |
Example: INVALID_API_KEY Error
{
"success": false,
"error": {
"code": "INVALID_API_KEY",
"message": "The provided API key is invalid"
},
"meta": {
"request_id": "req_xyz789"
}
}
Permission Errors (HTTP 403)
These errors occur when your API key doesn’t have the required permissions.
| Error Code | Description | Resolution |
|---|---|---|
PERMISSION_DENIED | API key lacks the required permission for this operation | Edit the API key and enable the required permission |
ACCOUNT_NOT_ACTIVE | The linked WhatsApp Business Account is inactive | Reactivate the WhatsApp account in the dashboard |
Required Permissions by Endpoint
| Endpoint | Required Permission |
|---|---|
POST /messages/text | send_text |
POST /messages/template | send_template |
POST /messages/template/send | send_template |
POST /messages/media | send_media |
GET /templates | view_templates |
GET /messages/:uuid | view_messages |
Rate Limiting Errors (HTTP 429)
These errors occur when you exceed your API usage limits.
| Error Code | Description | Resolution |
|---|---|---|
RATE_LIMIT_EXCEEDED | Too many requests in the current minute | Wait for retry_after seconds, then retry with backoff |
DAILY_LIMIT_EXCEEDED | Daily request quota has been reached | Wait until the next day or request a limit increase |
Rate Limit Error Response
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Please wait before making more requests.",
"details": {
"retry_after": 45
}
},
"meta": {
"request_id": "req_rate123",
"rate_limit": {
"limit": 60,
"remaining": 0,
"reset_at": "2025-12-19T10:01:00.000Z"
}
}
}
Implementing Rate Limit Handling
async function sendWithRateLimitHandling(payload) {
const response = await fetch(url, options);
if (response.status === 429) {
const data = await response.json();
const retryAfter = data.error?.details?.retry_after || 60;
console.log(`Rate limited. Waiting ${retryAfter} seconds...`);
await sleep(retryAfter * 1000);
// Retry the request
return sendWithRateLimitHandling(payload);
}
return response;
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
Validation Errors (HTTP 400)
These errors occur when your request data is invalid or incomplete.
| Error Code | Description | Resolution |
|---|---|---|
VALIDATION_ERROR | Request body validation failed on one or more fields | Check error.details.fields for specific issues |
INVALID_PHONE_NUMBER | Phone number is not in valid E.164 format | Use format: +[country code][number] (e.g., +919876543210) |
TEMPLATE_NOT_FOUND | Template name doesn’t exist or isn’t approved | Verify template name and approval status |
TEMPLATE_NOT_CONFIGURED | Template variable mapping not set up for this API key | Configure template in the dashboard Templates tab |
INVALID_TEMPLATE_PARAMS | Template parameters don’t match expected format | Check parameter count, types, and positions |
MISSING_REQUIRED_VARIABLE | A required template variable was not provided | Include all required variables in request |
Validation Error with Field Details
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": {
"fields": {
"to": "Phone number must be in E.164 format (e.g., +919876543210)",
"message": "Message is required and cannot be empty"
}
}
},
"meta": {
"request_id": "req_val456"
}
}
Message Delivery Errors (HTTP 400/500)
These errors occur during message sending or delivery.
| Error Code | Description | Resolution |
|---|---|---|
MESSAGE_SEND_FAILED | Failed to send message via WhatsApp | Check details.whatsapp_error_code for specifics |
MESSAGE_NOT_FOUND | Requested message ID doesn’t exist | Verify the message UUID is correct |
WhatsApp-Specific Error Codes
When messages fail through WhatsApp, you’ll receive specific error codes from Meta:
| WA Code | Description | Resolution |
|---|---|---|
131047 | Re-engagement message required | Customer hasn’t messaged in 24 hours; use a template message instead |
130472 | 24-hour customer service window has closed | Use an approved template message to re-initiate conversation |
131051 | Unsupported message type | Check message format is supported by WhatsApp |
131052 | Media URL is expired or invalid | Provide a fresh, publicly accessible media URL |
368 | Temporarily blocked for policy violation | Review Meta Business messaging policies |
80007 | Rate limit hit on WhatsApp side | Slow down message sending; implement backoff |
131026 | Recipient number not on WhatsApp | Verify recipient has WhatsApp installed |
WhatsApp Error Response Example
{
"success": false,
"error": {
"code": "MESSAGE_SEND_FAILED",
"message": "Failed to send message",
"details": {
"whatsapp_error_code": 131047,
"whatsapp_error_message": "Re-engagement message required. Outside 24-hour customer service window."
}
},
"meta": {
"request_id": "req_wa789"
}
}
Server Errors (HTTP 500/503)
| Error Code | Description | Resolution |
|---|---|---|
INTERNAL_ERROR | Unexpected server error occurred | Retry with exponential backoff; contact support if persistent |
SERVICE_UNAVAILABLE | Service is temporarily unavailable | Retry after a few minutes |
Implementing Robust Error Handling
Comprehensive Retry Logic
async function sendMessageWithRetry(payload, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await sendMessage(payload);
if (response.success) {
return response;
}
const errorCode = response.error?.code;
// Don't retry client errors (except rate limits)
if (!shouldRetry(errorCode)) {
throw new ApiError(errorCode, response.error?.message);
}
// Handle rate limits specially
if (errorCode === 'RATE_LIMIT_EXCEEDED') {
const retryAfter = response.error?.details?.retry_after || 60;
await sleep(retryAfter * 1000);
continue;
}
// Exponential backoff for other retryable errors
const delay = Math.pow(2, attempt) * 1000;
console.log(`Retry attempt ${attempt} after ${delay}ms`);
await sleep(delay);
} catch (error) {
if (attempt === maxRetries) {
throw error;
}
}
}
throw new Error('Max retries exceeded');
}
function shouldRetry(errorCode) {
const retryableCodes = [
'RATE_LIMIT_EXCEEDED',
'INTERNAL_ERROR',
'SERVICE_UNAVAILABLE'
];
return retryableCodes.includes(errorCode);
}
Error Code Switch Handler
function handleApiError(error) {
const code = error.code;
const details = error.details;
switch (code) {
case 'INVALID_API_KEY':
case 'EXPIRED_API_KEY':
case 'REVOKED_API_KEY':
console.error('Authentication failed - check your API credentials');
// Alert operations team
break;
case 'PERMISSION_DENIED':
console.error('Missing permission - update API key settings');
break;
case 'RATE_LIMIT_EXCEEDED':
console.warn(`Rate limited. Retry after ${details?.retry_after}s`);
// Queue for delayed retry
break;
case 'INVALID_PHONE_NUMBER':
console.error('Bad phone number format');
// Mark contact as invalid
break;
case 'MESSAGE_SEND_FAILED':
const waCode = details?.whatsapp_error_code;
if (waCode === 131047 || waCode === 130472) {
console.log('24-hour window closed - need template message');
// Switch to template sending
}
break;
default:
console.error(`Unhandled error: ${code}`);
}
}
HTTP Status Code Quick Reference
| Status | Meaning | Should Retry? | Action |
|---|---|---|---|
| 200 | Success | N/A | Process response data |
| 400 | Bad Request | No | Fix request data |
| 401 | Unauthorized | No | Fix authentication |
| 403 | Forbidden | No | Update permissions |
| 404 | Not Found | No | Verify resource exists |
| 429 | Rate Limited | Yes | Wait and retry with backoff |
| 500 | Server Error | Yes | Retry with exponential backoff |
| 503 | Unavailable | Yes | Retry after delay |
Getting Help
If you encounter persistent errors that you can’t resolve:
- Note the request_id from the error response
- Check the Webhook Logs in the dashboard for delivery issues
- Review API Key permissions and status
- Verify template configuration if using templates
- Contact support with the request_id and error details

