# Erreur WhatsApp 131050 : désinscription du marketing

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

> Erreur WhatsApp 131050 : le destinataire a arrêté vos messages marketing. Pourquoi ne jamais réessayer, et comment Genuka WA bloque les envois suivants.

L'erreur WhatsApp 131050 signifie que le destinataire a choisi de ne plus recevoir vos messages
marketing sur WhatsApp. Ne réessayez pas : le message ne sera pas reçu. Retirez-le de vos envois
marketing, et ne le réinscrivez que s'il réactive lui-même ces messages, ce que Meta vous signale
par webhook.

## Que signifie l'erreur 131050 ?

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

La consigne de Meta est sans ambiguïté : « Do not retry sending messages to this user as they will
not be received », ne renvoyez rien, le message ne sera pas reçu. Pour être prévenu à l'avance
plutôt qu'après un envoi raté, Meta renvoie au webhook **`user_preferences`**, qui se déclenche
quand un utilisateur arrête ou reprend les messages marketing de votre entreprise. Il ne se
déclenche pas pour les retours *Interested* ou *Not interested* du réglage *Offers and
announcements*
([Meta, user\_preferences webhook](https://developers.facebook.com/documentation/business-messaging/whatsapp/webhooks/reference/user_preferences)).

## Quand l'erreur 131050 apparaît-elle ?

Lors de l'envoi d'un template `MARKETING` à quelqu'un qui a arrêté les messages marketing de
l'entreprise. Avec Genuka WA, vous la voyez surtout dans deux cas : la désinscription date d'avant
la connexion du numéro, donc Genuka WA n'a jamais reçu le webhook `user_preferences` qui
l'annonçait ; ou le template a été créé hors de Genuka WA, et sa catégorie nous est inconnue.

### Que fait Genuka WA de son côté ?

Une désinscription est une frontière de conformité, pas une optimisation. Genuka WA la traite
ainsi :

* **Deux sources alimentent le même registre**, par client : le webhook `user_preferences` de Meta
  (`stop` ou `resume`), et toute erreur 131050 signalée par le webhook de statut d'un envoi. Une
  réinscription ne peut venir que d'un `resume` : un 131050 n'est jamais pris pour un accord.
* **Envoi unitaire** : un template `MARKETING` connu de Genuka WA, adressé à un contact désinscrit,
  est refusé **avant** d'atteindre Meta, avec `403 recipient_opted_out`. Rien n'est envoyé, rien
  n'est décompté de votre quota.
* **Campagne `MARKETING`** : les contacts désinscrits sont exclus avant le premier envoi, marqués
  `skipped` avec le motif « Recipient opted out of marketing messages », et comptés dans le champ
  `skipped` de la réponse de lancement.
* **Ce qui n'est pas bloqué** : les templates `UTILITY` et `AUTHENTICATION`, et les réponses
  libres dans la fenêtre de 24 heures. Un refus du marketing n'est pas un refus d'être répondu.

### Où la voir dans Genuka WA ?

| Canal                              | Ce que vous recevez                                                           |
| ---------------------------------- | ----------------------------------------------------------------------------- |
| Réponse de `POST /api/v1/messages` | `403`, `"error": "recipient_opted_out"`, si la désinscription est déjà connue |
| Webhook `message_status`           | `data.status: "failed"`, `data.errors[0].code: 131050`, si Meta refuse        |
| Webhook `user_preference.stopped`  | `data.waId`, `data.value: "stop"`, `data.timestamp`                           |
| Campagne                           | Destinataires `skipped`, avec le motif dans `errorMessage`                    |

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

## Comment corriger l'erreur 131050 ?

1. **Arrêtez tout envoi marketing à ce contact.** Genuka WA classe 131050 en
   `recipient_permanent` : il n'est jamais réessayé.
2. **Reportez la désinscription dans votre propre outil** (CRM, base clients), pour qu'elle survive à
   un export ou à une campagne montée ailleurs.
3. **Recevez les événements `user_preference.stopped` et `user_preference.resumed`.** Un endpoint
   sans filtre d'événements les reçoit déjà ; un endpoint filtré doit les ajouter à sa liste
   `events`, via `PATCH /api/v1/webhooks/{id}`. Réinscrivez le contact seulement sur un `resumed`.
4. **Traitez `403 recipient_opted_out` comme une réponse normale**, pas comme une panne : le contact
   reste joignable par template utilitaire et en réponse à ses messages.

**Node.js**

```ts
// 1. À l'envoi : un refus pour désinscription n'est pas une erreur à remonter.
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: "promo_octobre", language: "fr", body: ["Awa"] },
  }),
});
if (response.status === 403) {
  const { error } = await response.json();
  if (error === "recipient_opted_out") await crm.setMarketingConsent("+237690000001", false);
}

// 2. Dans votre route webhook, une fois la signature vérifiée.
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
# Dans votre route webhook, une fois la signature vérifiée.
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)
```

## Comment éviter l'erreur 131050 ?

* **Recueillez un accord explicite** avant tout marketing, en nommant votre entreprise et ce que
  vous enverrez.
* **Écoutez `user_preferences` dès le premier jour** : une désinscription apprise par webhook
  évite l'envoi raté, celle apprise par 131050 arrive après coup.
* **Créez vos templates via Genuka WA** (`POST /api/v1/templates`) : leur catégorie est alors
  connue, et le refus préventif `403 recipient_opted_out` s'applique.
* **Envoyez moins, mais mieux.** La désinscription est la réponse d'un client à des messages qu'il
  ne voulait pas ; leur fréquence et leur pertinence sont vos leviers.

## Quels codes sont liés ?

* [131049](https://wa.genuka.com/docs/errors/131049) : message marketing retenu pour ce destinataire, mais
  temporairement ; là, une relance après 24 heures est permise.
* [131026](https://wa.genuka.com/docs/errors/131026) : le destinataire ne reçoit aucun message, quelle que soit sa
  catégorie.
* [131047](https://wa.genuka.com/docs/errors/131047) : la fenêtre de 24 heures est fermée pour un message libre.

## FAQ

### Puis-je encore envoyer une confirmation de commande à un contact désinscrit ?

Genuka WA ne bloque pas les templates `UTILITY` ni `AUTHENTICATION` pour un contact désinscrit du
marketing : le 131050 de Meta porte sur les messages marketing. Une confirmation de commande doit
alors être un vrai template utilitaire, pas une promotion déguisée.

### La désinscription vaut-elle pour un numéro ou pour toute l'entreprise ?

Meta parle des messages marketing « from your business », de votre entreprise. Genuka WA
l'enregistre par client : tous les numéros de ce client sont concernés.

### Que se passe-t-il pour un template créé hors de Genuka WA ?

Genuka WA ne connaît pas sa catégorie et le laisse passer. Si Meta signale un 131050, la
désinscription est tout de même enregistrée : vos campagnes marketing et vos templates marketing
créés via Genuka WA excluront ensuite ce contact. Le template inconnu, lui, continuera de passer
jusqu'à Meta.

### Comment un contact se réinscrit-il ?

En réactivant les messages marketing de votre entreprise dans WhatsApp. Meta envoie alors le
webhook `user_preferences` avec la valeur `resume`, que Genuka WA vous transmet en
`user_preference.resumed` et applique à son registre.

## 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)
