Skip to content
WaaruDocs

Handle API errors, limits, and retries

Interpret Waaru Developer API error codes, rate-limit headers, admission failures, and uncertain send outcomes without duplicating customer messages.

Reviewed

Send HTTPS requests with a Bearer key. For message writes use Content-Type: application/json and the supported message payload. Check the HTTP status before interpreting the body: message acceptance is 202, reads are 200, and successful media reads contain bytes.

Read the error envelope

Errors include a stable code and a human-readable message. Some include additional safe details. Branch on the status and code rather than matching the message text.

{
  "code": "service_window_closed",
  "message": "The customer-service window is closed. Use an approved template."
}
Status and codeNext action
400 invalid_messageCorrect the payload shape, recipient, or field limit. Unknown message fields are rejected.
400 invalid_pagination or invalid_cursorUse only the supported list parameters and the returned opaque cursor.
401 unauthorized or invalid_api_keyCheck the token, rotation, and revocation state.
403 insufficient_scopeAdd only the scope required for this operation.
403 api_key_not_allowedChoose a supported external endpoint. Dashboard routes are not generally API-key routes.
404 message_not_found, conversation_not_found, or media_not_foundCheck the identifier and the key's number. The resource may be unavailable within that scope.
404 template_not_foundCreate or sync the exact template name and language for the sending account in the dashboard.
409 instance_not_api_managedChoose Developer API handling for the bound number.
409 contact_unavailableThe contact was deleted or is unavailable. Review the contact record before sending.
409 message_not_allowedAnother admission policy blocks this message. Review the error and current conversation state.
503 temporarily_unavailableDelay and respect retryAfterSeconds when returned. Do not bypass an unavailable safety check.
409 instance_unavailableRestore the sender connection.
409 conversation_owned_by_humanCoordinate with the Inbox owner. Use Release to API when a person decides the server should resume.
409 service_window_closedUse an eligible approved template or wait for a new customer message.
409 template_not_approved or quality_blockedCheck template approval and current sender/template quality. Do not bypass admission with another key.
409 contact_opted_out, contact_instance_restricted, or contact_marketing_restrictedRespect the restriction. Review its exact scope in the dashboard.
429Reduce request volume and wait for Retry-After when supplied. For media_concurrency_exceeded, also close active downloads.
503 backlog_fullAdmission is temporarily at capacity. Delay further sends.
Other 5xx or network timeoutReconcile the outcome before retrying a write.

An accepted message can fail later. Check its message status or message.failed callback as well as the initial HTTP response.

Respect rate limits

Read RateLimit-Policy, RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset when returned. Reset is a wait in seconds, not an absolute timestamp. A request-rate 429 includes Retry-After. Safety services can return 503 instead of allowing unbounded traffic.

Current Developer API request budgets are:

Request classBurstSustained
Sends20 per second per key and per number600 per minute per key and per number; 1,200 per minute across the workspace.
Reads60 per second per key3,000 per minute per key.

Additional network-level limits and media-download concurrency checks apply. These request budgets do not promise WhatsApp delivery throughput or override Meta quality and capacity limits. Follow the returned limiting headers when several controls apply.

Retry without duplicate messages

Retry safe reads with bounded exponential backoff and jitter. Respect Retry-After instead of retrying immediately.

POST /v1/messages has no public client idempotency contract. A timeout does not prove rejection. Store your send attempt and any returned messageId; query that message, inspect the conversation, and reconcile callbacks before deciding to send again. Do not attach an invented Idempotency-Key header and assume it prevents duplicates.

For help, record the request time, route, status, stable error code, and returned X-Waaru-Request-Id if present. Share sensitive contact or conversation details only through the appropriate support flow, and never include the API key or signing secret.

Next: Receive and reconcile webhooks.

On this page