Errors
Success vs error shapes
Success responses vary by endpoint (see each reference page) — some use success: true, some use status: true, and group endpoints nest their payload under data.
Errors are always the same envelope:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": { "fieldErrors": { "number": ["Required"] } }
}
}
code— a stable machine-readable string (table below).message— a human-readable explanation.details— optional; present on validation errors (a flattened field-error map) and some others.
Always branch on the HTTP status code and error.code, not on the message text.
Status codes
| HTTP | error.code | Meaning |
|---|---|---|
| 400 | VALIDATION_ERROR | Body failed validation (missing/invalid fields). Check details. |
| 401 | UNAUTHORIZED | Missing or invalid Device Key / apikey. |
| 402 | INSUFFICIENT_CREDITS | Wallet can't cover the call. Top up. |
| 403 | FORBIDDEN | Authenticated but not allowed to perform this action. |
| 403 | SUBSCRIPTION_REQUIRED | An active subscription is required. |
| 404 | NOT_FOUND | Resource doesn't exist. |
| 409 | CONFLICT | Conflicting state. |
| 409 | SESSION_NOT_CONNECTED | The device isn't linked/connected — (re)scan the QR. |
| 429 | RATE_LIMITED | Too many requests. Honor Retry-After. |
| 502 | ENGINE_ERROR | The WhatsApp engine failed or was unreachable. Retry with backoff. |
| 502 | UPSTREAM_ERROR | An upstream dependency failed. |
| 500 | INTERNAL_ERROR | Unexpected server error. Retry; contact support if it persists. |
Common cases
Missing Device Key → 401
{ "success": false, "error": { "code": "UNAUTHORIZED", "message": "Missing Device Key (Authorization: Bearer <deviceKey>)" } }
Validation error → 400
Sending an image without media_url:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": { "fieldErrors": { "media_url": ["media_url is required for image"] } }
}
}
Device not connected → 409
{ "success": false, "error": { "code": "SESSION_NOT_CONNECTED", "message": "Session not connected" } }
Open the QR page and re-link the device.
Retry guidance
| Code | Retry? |
|---|---|
RATE_LIMITED | Yes — after Retry-After seconds. |
ENGINE_ERROR, UPSTREAM_ERROR, INTERNAL_ERROR | Yes — with exponential backoff. |
SESSION_NOT_CONNECTED | Only after re-linking the device. |
VALIDATION_ERROR, UNAUTHORIZED, INSUFFICIENT_CREDITS | No — fix the request / wallet first. |