La cause se lit à deux endroits : l'erreur (#code) renvoyée à la création (400 avant Meta, 502 après) et rejected_reason dans GET /v1/templates une fois le statut REJECTED. Vous ne pouvez pas éditer un template : corrigez-le puis recréez-le.
Astuce
La cause se lit à deux endroits : l'erreur (#code) renvoyée à la création (400 avant Meta, 502 après) et rejected_reason dans GET /v1/templates une fois le statut REJECTED. Vous ne pouvez pas éditer un template : corrigez-le puis recréez-le.
Vous créez un template et il reste en PENDING, puis passe en REJECTED. Ou bien la création elle-même répond une erreur. Oui, la cause est lisible, mais pas toujours au même endroit. Voici où chercher, dans l'ordre.
POST /v1/templates
├─ 422 champ invalide (nom, longueur, boutons) avant Meta
├─ 400 règle de variables ou de boutons non respectée avant Meta, message précis
├─ 502 Meta refuse à la soumission : « (#code) titre — détail »
└─ 201 soumis, status PENDING
│ (Meta examine)
▼
GET /v1/templates
└─ status APPROVED → utilisable
status REJECTED → rejected_reason = la raison de Meta, telle quelle
curl
curl -X GET "https://wa-api.geskap.com/v1/templates" \
-H "Authorization: Bearer $GESKAP_API_KEY"
Node.js
const res = await fetch("https://wa-api.geskap.com/v1/templates", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.GESKAP_API_KEY}`,
},
});
console.log(res.status, await res.json());
PHP
$ch = curl_init("https://wa-api.geskap.com/v1/templates");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("GESKAP_API_KEY"),
],
]);
$res = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), " ", $res;
Python
import os, requests
res = requests.request(
"GET",
"https://wa-api.geskap.com/v1/templates",
headers={"Authorization": f"Bearer {os.environ['GESKAP_API_KEY']}"},
timeout=15,
)
print(res.status_code, res.json())
rejected_reason ne contient quelque chose que si le status est REJECTED. Sa valeur est celle de Meta, sans reformulation : un code comme INVALID_FORMAT, INCORRECT_CATEGORY, TAG_CONTENT_MISMATCH, SCAM ou ABUSIVE_CONTENT, ou une phrase. Elle se lit en listant les templates : la liste se synchronise avec Meta à cet appel.
Ces refus ne coûtent rien et ne partent pas chez Meta :
| Message ou cause | Correction |
|---|---|
| Variable vide {{}} | Retirez-la ou nommez-la : {{1}} ou {{nom}} |
| Variables numérotées et nommées mélangées | Une seule forme dans tout le template |
| Variables numérotées avec un trou ({{1}} puis {{3}}) | Numérotez de {{1}} à {{n}} sans trou |
| Moins de example_values que de variables | Une valeur d'exemple par variable, dans l'ordre |
| Variable nommée avec un caractère interdit | Lettres, chiffres et _ uniquement |
| En-tête texte de plus de 60 caractères, sur plusieurs lignes, ou avec plus d'une variable | Une ligne, 60 caractères, au plus une variable {{1}} |
| Lien wa.me dans un bouton lien | Utilisez un bouton de réponse rapide (kind: quick_reply) |
| Lien variable mal formé | Une seule variable {{1}}, à la fin de l'URL, avec url_example complet en https |
| Nom du template | Minuscules, chiffres et _ uniquement (sinon 422) |
| Ce que Meta renvoie | Cause | Correction |
|---|---|---|
| (#132000) nombre de paramètres incorrect | Variables du corps différentes des valeurs fournies | Mêmes nombres à la création et à l'envoi |
| (#132001) le template n'existe pas | Mauvais nom ou mauvaise langue, ou pas encore APPROVED | Nom et langue exacts du template approuvé |
| INVALID_FORMAT ou exemple manquant | Une variable n'a pas d'exemple | Une entrée example_values par variable |
| Variable au début ou à la fin du corps, ou deux variables collées {{1}}{{2}} | Interdit par Meta | Mettez du texte ou une espace autour de chaque variable |
| (2388081) lien wa.me | Meta refuse les liens WhatsApp en bouton lien | Bouton quick_reply |
| INCORRECT_CATEGORY | La catégorie choisie ne correspond pas au contenu, selon Meta | Recréez avec la catégorie qui correspond au contenu |
| TAG_CONTENT_MISMATCH, SCAM, ABUSIVE_CONTENT | Contenu jugé non conforme par Meta | Réécrivez le contenu ; l'API ne peut pas contester le verdict |
| 2494160, numéro « Hors ligne » | Le numéro n'est pas connecté à l'API Cloud | Connectez et vérifiez le numéro dans WhatsApp Manager, puis recommencez |
| Catégorie AUTHENTICATION refusée | Votre entreprise Meta doit être vérifiée (Business Verification) | Faites vérifier votre entreprise dans Meta Business Manager |
Cette table reprend ce que l'API et sa documentation établissent. Pour tout autre code, le message de Meta est renvoyé tel quel : c'est lui qui fait foi.
Il n'existe pas de route de modification pour un développeur. Procédure :
Il n'y a pas d'événement de webhook pour le statut d'un template : interrogez la liste.
Un template qui n'est pas APPROVED répond 400 « Le template doit être APPROVED par Meta avant l'envoi. ». Un template introuvable (nom ou langue faux) répond 400 « Template introuvable ». Créer et lister des templates ne coûte aucun crédit chez Geskap.
Attention
Piège : un template approuvé sur un numéro n'existe pas sur un autre. Si vous avez plusieurs numéros, voir Plusieurs numéros.
Attention
Piège : PENDING n'est pas un échec. Tant que Meta n'a pas répondu, ne recréez pas : vous créeriez un doublon. Attendez le statut.
Attention
Piège : un 502 à la création n'est pas une panne de l'API : c'est Meta qui a refusé, et son message est dans la réponse. Lisez-le avant de réessayer.
Pour un template qui passe du premier coup, voir Écrire à un client qui ne vous a jamais écrit et Template à boutons de réponse rapide.
Preuve — vérifié dans le code de l'API : api_schemas.py, templates.py, api_send.py, public_api.py, dev_api_docs.py.