Errors and limits
HTTP codes
| Code | Name | What to do |
|---|---|---|
| 200 201 | Success | — |
| 400 | Bad request | Fix the parameters based on the error message. Don’t retry as is. |
| 401 | Unauthenticated | Key missing, mistyped or regenerated. Check the x-api-key header. |
| 402 | Plan / subscription limit | See the codes below. Upgrade or wait for next month. |
| 403 | Action not possible | Number not connected, access revoked. Read the message. |
| 404 | Not found | deviceId, contact or webhook doesn’t exist (or belongs to another account). |
| 429 | Too many requests | Slow down; retry after the delay given by the RateLimit-Reset / Retry-After header. |
| 500 | Server / WhatsApp error | Retry later with an increasing delay. |
| 501 | Not available | Endpoint reserved for a future version (audience lists, campaigns). |
| 502 | Refused by WhatsApp | The recipient doesn’t have WhatsApp or blocked your number. Don’t retry in a loop. |
Error messages (error field) are in French: rely on the HTTP code and the code field in your logic.
Business error codes
Some 402 errors include a code field to test in your code:
| Code | Meaning |
|---|---|
PLAN_LIMIT | Plan limit reached. The feature field says which one (crm, workflows…). |
API_ACCOUNT_SUSPENDED | Subscription expired or suspended: API access is blocked. |
ACCOUNT_SUSPENDED (in error) | Same cause, returned by some send operations. |
{
"error": "Limite de 2000 contacts atteinte pour votre forfait.",
"code": "PLAN_LIMIT",
"feature": "crm"
}
Rate limits
| Scope | Limit |
|---|---|
Sending messages (/whatsapp/messages/send, /whatsapp/send) | 200 requests / minute |
Incoming webhooks (/webhook/…) | 120 requests / minute |
| All other API routes | 1,000 requests / 15 minutes |
Limits are counted per IP address. Every response includes the standard RateLimit header (remaining requests and reset delay).
200 messages per minute is an API safety ceiling, not a recommended pace. WhatsApp may block a number that sends too fast to people who don’t expect it. For transactional messages (confirmation, reminder), no problem. For marketing, space your sends widely or use campaigns.
Plan quotas
Messages sent through the API count toward the monthly message quota; contacts created count toward the contact limit. Track your usage on the dashboard. You’re notified by email and WhatsApp at 80% and 100%.
Retry smartly
async function sendWithRetry(body, tries = 4) {
for (let i = 0; i < tries; i++) {
const res = await fetch('https://api.whatixo.com/api/whatsapp/messages/send', {
method: 'POST',
headers: { 'x-api-key': process.env.WHATIXO_API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
if (res.ok) return res.json();
// Don't retry "permanent" errors
if ([400, 401, 402, 403, 404, 502].includes(res.status)) throw new Error((await res.json()).error);
await new Promise((r) => setTimeout(r, 2 ** i * 2000)); // 2 s, 4 s, 8 s, 16 s
}
throw new Error('Failed after several attempts');
}