wapi.
Guides

Errors

Failures come back in two different shapes, and which one tells you where it failed.

Failures come back in one of two forms, and which shape you get tells you where the failure happened. This mirrors the interface being cloned rather than tidying it up, because their SDK branches on it.

Route-level — uses error

Decided inside a handler:

{ "success": false,
  "error": "Your Whatsapp Session is not connected please connect your session first." }

Validation and auth — uses message

Decided by middleware, before a handler ran:

{ "success": false,
  "message": "Validation failed",
  "errors": { "to": ["The to field is required."] } }

errors is keyed by field, and each value is an array — a single field can fail more than one rule.

A third shape: 429

A rate-limit response has no success key at all:

{ "message": "Too Many Attempts.", "retry_after": 30 }

Code that checks body.success === false to detect failure will read a 429 as a success. Check the status code first.

Rate-limit headers

On every response, not just a 429:

HeaderMeaning
X-RateLimit-LimitRequests allowed in the window
X-RateLimit-RemainingHow many are left
X-RateLimit-ResetWhen the window resets

Common statuses

StatusMeaningWhat to do
401Missing or invalid credentialCheck the header is Authorization: Bearer …
403Wrong type of credentialSee Authentication
409Session not connectedConnect it; poll GET /api/status
422Validation failedRead errors, keyed by field
429Rate limitedWait retry_after seconds
503WhatsApp briefly unavailableRetry with backoff

Retrying safely

503 and 429 are safe to retry. 422 and 403 are not — they will fail identically.

The dangerous case is a timeout on a send, which is neither. The request failed, but the message may well have gone out. Reconcile with GET /api/messages/{msgId}/info rather than re-sending; see Sending messages.

On this page