Guides
Tester avec le bac à sable
Un environnement séparé, gratuit et illimité, avec un simulateur pour tester vos webhooks sans numéro WhatsApp.
Mis à jour le 12 novembre 2026Voir en Markdown
Chaque application a un environnement sandbox, strictement séparé de la production : ses propres clés (pk_test_…), entreprises, numéros, webhooks et données.
| Sandbox | Production | |
|---|---|---|
| Clés | pk_test_… | pk_live_… |
| Limites de quota et de nombre d'entreprises | Aucune | Celles de votre plan |
| Facturation Bref Point Inbox | Aucune | Selon votre plan |
| Simulateur | Oui | Refusé (403 sandbox_only) |
Simuler un message reçu#
Idéal pour tester votre réception de bout en bout : le message est enregistré, la fenêtre de 24 heures s'ouvre pour cet expéditeur, et votre webhook message.received se déclenche exactement comme en production (les données portent "simulated": true).
curl -X POST "$INBOX_API/sandbox/simulate/inbound-message" \
-H "Authorization: Bearer $INBOX_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumberId": "4d8e654e-d744-4bf3-8211-9ceffcccfe87",
"from": "+237611111111",
"text": "Bonjour, je voudrais déplacer mon rendez-vous"
}'const res = await fetch(`${process.env.INBOX_API}/sandbox/simulate/inbound-message`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.INBOX_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"phoneNumberId": "4d8e654e-d744-4bf3-8211-9ceffcccfe87",
"from": "+237611111111",
"text": "Bonjour, je voudrais déplacer mon rendez-vous"
}),
});
const data = await res.json();import os
import requests
res = requests.post(
f"{os.environ['INBOX_API']}/sandbox/simulate/inbound-message",
headers={
"Authorization": f"Bearer {os.environ['INBOX_KEY']}",
},
json={
"phoneNumberId": "4d8e654e-d744-4bf3-8211-9ceffcccfe87",
"from": "+237611111111",
"text": "Bonjour, je voudrais déplacer mon rendez-vous",
},
)
print(res.json())<?php
$ch = curl_init(getenv('INBOX_API') . '/sandbox/simulate/inbound-message');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('INBOX_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'phoneNumberId' => '4d8e654e-d744-4bf3-8211-9ceffcccfe87',
'from' => '+237611111111',
'text' => 'Bonjour, je voudrais déplacer mon rendez-vous',
]),
]);
$data = json_decode(curl_exec($ch), true);{
"messageId": "3f3baf5a-f93e-42e8-8263-ce62dc4aadd6",
"from": "237611111111",
"status": "received",
"simulated": true
}Faire avancer le statut d'un message#
Après un envoi (POST /messages), faites évoluer le message comme le ferait Meta :
curl -X POST "$INBOX_API/sandbox/simulate/message-status" \
-H "Authorization: Bearer $INBOX_KEY" \
-H "Content-Type: application/json" \
-d '{
"messageId": "d5ad1e3e-6ab9-4f7f-8e4e-b17104a7bd00",
"status": "delivered"
}'const res = await fetch(`${process.env.INBOX_API}/sandbox/simulate/message-status`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.INBOX_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"messageId": "d5ad1e3e-6ab9-4f7f-8e4e-b17104a7bd00",
"status": "delivered"
}),
});
const data = await res.json();import os
import requests
res = requests.post(
f"{os.environ['INBOX_API']}/sandbox/simulate/message-status",
headers={
"Authorization": f"Bearer {os.environ['INBOX_KEY']}",
},
json={
"messageId": "d5ad1e3e-6ab9-4f7f-8e4e-b17104a7bd00",
"status": "delivered",
},
)
print(res.json())<?php
$ch = curl_init(getenv('INBOX_API') . '/sandbox/simulate/message-status');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('INBOX_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'messageId' => 'd5ad1e3e-6ab9-4f7f-8e4e-b17104a7bd00',
'status' => 'delivered',
]),
]);
$data = json_decode(curl_exec($ch), true);{
"messageId": "d5ad1e3e-6ab9-4f7f-8e4e-b17104a7bd00",
"status": "delivered",
"simulated": true
}Les mêmes règles qu'en production s'appliquent : un statut ne recule jamais, et un failed ne remplace pas un message déjà read. Une transition sans effet répond simplement avec l'état actuel.
Un scénario complet#
- Connectez un numéro dans le sandbox et déclarez un webhook sur
*(Démarrage rapide). POST /sandbox/simulate/inbound-message: votre serveur reçoitmessage.received.- Répondez avec
POST /messages(message libre, la fenêtre est ouverte). POST /sandbox/simulate/message-statusavecdelivered, puisread: vous recevez les événements correspondants.- Provoquez une panne chez vous (réponse
500) et observez les reprises dansGET /webhook-deliveries. - Quand tout est bon, créez une clé de production et reprenez les mêmes appels.