Errors

Qyvo error response shape, HTTP status codes, and the Meta WhatsApp error codes you may encounter.

Qyvo returns conventional HTTP status codes and a stable JSON error shape. When sending fails because Meta rejected the message, the underlying Meta error code propagates so you can handle it cleanly.

Error shape

Every error response is JSON with at least an error field:

{
  "error": "Template not found"
}

Validation failures (Laravel format) include a message and a errors map keyed by field:

{
  "message": "The given data was invalid.",
  "errors": {
    "phone": ["The phone field is required."],
    "template_id": ["The template id must be a valid UUID."]
  }
}

Some endpoints add structured detail to help you fix the problem in code:

{
  "error": "Template requires variables that were not provided.",
  "expected_placeholders": ["1", "2"],
  "missing": ["2"]
}

HTTP status codes

Code Meaning When you see it
200 OK Successful read or send
201 Created Resource creation (contact, sequence session, …)
401 Unauthenticated Missing or invalid Authorization header, revoked token
403 Forbidden Token valid but lacks required scope (rare today — every token has mcp)
404 Not found Resource doesn't exist or doesn't belong to your tenant
422 Unprocessable Validation failed, business rule rejected, or no WhatsApp account configured
429 Too many requests Quota exceeded — see Rate limits
5xx Server error Transient — retry with backoff

Common Qyvo errors

Status error text Why
401 Unauthenticated. Token missing/wrong/revoked
404 Personal access client not found Backend install issue — contact support
404 Contact not found The phone or contact_id doesn't match any contact in your tenant
404 Template not found The template_id UUID doesn't exist in your tenant
404 Sequence not found or not published The sequence is in draft — publish it first
404 Flow not found or not published Same for flows
422 No workspace configured for this account. The user behind the token has no tenant
422 No WhatsApp account configured The tenant has no WabaAccount row — onboard a number first
422 Either contact_id or phone is required Endpoint accepts either; you sent neither
422 Template requires variables that were not provided. Body has {{1}} etc. but you didn't pass them in variables
422 Template has no approved translation to send. The template is in PENDING or REJECTED on Meta

Meta WhatsApp error codes

When the send actually reaches Meta and fails, the Meta error message bubbles up in the error field of a 422 response. The most frequent ones:

Meta code Meaning What to do
132001 Template name does not exist in this language Sync templates and confirm the language has an APPROVED translation. See sync_templates MCP tool.
132012 Parameter format does not match Your variables count or types don't match the template body — check the template placeholders
131026 Message undeliverable The recipient phone is not on WhatsApp, or has not opted-in
131047 Re-engagement message The 24-hour customer service window is closed. Send a template instead of free-form text.
131051 Unsupported message type You sent a media URL Meta rejected (size, format, host)
131056 Pair rate limit reached Meta's per-pair (sender→recipient) throttle. Backoff and retry.
133010 Phone number not registered The WhatsApp Business number is not registered with Cloud API on Meta's side

Idempotency

The Qyvo API does not currently support an Idempotency-Key header. Two consecutive send-template-message calls with the same payload will send two messages.

To deduplicate on your side:

  • On create-contact, the endpoint is upsert by (tenant_id, phone) — calling twice with the same phone returns the existing contact, no duplicates.
  • On trigger-sequence / trigger-flow, an existing running session for the same (sequence_id, contact_id) pair returns {status: "already_running"} instead of starting a second.
  • On message sends, deduplicate at the application layer (e.g. lock on order_id before calling send-template-message).

Debugging tips

  • curl -i to see the headers — X-RateLimit-Remaining, Retry-After, request id.
  • The dashboard's Inbox shows the last failed messages with the same error Meta returned. If a send returns 422, the message also appears there with status: failed for the audit trail.
  • Templates in PENDING or REJECTED won't send; check Settings → WhatsApp → Templates and resync from Meta.