Description
What is a Graph API error code?
API error codes are the numbers Meta's Graph API returns to explain why a request or a message failed. Every WhatsApp Cloud API error has the same anatomy: a JSON error object with message (a short title, often prefixed with the code, such as (#132001) Template name does not exist in the translation), type (usually OAuthException), the numeric code, an error_data object whose details string explains the cause in plain language, and fbtrace_id, a trace ID Meta support can look up. General Graph errors, such as an expired token, can also carry error_subcode; for WhatsApp-specific codes Meta has deprecated it and no longer returns it from v16.0.
Errors arrive in two places. Synchronous errors come back in the HTTP response to your call: a bad parameter, a missing template, an invalid token, a throughput limit. Asynchronous errors come later in webhooks: a message accepted with a wamid can still fail, and the statuses webhook then reports status: failed with an errors array holding the same kind of code, title, message and error_data.details. A robust integration handles both paths with one lookup table.
Codes fall into families that tell you what to do. Authorisation (0, 190) and permission (3, 10, 200–299) codes point at the token. Throttling codes (4, 80007, 130429, 131056) mean slow down. Integrity codes (368, 131031) mean the account is restricted. Parameter codes (100, 131008, 131009) mean fix the request. The 131xxx range covers message-level failures such as 131026 (undeliverable), 131047 (the 24-hour window has closed) and 131049 (per-user marketing limit); 132xxx covers templates and 133xxx phone number registration. HTTP status codes report the transport-level result; the Graph error code is Meta's actual reason.
Key takeaways
- A Graph API error code is Meta's specific reason for a failure, returned in an
errorobject alongside a far less specific HTTP status. - Branch on
code, readerror_data.detailsfor the plain-language cause, and keepfbtrace_idfor Meta support. - Some failures arrive later: a send can return 200 and then fail in a
statuseswebhook carrying anerrorsarray. - For WhatsApp codes,
error_subcodeis deprecated and not returned from Graph API v16.0 onwards. - Retry throttling and temporary errors such as 4, 80007, 130429 and 131016 with backoff; fix the request, token or account for the rest.
Usage
A Graph API error code in code
{"error": {"message": "(#132001) Template name does not exist in the translation","type": "OAuthException","code": 132001,"error_data": {"messaging_product": "whatsapp","details": "template name (order_dispatched) does not exist in en_US"},"fbtrace_id": "AQx7fK2mZp9LrT4bW1nC8dE"}}
Returned in the HTTP response to POST /{PHONE_NUMBER_ID}/messages.
Properties
A Graph API error code: key facts and limits
- Error fields
- message, type, code, error_data.details, fbtrace_id
- error_subcode
- Deprecated for WhatsApp codes from v16.0
- Token errors
- 190 (expired or invalid), 0 (authentication failed)
- Permission errors
- 3, 10, 200–299
- Throttling
- 4, 80007, 130429, 131056
- Message failures (often via webhook)
- 131026, 131047, 131049
- Template errors
- 132000, 132001, 132015, 132016
- Registration errors
- 133xxx, e.g. 133005 wrong PIN
Mechanics
How does a Graph API error code work?
step 1 — Parse the body, not just the status
On any non-2xx response, read
error.code,error.messageanderror.error_data.details, and logfbtrace_idnext to your own request ID.step 2 — Classify by family
Map codes to an action: token (190 → rotate), permission (10, 200–299 → grant the scope or asset), throttling (4, 80007, 130429 → back off), request (100, 131008, 131009, 132000 → fix the payload).
step 3 — Handle webhook failures the same way
Subscribe to message statuses and treat
status: failedlike a synchronous error, readingstatuses[].errors[]. Codes such as 131026, 131047 and 131049 usually arrive this way.step 4 — Retry only what can succeed
Use exponential backoff with jitter for throttling and temporary errors. Never auto-retry 131047, 131049 or policy codes: send a template, wait, or fix the account instead.
step 5 — Escalate with evidence
For failures you cannot explain, open a support case with the
fbtrace_id, the timestamp, the phone number ID and the full error object.
Caveats
Common mistakes with a Graph API error code
Branching on the HTTP status only
Most Graph errors share a 400 status. Read
error.code, because two 400s can need opposite handling.Matching on message text
Titles and
detailsstrings are written for humans and their wording can change. Key your logic on the numericcodeand keep the text for display and logs.Retrying everything
Auto-retrying 131047, 131049 or 368 never helps and can hurt your quality signals. Retry only throttling and temporary codes, with exponential backoff and a cap.
Ignoring asynchronous failures
A 200 with a
wamidmeans accepted, not delivered. Without status webhooks you never see 131026 or 131049 and you overstate delivery.Dropping fbtrace_id
Without it Meta support cannot trace the request. Log it with every error, together with the phone number ID and timestamp.
Why it matters
Why does a Graph API error code matter?
The HTTP status alone cannot tell "retry in a second" from "never retry this". A 400 can be a typo in a parameter, a closed customer service window or a paused template; treating them alike either hammers Meta with doomed retries or drops messages that would have gone through. Mapping codes to actions — retry, fix, re-template, escalate — keeps delivery numbers honest and support queues short.
Example
Example: Triaging a festive campaign in Kochi
A Kochi jewellery chain's Onam broadcast shows 6% failures. Grouping the failed statuses by code takes a minute. Most are 131049 — withheld under per-user marketing limits, so wait at least 24 hours and do not retry now. A smaller group is 131026 — numbers that are not on WhatsApp or cannot receive the message, to be suppressed after repeated failures. And a burst of 130429 in the first minute shows the sender outran the number's throughput. The developer adds pacing to the queue, the marketer reports 131049 separately from genuine failures, and only the 130429 messages are re-queued.
Notes
Best practices for a Graph API error code
- Keep one shared table mapping each code to an action, an owner (dev, marketing or support) and a customer-facing message.
- Report 131049 separately from genuine failures: it is a limit, not a bad number.
- Alert on spikes per code rather than on the total error rate; a jump in 190 or 132015 needs a different person than a jump in 130429.
- Exercise error paths in staging with a deliberately wrong template name or an expired token.
Questions
API Error Codes FAQs
- What does OAuthException mean in a WhatsApp API error?
- It is the error
typeMeta uses for most Graph API errors, not a specific cause. The numericcodeanderror_data.detailstell you what actually went wrong — a token problem, a missing parameter or a closed window. - What is fbtrace_id in a Graph API error?
- A per-request trace identifier. Meta support uses it to find the exact failing call in their logs, so include it in any support case together with the timestamp and the phone number ID.
- Why did my message fail after the API returned 200?
- Because 200 only means Meta accepted the request. Delivery can still fail, and the reason arrives in a
statuseswebhook withstatus: failedand anerrorsarray, for example 131026 (undeliverable) or 131049 (per-user marketing limit). - Which WhatsApp API errors should I retry?
- Throttling and temporary errors: 4, 80007, 130429, 131016 and the generic 2 or 131000, always with exponential backoff. Do not retry 131047 (send a template instead), 131049 (wait at least 24 hours) or integrity errors such as 368.
- What is the difference between an HTTP status code and a Graph API error code?
- The HTTP status is the transport-level outcome; the Graph error code is Meta's specific reason. One 400 status can carry dozens of different error codes, each needing a different fix.