# Erreur WhatsApp 131026 : message non délivrable

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

> Erreur WhatsApp 131026 (Message Undeliverable) : numéro hors WhatsApp, conditions non acceptées ou application trop ancienne. Que vérifier, que faire.

L'erreur WhatsApp 131026 signifie que Meta n'a pas pu remettre le message au destinataire : son
numéro n'est pas sur WhatsApp, il n'a pas accepté les dernières conditions d'utilisation, ou son
application est trop ancienne. Ne réessayez pas sur WhatsApp : vérifiez le numéro, puis joignez la
personne par un autre canal.

## Que signifie l'erreur 131026 ?

Meta la décrit ainsi
([codes d'erreur de la Cloud API](https://developers.facebook.com/documentation/business-messaging/whatsapp/support/error-codes#other-errors)) :

> « Unable to deliver message. Reasons can include: The recipient phone number is not a WhatsApp
> phone number. Recipient has not accepted the new Terms of Service and Privacy Policy. Recipient
> using an old WhatsApp version. »

Trois causes possibles, donc, toutes du côté du destinataire. Pour la troisième, Meta donne les
versions minimales de l'application :

| Application                       | Version minimale |
| --------------------------------- | ---------------- |
| Android                           | 2.21.15.15       |
| SMBA (WhatsApp Business, Android) | 2.21.15.15       |
| iOS                               | 2.21.170.4       |
| SMBI (WhatsApp Business, iOS)     | 2.21.170.4       |
| KaiOS                             | 2.2130.10        |
| Web                               | 2.2132.6         |

Le titre qui accompagne le code dans le champ `message` est « Message Undeliverable »
([liste de 360dialog](https://docs.360dialog.com/docs/support/api-error-message-list)). Il décrit
le symptôme, pas la cause : c'est le code et `error_data.details` qui la donnent.

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

* **Le numéro n'a pas de compte WhatsApp** : une ligne fixe, un numéro de standard, une faute de
  frappe dans un formulaire.
* **Le numéro est mal formaté** : sans `+` ni indicatif pays, un numéro local peut être interprété
  dans le mauvais pays et tomber sur une personne qui n'a pas WhatsApp. Écrivez toujours `to` au
  format international, par exemple `+237690000001`.
* **L'application du destinataire n'est pas à jour**, ou il n'a pas validé les nouvelles
  conditions d'utilisation.

### Où la voir dans Genuka WA ?

Le cas le plus courant : Meta accepte l'envoi, puis signale l'échec dans le webhook de statut.

| Canal                                                          | Ce que vous recevez                                                                                    |
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| Webhook `message_status`                                       | `data.status: "failed"`, `data.errors[0].code: 131026`                                                 |
| Réponse de `POST /api/v1/messages`, si Meta refuse dès l'appel | `400`, `"error": "send_recipient_permanent"`, `meta.code: 131026`                                      |
| Campagne                                                       | Le destinataire passe `failed`, avec le message de Meta dans `errorMessage` ; il n'est jamais réessayé |
| Tableau de bord, section Messages                              | La bulle en échec ; « Voir pourquoi » affiche le code et le détail                                     |

```json title="Webhook message_status reçu par votre endpoint (extrait)"
{
  "id": "dlv_2f8c1a...",
  "type": "message_status",
  "field": "messages",
  "connection_id": "cn77...",
  "data": {
    "id": "wamid.HBgLMjM3...",
    "status": "failed",
    "timestamp": "1791451867",
    "recipient_id": "237690000001",
    "errors": [
      {
        "code": 131026,
        "title": "…",
        "message": "…",
        "error_data": { "details": "…" },
        "href": "/documentation/business-messaging/whatsapp/support/error-codes"
      }
    ]
  }
}
```

`data` est l'objet de statut de Meta, transmis intact : `error_data.details` dépend du cas et peut
préciser la cause.

## Comment corriger l'erreur 131026 ?

1. **Ne réessayez pas sur WhatsApp.** Le même envoi échouera de la même façon. Genuka WA classe
   131026 en `recipient_permanent` et ne le réessaie jamais, en campagne comme en envoi unitaire.
2. **Vérifiez le numéro tel que vous l'avez stocké** : indicatif pays, chiffres en trop ou en moins,
   numéro saisi dans un champ « téléphone fixe ».
3. **Joignez la personne par un autre canal**, SMS ou email, comme le recommande Meta, et
   demandez-lui de vérifier trois choses : qu'elle peut elle-même écrire à votre numéro WhatsApp
   Business, qu'elle a accepté les dernières conditions (Meta cite les écrans **Settings > Help**
   et **Settings > Application information**, qui affichent l'invite si besoin), et que son
   application est à jour.
4. **Marquez le contact comme injoignable sur WhatsApp** dans votre base, et ne le réactivez que
   lorsqu'il vous écrit : un message entrant prouve qu'il est joignable.

**Node.js**

```ts
// app/api/webhooks/whatsapp/route.ts
import { verifySignature } from "@genuka/whatsapp/webhooks";

export async function POST(request: Request) {
  const raw = await request.text();
  const signature = request.headers.get("x-genuka-signature");
  if (!(await verifySignature(process.env.WEBHOOK_SECRET!, raw, signature))) {
    return new Response("invalid signature", { status: 401 });
  }

  const event = JSON.parse(raw);
  if (event.type === "message_status" && event.data.status === "failed") {
    const codes: number[] = (event.data.errors ?? []).map((e: { code: number }) => e.code);
    if (codes.includes(131026)) {
      // À vous d'écrire cette fonction : le contact passe sur SMS/email jusqu'à son prochain message.
      void markWhatsAppUnreachable(event.data.recipient_id);
    }
  }
  return new Response("ok");
}
```

**Python**

```python
import hashlib
import hmac
import json
import os
import time

from flask import Flask, request

app = Flask(__name__)


def verify(raw: bytes, header: str, secret: str, tolerance: int = 300) -> bool:
    parts = dict(part.split("=", 1) for part in header.split(",") if "=" in part)
    timestamp = int(parts.get("t", "0"))
    if abs(time.time() - timestamp) > tolerance:
        return False
    expected = hmac.new(secret.encode(), f"{timestamp}.".encode() + raw, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts.get("v1", ""))


@app.post("/webhooks/whatsapp")
def whatsapp_webhook():
    raw = request.get_data()
    if not verify(raw, request.headers.get("X-Genuka-Signature", ""), os.environ["WEBHOOK_SECRET"]):
        return "invalid signature", 401

    event = json.loads(raw)
    if event["type"] == "message_status" and event["data"]["status"] == "failed":
        codes = [error["code"] for error in event["data"].get("errors", [])]
        if 131026 in codes:
            mark_whatsapp_unreachable(event["data"]["recipient_id"])  # votre fonction
    return "ok"
```

## Comment éviter l'erreur 131026 ?

* **Validez les numéros à la saisie**, au format international avec indicatif pays.
* **Faites venir le contact sur WhatsApp en premier** quand c'est possible, par un lien
  « Écrivez-nous sur WhatsApp » : un numéro qui vous a déjà écrit est un numéro qui reçoit.
* **Écoutez le webhook `message_status`** plutôt que la réponse d'envoi : un `200` veut dire
  « accepté par Meta », pas « livré ».
* **Gardez un canal de repli** pour les messages critiques, comme les codes de connexion. Le guide
  [OTP WhatsApp en Node.js](https://wa.genuka.com/docs/guides/whatsapp-otp-nodejs) prévoit ce repli.

## Quels codes sont liés ?

* [131050](https://wa.genuka.com/docs/errors/131050) : le destinataire reçoit bien WhatsApp, mais a refusé vos
  messages marketing.
* [131049](https://wa.genuka.com/docs/errors/131049) : message marketing retenu par Meta pour ce destinataire, à
  retenter plus tard.
* [131047](https://wa.genuka.com/docs/errors/131047) : la fenêtre de 24 heures est fermée ; un template passera.

## FAQ

### Faut-il réessayer un envoi en 131026 ?

Non, pas sur WhatsApp. Tant que le destinataire n'a pas changé de situation (installé WhatsApp,
mis à jour son application, accepté les conditions), le même envoi échouera.

### Pourquoi la réponse d'envoi est-elle 200 alors que le message a échoué ?

Parce que Meta a accepté la requête avant de tenter la livraison. Meta indique que ses erreurs
arrivent soit dans la réponse, soit par webhook, soit les deux, et recommande de surveiller les
deux. L'échec 131026 arrive le plus souvent dans le webhook de statut.

### Comment retrouver les destinataires en 131026 dans une campagne ?

`GET /api/v1/campaigns/{id}/recipients?status=failed&limit=1000` liste les destinataires en échec
avec le message de Meta, 200 par défaut et 1 000 au plus, sans pagination. Le code numérique, lui,
arrive dans le webhook `message_status` : c'est lui qu'il faut stocker si vous voulez filtrer par
cause, et c'est la seule liste complète pour une grosse campagne.

### Un message en échec 131026 est-il facturé ?

Pas par Meta, qui ne facture un template que lorsqu'il est livré
([Meta, Pricing](https://developers.facebook.com/documentation/business-messaging/whatsapp/pricing)).
Côté Genuka WA, en revanche, un envoi accepté par Meta compte dans le quota de votre abonnement,
même si la livraison échoue ensuite : écartez les numéros injoignables de vos prochains envois.

## Sources

* [Meta — Error codes](https://developers.facebook.com/documentation/business-messaging/whatsapp/support/error-codes)
* [Meta — Status webhook reference](https://developers.facebook.com/documentation/business-messaging/whatsapp/webhooks/reference/messages/status)
* [Meta — Pricing](https://developers.facebook.com/documentation/business-messaging/whatsapp/pricing)
* [360dialog — API error message list](https://docs.360dialog.com/docs/support/api-error-message-list)
