# WhatsApp error 131050: user stopped marketing messages

URL: https://wa.genuka.com/en/docs/errors/131050
Language: English

> WhatsApp error 131050: the recipient stopped your marketing messages. Why you must never retry, and how Genuka WA blocks the sends that would follow.

WhatsApp error 131050 means the recipient chose to stop receiving your marketing messages on
WhatsApp. Do not retry: the message will not be received. Remove them from your marketing sends,
and only add them back if they turn marketing messages on again themselves, which Meta tells you
about through a webhook.

## What does error 131050 mean?

> "Unable to deliver the message. This recipient has chosen to stop receiving marketing messages
> on WhatsApp from your business."
> — [Meta, Cloud API error codes](https://developers.facebook.com/documentation/business-messaging/whatsapp/support/error-codes#other-errors)

Meta's instruction leaves no room: "Do not retry sending messages to this user as they will not be
received." To learn about it ahead of time rather than after a failed send, Meta points to the
**`user_preferences`** webhook, which fires when a user stops or resumes marketing messages from
your business. It does not fire for "Interested" or "Not interested" feedback given through the
*Offers and announcements* setting
([Meta, user\_preferences webhook](https://developers.facebook.com/documentation/business-messaging/whatsapp/webhooks/reference/user_preferences)).

## When does error 131050 happen?

When you send a `MARKETING` template to someone who stopped the business's marketing messages.
With Genuka WA you mostly see it in two cases: the opt-out predates the number's connection, so
Genuka WA never received the `user_preferences` webhook announcing it; or the template was created
outside Genuka WA, and its category is unknown to us.

### What does Genuka WA do on its side?

An opt-out is a compliance boundary, not an optimization. Genuka WA treats it that way:

* **Two sources feed the same record**, per client: Meta's `user_preferences` webhook (`stop` or
  `resume`), and any 131050 reported by a send's status webhook. An opt-in can only come from a
  `resume`: a 131050 is never read as consent.
* **Single send**: a `MARKETING` template known to Genuka WA, addressed to an opted-out contact,
  is refused **before** it reaches Meta, with `403 recipient_opted_out`. Nothing is sent, nothing
  is counted against your quota.
* **`MARKETING` campaign**: opted-out contacts are excluded before the first send, marked
  `skipped` with the reason "Recipient opted out of marketing messages", and counted in the
  `skipped` field of the launch response.
* **What is not blocked**: `UTILITY` and `AUTHENTICATION` templates, and free-form replies inside
  the 24-hour window. Opting out of marketing is not opting out of being answered.

### Where do you see it in Genuka WA?

| Channel                           | What you get                                                               |
| --------------------------------- | -------------------------------------------------------------------------- |
| `POST /api/v1/messages` response  | `403`, `"error": "recipient_opted_out"`, when the opt-out is already known |
| `message_status` webhook          | `data.status: "failed"`, `data.errors[0].code: 131050`, when Meta refuses  |
| `user_preference.stopped` webhook | `data.waId`, `data.value: "stop"`, `data.timestamp`                        |
| Campaign                          | `skipped` recipients, with the reason in `errorMessage`                    |

```json title="403 — POST /api/v1/messages"
{
  "error": "recipient_opted_out",
  "message": "This recipient opted out of marketing messages"
}
```

## How do I fix error 131050?

1. **Stop every marketing send to this contact.** Genuka WA classifies 131050 as
   `recipient_permanent`: it is never retried.
2. **Record the opt-out in your own tool** (CRM, customer database), so it survives an export or a
   campaign built somewhere else.
3. **Receive the `user_preference.stopped` and `user_preference.resumed` events.** An endpoint with
   no event filter already gets them; a filtered endpoint must add them to its `events` list through
   `PATCH /api/v1/webhooks/{id}`. Only opt the contact back in on a `resumed`.
4. **Treat `403 recipient_opted_out` as a normal answer**, not an outage: the contact can still be
   reached with a utility template and in reply to their messages.

**Node.js**

```ts
// 1. On send: an opt-out refusal is not an error to page anyone about.
const response = await fetch("https://wa.genuka.com/api/v1/messages", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.GENUKA_WA_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    connectionId: "con_1",
    to: "+237690000001",
    template: { name: "october_promo", language: "en", body: ["Awa"] },
  }),
});
if (response.status === 403) {
  const { error } = await response.json();
  if (error === "recipient_opted_out") await crm.setMarketingConsent("+237690000001", false);
}

// 2. In your webhook route, once the signature is verified.
export async function onEvent(event: { type: string; data: { waId?: string } }) {
  if (event.type === "user_preference.stopped") await crm.setMarketingConsent(event.data.waId!, false);
  if (event.type === "user_preference.resumed") await crm.setMarketingConsent(event.data.waId!, true);
}
```

**Python**

```python
# In your webhook route, once the signature is verified.
def on_event(event: dict) -> None:
    kind = event.get("type")
    data = event.get("data", {})

    if kind == "user_preference.stopped":
        crm.set_marketing_consent(data["waId"], False)
    elif kind == "user_preference.resumed":
        crm.set_marketing_consent(data["waId"], True)
    elif kind == "message_status" and data.get("status") == "failed":
        if any(error.get("code") == 131050 for error in data.get("errors", [])):
            crm.set_marketing_consent(data["recipient_id"], False)
```

## How do I prevent error 131050?

* **Collect explicit consent** before any marketing, naming your business and what you will send.
* **Listen to `user_preferences` from day one**: an opt-out learned by webhook prevents the failed
  send, one learned through 131050 arrives after the fact.
* **Create your templates through Genuka WA** (`POST /api/v1/templates`): their category is then
  known, and the preventive `403 recipient_opted_out` applies.
* **Send less, but better.** An opt-out is a customer's answer to messages they did not want;
  frequency and relevance are your levers.

## Related error codes

* [131049](https://wa.genuka.com/en/docs/errors/131049): a marketing message held back for this recipient, but only
  temporarily; resending after 24 hours is allowed.
* [131026](https://wa.genuka.com/en/docs/errors/131026): the recipient receives no message at all, whatever its
  category.
* [131047](https://wa.genuka.com/en/docs/errors/131047): the 24-hour window is closed for a free-form message.

## FAQ

### Can I still send an order confirmation to an opted-out contact?

Genuka WA does not block `UTILITY` or `AUTHENTICATION` templates for a contact who opted out of
marketing: Meta's 131050 is about marketing messages. The order confirmation then has to be a
genuine utility template, not a disguised promotion.

### Does the opt-out apply to one number or to the whole business?

Meta speaks of marketing messages "from your business". Genuka WA records it per client: every
number of that client is covered.

### What happens with a template created outside Genuka WA?

Genuka WA does not know its category and lets it through. If Meta reports a 131050, the opt-out is
still recorded: your marketing campaigns and the marketing templates created through Genuka WA
will exclude that contact from then on. The unknown template itself keeps going through to Meta.

### How does a contact opt back in?

By turning your business's marketing messages back on in WhatsApp. Meta then sends the
`user_preferences` webhook with the value `resume`, which Genuka WA forwards to you as
`user_preference.resumed` and applies to its record.

## Sources

* [Meta — Error codes](https://developers.facebook.com/documentation/business-messaging/whatsapp/support/error-codes)
* [Meta — user\_preferences webhook reference](https://developers.facebook.com/documentation/business-messaging/whatsapp/webhooks/reference/user_preferences)
* [Meta — About the platform, user opt-in](https://developers.facebook.com/documentation/business-messaging/whatsapp/about-the-platform)
