Skip to content
Linq Copy agent prompt
Platform

Errors

Handle the WhatsApp API error envelope and its numeric codes safely.

Every failure uses the same envelope:

{
"success": false,
"error": {
"status": 422,
"code": 1001,
"message": "Field required.",
"doc_url": "https://docs.linqapp.com/channel/whatsapp/error/codes/1xxx/1001/",
"param": "/parts/0/body",
"details": [
{ "code": "field_required", "param": "/parts/0/body", "message": "Body is required." }
]
},
"request_id": "req_…"
}

error.status is the HTTP status the response was written with, error.code is a number, and error.message is for a human reading a log — it may be reworded at any time, so never match on it. Every code has a page in the error code reference, which also carries the complete tables.

Branch on the code, fall back to the range

Section titled “Branch on the code, fall back to the range”

Codes are allocated into five ranges. The range says what kind of failure it is; together with error.status it says whether the request or the service was at fault.

Range Category Retry?
1xxx Request errors No — correct the request first
2xxx Resource, permission and state errors No — inspect or reconcile that state
3xxx Service errors Yes — bounded backoff, unless the code’s page says otherwise
4xxx Operational and send refusals Sometimes — follow the code’s remedy
5xxx Attachment and file errors Sometimes — follow the code’s remedy

The set of codes grows additively. Branch on the integers you know, and treat an integer you do not know by its range plus the HTTP status that came with it — a 3xxx with a 503 is retryable, a 1xxx with a 422 is not, and an integer outside every range is a generic failure. Do not model the codes as a closed enum. A number is never removed and never reassigned to a different failure: once it means something, it means that forever, so a branch you write today stays correct.

When error.retry_after is present, it overrides the range guidance above: wait that many seconds, then retry. It appears exactly when the response also carries a Retry-After header, with the same value, so either source is safe to read. A 3xxx with no retry_after is retried with bounded exponential backoff, starting at 1 second and capping at 30. Sends are idempotent on Idempotency-Key, so retrying a send that actually succeeded returns the original result rather than sending twice.

  • param is present only when the response is about exactly one field and is that field’s JSON Pointer. A fault about the whole body points at the root, which is the empty string, so param may be present and empty.
  • details lists every field-level finding on a validation failure. Each entry has a string code, a JSON Pointer param naming the most specific request location the API could identify, and a message. Validation rejects and points; it never coerces a value into something acceptable.
  • context carries typed facts about the failure you may need to branch on, such as whether a customer window ever opened. Its members are documented on the codes that set them.
  • doc_url is the absolute address of the code’s page in the error code reference, present on every response whose code has a published page and absent for a code reachable only on a surface that has not been released yet; it is derived from the code alone, so link to it rather than building the address yourself.
  • trace_id appears when a valid trace context exists.

None of these is guaranteed on every error.

Log the HTTP status, request_id, and error.code. Never log credentials or message content. Include request_id when contacting Linq support; it identifies the exact request in our logs.

These codes belong to WhatsApp. Every channel numbers its own errors, so the same integer means something different on another channel — branch on the code only in code paths you know are talking to this API, and follow the doc_url it gives you rather than one from another channel.