Features Pricing Use cases Compare Blog

WhatsApp error 131050: the opt-out you only learn once

14 min read

The short answer

Error 131050 means the recipient has switched off marketing messages from your business. Meta's guidance is not to retry. It arrives asynchronously as a failed status on the messages webhook, never in the send response, and Meta documents no endpoint for reading a user's current preference, only the user_preferences webhook event. Checked 11 September 2026.

Contacts screen in a demo workspace showing a search box, status, source and subscription filters, a green Add contact button, and a table of names, phone numbers, status badges, lead scores, groups and a Subscribed column of green badges with per-row Chat, Edit and Delete actions.

What does WhatsApp error 131050 mean?

131050 means the person you tried to send a marketing template to has switched off marketing messages from your business. Meta's error reference gives the text word for word:

"Unable to deliver the message. This recipient has chosen to stop receiving marketing messages on WhatsApp from your business." (Meta - WhatsApp error codes)

That sentence repays an exact transcription. Meta's wording is from your business, not "from this business", and the difference is not cosmetic: the preference is scoped to you, the sender, rather than to WhatsApp marketing in general.

The remedy Meta publishes alongside it is equally direct, and it is the only instruction on the row:

"Do not retry sending messages to this user as they will not be received. To be notified whenever a WhatsApp user stops or resumes delivery of marketing template messages from your business, subscribe to the user_preferences webhook." (Meta - WhatsApp error codes)

That second sentence is where the problem starts. Meta is telling you to subscribe to a webhook so that you learn about opt-outs some way other than by hitting this error. Which raises the question no error-code page answers: if you were not subscribed at the moment the customer tapped stop, how do you ever find out?

Four ways a business can learn a customer switched off marketing, with the read API marked as not existing and the feedback buttons marked as never forwarded
A marketing preference exists as two fleeting signals and no stored one you can query.

The honest answer is that you do not, and Meta offers no way to catch up. An opt-out list on the WhatsApp Business Platform is an event-sourced projection whose completeness is capped by your webhook uptime, and 131050 is less a per-message error than an audit signal saying your copy of the truth has already drifted.

Where does 131050 actually arrive, if not in the API response?

Several of the pages ranking for this code imply you catch it where you catch everything else: in the response to POST /messages. Code written that way will never see it. Meta states the general rule on the error page itself:

"Cloud API errors are returned either synchronously as a Graph API response, asynchronously via Webhook, or sometimes through both methods." (Meta - WhatsApp error codes)

131050 is in the asynchronous group, and Meta says which one outright. The changelog entry that introduced the code, dated 18 November 2024, reads:

"Added error code 131050 for messages webhooks, indicating message non-delivery due user marketing preferences." (Meta - WhatsApp changelog)

Messages webhooks. Not the send response. The same changelog entry adds the user_preferences field itself, which is why the two have always been documented as a pair.

What happens instead is easy to miss. Your send is accepted, you get a message id, and then a failed status arrives on the messages webhook carrying 131050 in its errors array. If your pipeline treats a successful POST /messages as a delivered send, or logs webhook statuses to a table nobody queries, the opt-out is recorded somewhere in your infrastructure and visible nowhere.

Signal Arrives What it costs to obtain
user_preferences webhook The instant the user changes the setting Nothing. Subscribe once
131050 on a failed status After you attempt a send One marketing message you were told not to send
A read API Never. Not documented Not available

That changes what "handling 131050" means. Catching it in your send path is not error handling; it is the discovery mechanism of last resort, and every discovery through it is a message that should not have gone out.

Is there any API to read a user's marketing preference?

No, and this is the single most useful thing to know about the code.

Meta's user_preferences reference documents a webhook and nothing else: a Triggers section, a Syntax block, a parameter table and an example payload. No GET endpoint, no field on the contact object carrying a current preference, and nothing in the developer documentation pointing at one in WhatsApp Manager either. The reference's whole job is stated in one line:

"The user_preferences webhook notifies you of changes to a WhatsApp user's marketing message preferences." (Meta - user_preferences webhook reference)

Changes. Not state. A negative claim deserves the same scrutiny as a positive one, so to be precise about what was checked: the user_preferences reference documents no read operation, and neither the messages webhook reference nor the error-codes page names one either. If Meta ships a lookup later, that page is where it would appear.

The consequence is structural. Every other list you keep about a customer can be rebuilt from a source of record. This one cannot. There is no backfill, no replay of missed events, and no reconciliation call that returns every user who has switched you off. Your opt-out list is whatever your endpoint happened to catch, and nothing will tell you what it missed.

What does the user_preferences webhook payload contain?

This is the payload Meta publishes as its own example, reproduced as written:

{
  "object": "whatsapp_business_account",
  "entry": [{
    "id": "102290129340398",
    "changes": [{
      "value": {
        "messaging_product": "whatsapp",
        "metadata": {
          "display_phone_number": "15550783881",
          "phone_number_id": "106540352242922"
        },
        "contacts": [{ "wa_id": "16505551234" }],
        "user_preferences": [{
          "wa_id": "16505551234",
          "detail": "User requested to resume marketing messages",
          "category": "marketing_messages",
          "value": "resume",
          "timestamp": 1731705721
        }]
      },
      "field": "user_preferences"
    }]
  }]
}

A stop event is the same shape with the opposite values. Meta's parameter table describes three of those four fields, in these words:

Field What Meta's parameter table says Value on a stop
value "Marketing message preference." stop
detail "Description of marketing message preference." User requested to stop marketing messages
timestamp "Unix timestamp indicating when the webhook was triggered." Integer
category No row at all marketing_messages

That last row is worth pausing on. category appears only inside the example payload, hardcoded, with no entry in the parameter table and therefore no documented list of the values it can take. marketing_messages is the only one anybody has seen. Write your handler so an unrecognised category is stored and skipped rather than assumed to be marketing.

One more detail in that reference repays a careful read: a caution attached to the user identifier, noting that a WhatsApp user's ID and phone number may not always match. A suppression table keyed strictly on a normalised E.164 number works right up until it silently does not, and the failure mode is an opt-out that was received, parsed, stored under a key nothing looks up, and then contradicted by a campaign.

What happens to your opt-out list while the webhook endpoint is down?

Nothing visible. That is the problem.

A user_preferences event fires once, at the moment the setting changes. Meta's webhooks documentation is explicit about what happens when your server does not take it:

"If any update sent to your server fails, we will retry immediately, then try a few more times with decreasing frequency over the next 36 hours." (Meta - Webhooks, Getting started)

and, on the same page, "Unacknowledged responses will be dropped after 36 hours." The sentence that makes this article necessary is there too:

"You will not be able to query historical webhook event notification data, so be sure to capture and store any webhook payload content that you want to keep." (Meta - Webhooks, Getting started)

So the hole is not vaguely "a period of downtime". It is precisely whatever your endpoint failed to acknowledge inside 36 hours, and it is permanent.

The hole also has no shape. You cannot count it, you cannot list the affected numbers, and the only way to find one is to send the message you were told not to send and watch a 131050 come back. A lapsed certificate, a four-minute deploy or a firewall change does the damage, and it surfaces weeks later in a campaign report. The diagnostic path is the same as for any missed inbound event, covered in why a verified WhatsApp webhook can still receive nothing.

This is why "subscribe to the webhook" is a true instruction and an incomplete answer. The practical mitigations are unglamorous: alert on the absence of user_preferences events rather than only on their content, record your endpoint's downtime windows where a campaign owner can see them, and treat every 131050 as a report that your store was already wrong.

How is 131050 different from 131049?

These two are conflated constantly, including on pages that list both. They differ in kind, and the correct response to each is the opposite of the response to the other.

131049 is Meta's own per-user frequency cap:

"WhatsApp may limit the number of marketing template messages a WhatsApp user receives from any business in a given period of time when they are less likely to be receptive and engage with those messages." (Meta - Per-user marketing template message limits)

and the same page states how it reaches you:

"If a marketing template message is not delivered due to per-user marketing template limit enforcement or a business has repeatedly attempted to resend a message to a user that has reached their limit, the messages webhook is triggered with status set to failed and error code set to 131049." (Meta - Per-user marketing template message limits)

Note "from any business". 131049 counts across every sender and the customer took no action to cause it. 131050 counts only against you, and the customer chose it.

What differs 131049 131050
Who decided WhatsApp The recipient
Scope Across every business Your business only
Lifetime Temporary Standing until the user resumes

The retry advice follows. Meta's guidance on 131049 is to wait at least 24 hours before resending; its guidance on 131050 is not to retry at all. A queue treating both as "failed, back off and try later" will eventually retry an opt-out, and repeatedly messaging someone who asked you to stop is a policy problem rather than a delivery one. What error 131049 means and what to do about it covers that code on its own terms.

Do utility and authentication templates still reach an opted-out user?

Several of the pages ranking for this code say yes. I could not find that stated anywhere in Meta's documentation, and this page is not going to launder an inference into a fact.

What Meta does state is narrower. The preference carries category: "marketing_messages" and no other category. The error text names marketing messages specifically. The user_preferences reference describes stopping and resuming marketing messages and says nothing about any other message type. The user-facing control, described below, is about offers and announcements.

From that it is reasonable to infer that a utility or authentication template is unaffected, and most implementations already rely on the inference. It is still an inference. Treat it as a working assumption rather than a guarantee to promise a customer, and where it matters commercially, an OTP that must arrive or a delivery notification someone is waiting on, confirm it against your own send records for a user you know has opted out rather than against anyone's blog, including this one.

What does the customer actually tap to switch marketing off?

The control the customer sees and the string your code receives are not the same words, which is why searching Meta's developer documentation for the user-facing name returns nothing useful.

Meta's newsroom describes the consumer surface:

"WhatsApp gives people tools to share feedback on messages they receive from businesses using the interested and not interested buttons when they receive offers and announcements such as a coupon for a holiday sale, information about new products, back-in-stock alerts, or reminders about upcoming sales and events. They can also turn off/on the option to receive these types of messages at any time." (Meta Newsroom - Ways to manage your business chats on WhatsApp, 3 April 2025)

So the customer sees Offers and announcements, plus Interested and Not interested buttons. Your API sees marketing_messages. Nothing in either vocabulary points at the other, and the webhook is deliberately blind to half of that surface:

"Note: This webhook triggers only when a user stops or resumes marketing messages. It does not trigger when a user indicates Interested or Not interested feedback through the Offers and announcements setting." (Meta - user_preferences webhook reference)

Meta collects that feedback and never forwards it. A customer can press Not interested on three of your campaigns in a row and your own data will show three delivered messages and no dissent at all. If your campaign reporting looks healthy and your reach is capped anyway, this is one of the invisible inputs.

What should happen in your own system the moment a stop arrives?

Four things, in this order, and none of them is a retry.

  1. Persist it before you acknowledge it. Write the event to durable storage and return 200 after the write, not before. A 200 tells Meta to stop retrying, and a 200 from a handler that then throws is how an opt-out is lost while both sides believe it was delivered.
  2. Key the record on the identifier Meta sent, with the phone number stored alongside rather than as the primary key, for the reason in the payload section above.
  3. Enforce it at send time, per recipient, not at campaign launch. A campaign built on Monday and sent on Thursday has a three-day window in which a stop can arrive, and an audience frozen at launch will happily send into it.
  4. Record the resume as carefully as the stop. The values are symmetrical and a customer who turns marketing back on has told you something valuable. A store that only ever writes suppressions cannot represent that.
Contacts table in a demo workspace with phone, status, lead score and group columns, a Subscribed column of green badges, and filters for status, source and subscription state above the rows
A per-contact consent state that the campaign dispatcher re-reads for every recipient at send time, rather than freezing it when the campaign was built.

The third point is where platforms differ, and it is worth asking yours directly. In WabaCRM the audience is a stored filter until launch and the dispatcher re-checks consent per recipient as it sends, so an opt-out landing mid-campaign stops the remaining messages rather than only the next campaign. Whatever the platform, the question is the same: at what moment is the suppression list read, and what happens to a send queued before the stop arrived.

Does honouring 131050 cover what WhatsApp's policy requires?

Not on its own, and this is the part a purely technical reading of the error misses. The WhatsApp Business Messaging Policy sets the obligation wider than any one signal:

"You must respect all requests (either on or off WhatsApp) by a person to block, discontinue, or otherwise opt out of communications from you via WhatsApp, including removing that person from your contacts list." (WhatsApp Business Messaging Policy)

"Either on or off WhatsApp" is doing the work there. A customer who replies STOP in the chat, emails your support address, tells a salesperson on the phone, or unsubscribes from your mailing list has made a request you are required to respect, and none of those produces a user_preferences event or a 131050. Meta's own opt-in guidance points the same way, asking businesses to provide clear instructions for how people can opt out of receiving specific categories of messages, and honour those requests.

So 131050 is the floor, not the ceiling. The platform preference is one input to a suppression list that also has to absorb keyword replies, off-platform requests and your own consent record. The consent side of that is covered in what WhatsApp actually requires from an opt-in, and the two halves are worth designing together: a business that collects consent carefully and then keeps its opt-outs in an incomplete event log has only solved the half that shows up in an audit.

Every Meta quotation on this page was read from Meta's own documentation on 11 September 2026. Meta changes that documentation without notice; the linked pages are authoritative and this one is not.

Questions people also ask

Can a business reverse a 131050 opt-out from its side?

No. Meta documents two values for the preference, stop and resume, and both describe something the WhatsApp user did: stop indicates the user has opted to stop receiving marketing messages from you, and resume is the same action in reverse. There is no documented endpoint that writes a preference, and nothing in the user_preferences reference describes a business-initiated change. The only path back is the person turning the setting on again in their own WhatsApp client, which produces a resume event on the same webhook field. Treat a stop as permanent until a resume arrives, and do not build an interface that implies your team can clear it.

Does the user_preferences webhook need its own subscription?

Yes. It is its own webhook field, distinct from messages, and Meta's own payload carries the string user_preferences in the field key of every change object. A server already receiving inbound customer messages and delivery statuses is subscribed to messages and is not, by that fact, subscribed to user_preferences. Field subscription is set on the app in the App Dashboard, and delivery to any one WhatsApp Business Account additionally depends on that account being subscribed to your app. Check both before assuming opt-out events are reaching you, because an unsubscribed field fails silently: no error is raised anywhere, you simply never receive the notification.

Will 131050 appear even if I never subscribed to user_preferences?

Yes, because the two are separate signals on separate fields. Error 131050 arrives as a failed status on the messages webhook, which almost every integration is already subscribed to in order to render delivery ticks. The user_preferences field is what tells you about a preference change at the moment it happens, before any send. So a business that never subscribed to user_preferences still sees 131050, just later and only for people it has already attempted to message. That is the whole asymmetry this article is about: one signal is free and proactive, the other costs you an attempted send to obtain.

Does switching marketing off stop every business or just mine?

Meta's opt-in documentation describes the control as per business: people can share feedback with WhatsApp or choose to stop receiving marketing messages from individual businesses. So a customer who has switched your marketing off has not necessarily switched anyone else's off, and a customer who is happily receiving another company's promotions may still return 131050 for yours. This also means you cannot infer anything about your own standing from the fact that a person receives marketing from other senders. The preference is scoped to the sender, and the error text says so directly by naming your business rather than businesses in general.

Is the wa_id in the payload always the customer's phone number?

Not necessarily. Meta's parameter table for this webhook annotates the WhatsApp user ID with a caution worth reading before you build a suppression list: it notes that a WhatsApp user's ID and phone number may not always match. Most of the time they do, which is exactly why a store keyed strictly on an E.164 phone number appears to work for months. Key your opt-out records on the identifier Meta sends, keep the phone number alongside it as a secondary attribute, and make the lookup at send time tolerate an entry that has no phone number attached rather than skipping it.

Keep reading

Your customers are already on WhatsApp

Free for your first 1,000 contacts, with no time limit and no card. Setting up the workspace takes minutes; connecting a number takes as long as Meta's own review of it.

Sign up with your company email address. No sales call, no onboarding fee, nothing to schedule.

Why this is safe to point your customer list at

Payments are processed by Razorpay on their own checkout — your card details are never entered on, or stored by, WabaCRM. Every inbound WhatsApp webhook is checked against its signature before it is trusted.

Tech Provider is a Meta platform access tier — not a partnership, a reseller agreement or an endorsement.