Error Handling
Understanding error codes and handling failures in Sendable API.
| Code | Meaning | Description |
|---|
200 | OK | Request succeeded |
400 | Bad Request | Invalid request parameters |
401 | Unauthorized | Invalid or missing API key |
403 | Forbidden | API key lacks permission |
404 | Not Found | Resource doesn't exist |
429 | Too Many Requests | Rate limit exceeded |
500 | Server Error | Internal server error |
All errors follow this structure:
{
"success": false,
"error": {
"code": "INVALID_PHONE_NUMBER",
"message": "The phone number format is invalid",
"details": {
"field": "to",
"value": "123456"
}
}
}
| Code | Description | Solution |
|---|
UNAUTHORIZED | API key is missing or invalid | Check your API key header |
KEY_REVOKED | API key has been revoked | Generate a new API key |
SESSION_EXPIRED | Session has expired | Reconnect your session |
| Code | Description | Solution |
|---|
INVALID_PHONE_NUMBER | Phone number format is invalid | Use international format (e.g., 6281234567890) |
MESSAGE_TOO_LONG | Text exceeds maximum length | Split into multiple messages |
MEDIA_DOWNLOAD_FAILED | Could not download media URL | Check URL is accessible |
SESSION_NOT_CONNECTED | WhatsApp session is not connected | Reconnect your session |
| Code | Description | Solution |
|---|
RATE_LIMITED | Too many requests | Implement exponential backoff |
QUOTA_EXCEEDED | Monthly quota exceeded | Upgrade your plan |
Implement exponential backoff for transient errors:
async function sendWithRetry(message: any, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await sendMessage(message)
} catch (error) {
if (error.status === 429 || error.status >= 500) {
const delay = Math.pow(2, i) * 1000 // 1s, 2s, 4s
await new Promise(r => setTimeout(r, delay))
continue
}
throw error
}
}
}