WhatsApp API error codes and what to do

A WhatsApp Cloud API error is a numeric code inside an error object that Meta returns when it refuses a request, and the code, not the HTTP status, tells you whether to retry. Some codes mean "slow down", some mean "fix your message", and some mean "stop sending to this person". This post lists the common ones with Meta's wording and a retry rule for each.

What does a Meta error look like?

Meta's error object carries a message, a type, a numeric code, an optional error_subcode, an fbtrace_id and, for WhatsApp, an error_data.details string with a plain explanation. According to Meta's error codes page, you branch on the code. WhaBuzz returns this object unchanged, so the same table applies whether you call Meta directly or through WhaBuzz.

Treat the HTTP status as a hint only. A rate-limit code and a bad-parameter code can both arrive as a 4xx, and you want to retry one and not the other.

How does WhaBuzz return Meta's errors?

WhaBuzz puts Meta's object under error with "source":"meta" and uses Meta's own HTTP status. From the errors reference:

{
  "source": "meta",
  "error": {
    "message": "(#131030) Recipient phone number not in allowed list",
    "type": "OAuthException",
    "code": 131030,
    "error_data": {
      "messaging_product": "whatsapp",
      "details": "Recipient phone number not in allowed list: Add recipient phone number to recipient list and try again."
    },
    "error_subcode": 2655007,
    "fbtrace_id": "AqN2fZtPLm1oV0xK3wRhjQe"
  }
}
json

Errors WhaBuzz raises itself (a bad API key, a number that is not connected) use "source":"whabuzz" and a WhaBuzz code such as number_not_connected. The header X-WhaBuzz-Error-Source repeats the source so you can branch before parsing. If Meta answers with something that is not JSON, you get {"source":"meta","error":{"raw_body":"..."}} with the first 4 KB.

Every response also carries a request_id (and an X-WhaBuzz-Request-Id header). Log it. You can look a request up yourself with GET /v1/requests/{request_id}, or on the console's Logs page. Per the docs, lookups cover the last 24 hours and only your own requests, so a request that failed with a 401 before authentication cannot be looked up.

curl https://api.whabuzz.com/v1/requests/req_01JAB3W1Z4B7D0F3H6K9N2Q5S8 \
  -H "Authorization: Bearer $WHABUZZ_KEY"
bash

Which errors mean slow down and retry?

Two codes are about rate, and both are safe to retry after waiting.

  • 130429. Meta: "Cloud API message throughput has been reached." Reduce how often you send and try again later. Per Meta's throughput page the default is 80 messages per second per number.
  • 131056. Meta: too many messages sent from the sender phone number to the same recipient in a short period. Wait and retry if you still intend to message that person; sends to other people are unaffected. The limit is 1 message every 6 seconds to the same user.

Retry with exponential back-off and the same Idempotency-Key. The full picture of limits is in the messaging limits post.

Which errors mean fix the message?

These fail every time until you change something, so do not auto-retry. The one new teams meet first is 131047, where Meta's text is:

More than 24 hours have passed since the recipient last replied to the sender number.

The fix is to send a template message instead (see the 24-hour window post). The others in this group:

  • 131047. Free-form message outside the window. Use an approved template.
  • 132000. The number of variable parameter values did not match the number defined in the template.
  • 132001. Meta: the template does not exist in the specified language, or has not been approved. Check the approval status, the name and the language code.
  • 131021. Sender and recipient are the same number. Send to a different one.
  • 131026. Meta: unable to deliver. Reasons include the recipient not being on WhatsApp, or not having accepted the new Terms of Service and Privacy Policy. Retrying will not help. Mark the contact as unreachable.

For template failures, the template approval post covers why Meta rejects them.

Which errors mean stop sending?

Some codes are Meta telling you the audience or the content is the problem. Resending makes it worse.

  • 131050. Meta: the recipient has chosen to stop receiving marketing messages from your business. Meta's own text says not to retry. Record the preference on your side.
  • 131048. Meta: restrictions on how many messages can be sent from this number, possibly because too many earlier messages were blocked or flagged as spam. Review content and audience before sending more.
  • 131049. Meta: the message was not delivered because of a per-user marketing limit. If you suspect that limit, Meta says to wait at least 24 hours before resending the template, because an earlier retry will only fail again.
  • 132015 and 132016. The template is paused for low quality, or has been paused too many times and is permanently disabled. Edit it, or for a disabled template create a new one with different content.

WhaBuzz does not hold opt-out lists, so keeping your own record of 131050 is your job. WhaBuzz forwards user.preferences events, nothing more.

Which errors are about the account or token?

  • 190. Meta: the access token has expired. For a number connected through WhaBuzz, reconnect it from the console. The numbers guide explains connection states.
  • 133010. Meta: phone number not registered on the WhatsApp Business Platform. Register it.
  • 131042. Meta: an error related to the payment method, such as no payment account attached to the business account, or a credit line over its limit. Meta bills its charges to your own Meta account, so this is fixed in your Meta billing settings, not in WhaBuzz.
  • 131000. Meta: unknown error. Retry once, then contact support with the fbtrace_id and the request_id.

What is the outcome-unknown case?

502 meta_unreachable is a WhaBuzz code, not a Meta one. It means Meta's Graph API did not answer within 15 seconds, and the docs are clear that the outcome is unknown: the message may or may not have gone out. Do not compose a fresh send blindly. Check for a message.outbound or message.status event first, and read the idempotency guide for how a stored 502 behaves against a key.

Failures after Meta accepts a message arrive later as events: a message.status with status: "failed" carries status.errors[] in Meta's format, so the same codes apply.

How do you handle errors in Node.js?

With the whabuzz package, failures throw WhaBuzzError with status, source, code, meta (Meta's error object, verbatim) and requestId. A small classifier keeps the retry rules in one place:

const RETRY = new Set([130429, 131056]);
const STOP = new Set([131050, 131048, 131026]);

function classify(e) {
  if (e.source !== 'meta') return 'inspect';
  if (RETRY.has(e.meta.code)) return 'retry-later';
  if (STOP.has(e.meta.code)) return 'stop-contacting';
  return 'fix-and-resend';
}
js

Log e.requestId and e.meta.fbtrace_id together. Meta support asks for the second, and WhaBuzz support looks up the first.

Frequently asked questions

Should I retry every WhatsApp API error?

No. Retry only rate codes such as 130429 and 131056, and server-side faults. Codes like 131047, 131050 and 132001 fail until you change the message, the template or the audience.

Where is the full list of WhatsApp error codes?

On Meta's error codes page. It lists each code, its meaning and Meta's recommended fix. This post covers the common ones only.

Does WhaBuzz change Meta's error codes?

No. Meta's error object is returned verbatim under error, with Meta's own HTTP status and "source":"meta".

How long can I look up a request_id?

The docs say lookups cover the last 24 hours and only your own requests.

What does 131047 mean?

More than 24 hours have passed since the customer last replied. Send an approved template instead of a free-form message.