Implémenter une enquête de satisfaction NPS ou CSAT via l'API WhatsApp Business demande de maîtriser quatre composants : le template de question avec boutons de note, l'envoi déclenché par un événement, la réception de la réponse via webhook, et la relance pour le verbatim. Ce tutoriel couvre chaque étape avec des exemples de code concrets.
Prérequis avant de commencer
Avant d'écrire la première ligne de code, assurez-vous d'avoir :
- Un accès API Whakup actif (Meta Tech Provider certifié, pas de démarche Meta directe nécessaire)
- Un
API_KEYet unphone_number_idpour le numéro expéditeur - Un endpoint HTTPS exposé publiquement pour recevoir les webhooks
- Un template WhatsApp approuvé par Meta (procédure dans l'étape 2)
- Une base de données pour stocker les réponses et les
message_id
Pour les fondamentaux de l'architecture, consultez le guide complet de l'API WhatsApp Business.
Étape 1 : Concevoir la séquence d'enquête
Une enquête WhatsApp efficace se déroule en deux temps :
Temps 1 — Template de note (envoi proactif, nécessite un template approuvé) :
Bonjour Marie, comment évaluez-vous votre expérience avec notre service client ce matin ? Appuyez sur une note. [Très satisfaite] [Neutre] [Déçue]
Temps 2 — Relance verbatim (message session, dans les 24h suivant la réponse) :
Merci pour votre retour ! Pouvez-vous nous dire ce qui vous a le plus marquée ?
Cette séquence donne un score ET un verbatim sans rediriger vers un formulaire externe. Le taux de complétion est nettement supérieur à un lien URL.
Étape 2 : Créer et soumettre le template de note
Structure du template NPS simplifié (3 boutons)
{
"name": "enquete_satisfaction_livraison",
"language": "fr",
"category": "UTILITY",
"components": [
{
"type": "body",
"text": "Bonjour {{1}}, votre commande {{2}} a été livrée. Comment s'est passée votre expérience de livraison ?\n\nAppuyez sur une note pour répondre en 2 secondes.",
"example": {
"body_text": [["Marie Dupont", "#CMD-45821"]]
}
},
{
"type": "buttons",
"buttons": [
{
"type": "quick_reply",
"text": "😊 Très bien"
},
{
"type": "quick_reply",
"text": "😐 Correct"
},
{
"type": "quick_reply",
"text": "😕 Décevant"
}
]
}
]
}
Soumettez ce template via le dashboard Whakup ou l'API de gestion de templates. Le délai de validation est généralement inférieur à 1 heure pour un template simple sans lien externe.
Template NPS numérique (avec lien formulaire pour granularité)
Si vous avez besoin d'une échelle 0-10 standard, un bouton URL vers un formulaire externe est plus adapté :
{
"type": "buttons",
"buttons": [
{
"type": "url",
"text": "Donner ma note (0 à 10)",
"url": "https://votreplateforme.com/nps/{{1}}",
"example": ["token_membre_abc123"]
}
]
}
Le {{1}} dans l'URL est remplacé à l'envoi par un token unique par répondant, ce qui permet le tracking sans authentification.
Étape 3 : Envoyer le template au bon moment
Déclenchement après un événement
import requests
from datetime import datetime
WHAKUP_API_KEY = "your_api_key"
PHONE_NUMBER_ID = "your_phone_number_id"
def envoyer_enquete_satisfaction(commande):
"""
Appelé 1 heure après confirmation de livraison.
"""
payload = {
"to": commande["client_telephone"],
"phone_number_id": PHONE_NUMBER_ID,
"type": "template",
"template": {
"name": "enquete_satisfaction_livraison",
"language": {"code": "fr"},
"components": [
{
"type": "body",
"parameters": [
{"type": "text", "text": commande["client_prenom"]},
{"type": "text", "text": commande["numero_commande"]}
]
}
]
}
}
response = requests.post(
"https://api.whakup.com/v1/messages",
headers={"Authorization": f"Bearer {WHAKUP_API_KEY}"},
json=payload,
timeout=10
)
data = response.json()
message_id = data.get("message_id")
if message_id:
# Stocker le message_id pour corréler la réponse
save_enquete_envoi(
commande_id=commande["id"],
client_tel=commande["client_telephone"],
message_id=message_id,
envoyee_le=datetime.utcnow()
)
return message_id
Planification avec un scheduler
Si votre plateforme envoie les enquêtes 1h après livraison, utilisez votre système de tâches différées :
# Exemple avec Celery
from celery import Celery
app = Celery()
@app.task
def task_enquete_post_livraison(commande_id):
commande = get_commande(commande_id)
if commande and commande["client_optout_whatsapp"] is False:
envoyer_enquete_satisfaction(commande)
# Déclenché depuis votre logique de confirmation livraison :
task_enquete_post_livraison.apply_async(
args=[commande.id],
countdown=3600 # 1 heure
)
Étape 4 : Recevoir et traiter les réponses via webhook
Endpoint webhook
from flask import Flask, request, jsonify
import json
app = Flask(__name__)
@app.route("/webhook/whatsapp", methods=["POST"])
def webhook_handler():
data = request.json
event_type = data.get("type")
if event_type == "button":
# Réponse à un bouton quick_reply
traiter_reponse_note(data)
elif event_type == "message":
# Message texte libre (verbatim)
traiter_verbatim(data)
elif event_type == "message_status":
# Mise à jour de statut (sent, delivered, read, failed)
mettre_a_jour_statut(data)
return jsonify({"status": "ok"})
def traiter_reponse_note(data):
sender = data["from"]
bouton_texte = data["button"]["text"]
# Mapper le libellé du bouton vers un score
scores = {
"😊 Très bien": 5,
"😐 Correct": 3,
"😕 Décevant": 1
}
score = scores.get(bouton_texte)
# Retrouver l'enquête liée à ce numéro (dernière non-répondue)
enquete = get_enquete_en_cours(sender)
if enquete and score is not None:
save_note_enquete(enquete["id"], score, bouton_texte)
# Envoyer la relance verbatim
envoyer_relance_verbatim(sender, enquete)
def traiter_verbatim(data):
sender = data["from"]
verbatim = data["text"]["body"]
enquete = get_enquete_en_cours_verbatim(sender)
if enquete:
save_verbatim_enquete(enquete["id"], verbatim)
# Remercier le client
envoyer_remerciement(sender)
cloturer_enquete(enquete["id"])
Envoyer la relance verbatim (message session)
Après réception de la note, envoyez un message libre (pas besoin de template dans la fenêtre de 24h) :
def envoyer_relance_verbatim(telephone, enquete):
payload = {
"to": telephone,
"phone_number_id": PHONE_NUMBER_ID,
"type": "text",
"text": {
"body": "Merci pour votre retour ! Pouvez-vous nous dire ce qui vous a le plus marqué(e) ? (Quelques mots suffisent)"
}
}
requests.post(
"https://api.whakup.com/v1/messages",
headers={"Authorization": f"Bearer {WHAKUP_API_KEY}"},
json=payload
)
Étape 5 : Stocker et agréger les scores
Schéma de base de données minimal
CREATE TABLE enquetes_satisfaction (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
commande_id UUID REFERENCES commandes(id),
client_telephone VARCHAR(20) NOT NULL,
message_id VARCHAR(100), -- ID retourné par Whakup
statut VARCHAR(20) DEFAULT 'envoyee', -- envoyee, vue, note_recue, complete
score SMALLINT, -- 1, 3 ou 5 pour 3 boutons
bouton_clique VARCHAR(50),
verbatim TEXT,
envoyee_le TIMESTAMP NOT NULL,
repondue_le TIMESTAMP,
INDEX idx_telephone (client_telephone),
INDEX idx_message_id (message_id)
);
Calcul du CSAT en temps réel
def calculer_csat(periode_debut, periode_fin):
"""
CSAT = % de répondants avec score >= 4 (sur 5).
Avec 3 boutons (scores 1/3/5), CSAT = % de "Très bien".
"""
total = count_enquetes_completes(periode_debut, periode_fin)
positifs = count_enquetes_score_5(periode_debut, periode_fin)
if total == 0:
return None
return round((positifs / total) * 100, 1)
FAQ
Comment gérer le cas où le répondant envoie un message hors contexte ?
Si le client envoie un texte libre qui n'est pas un verbatim attendu (par exemple, une question sur sa commande), votre webhook le reçoit comme un message ordinaire. Décidez si votre plateforme a un chatbot de fallback ou si vous renvoyez vers votre support. Dans tous les cas, répondez dans la fenêtre de 24h pour rester dans la session gratuite.
Peut-on envoyer plusieurs enquêtes différentes depuis le même numéro ?
Oui. Un seul numéro peut avoir plusieurs templates actifs. Assurez-vous que la logique de corrélation (quel template correspond à quelle enquête en cours pour ce numéro) est solide côté base de données.
Les boutons quick_reply sont-ils limités en nombre de caractères ?
Oui. Chaque bouton quick_reply est limité à 20 caractères. Tenez-en compte dans la rédaction de vos libellés. Avec les emojis, comptez bien les caractères Unicode.
Comment éviter d'envoyer deux enquêtes au même client dans un court délai ?
Ajoutez une vérification avant l'envoi : si le client a déjà une enquête ouverte (statut envoyee ou vue) depuis moins de 7 jours, ne renvoyez pas. Définissez cette règle de déduplication côté base de données.
Conclusion
Ce tutoriel couvre l'implémentation complète d'une enquête de satisfaction WhatsApp : template avec boutons de note, envoi déclenché par événement, webhook de réponse, relance verbatim et stockage des scores. L'architecture est reproductible pour chaque nouveau client via l'embedded signup Whakup.
Pour choisir le bon niveau d'accès API selon votre volume, consultez la page API WhatsApp de Whakup. Pour une vue sur les tarifs, l'article sur les prix de l'API WhatsApp Business en 2026 détaille les coûts par catégorie et par pays. Pour comprendre l'offre Whakup en tant que Meta Tech Provider, lisez la page Meta Tech Provider WhatsApp.

Head of Growth chez Whakup, Stéphane pilote la stratégie d'acquisition et les partenariats en Afrique francophone. Expert en marketing digital et expansion marché.
Prêt à passer à l'action ?
Essayez Whakup gratuitement pendant 15 jours. Aucune carte bancaire requise.
Démarrer l'essai gratuitArticles similaires
WhatsApp pour les alertes de sécurité via l'API : tutoriel pour les éditeurs
Tutoriel pas-à-pas pour envoyer vos premières alertes de sécurité WhatsApp via l'API Business : configuration, template AUTHENTICATION, webhooks et test en sandbox pour éditeurs SaaS.
WhatsApp pour les enquêtes de satisfaction via l'API : cas pratique pour les éditeurs
Découvrez comment intégrer une enquête satisfaction WhatsApp via l'API Business : architecture, templates, logique de scoring et retour d'expérience concret pour les éditeurs.
WhatsApp pour les enquêtes de satisfaction via l'API : FAQ pour les éditeurs
Toutes les questions que se posent les éditeurs avant d'intégrer une enquête satisfaction WhatsApp via l'API Business : opt-in, templates, coûts, limites et conformité RGPD.