Tester l'API WhatsApp sans payer : existe-t-il un mode sandbox ou test ?

Non, il n'y a pas de sandbox : chaque template envoyé coûte des crédits. Mais vous pouvez tout tester à très bas coût : ping, lecture, création de templates et réponses dans les 24 h ne débitent rien ou presque, et un envoi refusé ne coûte rien.

Tester l'API WhatsApp sans payer : existe-t-il un mode sandbox ou test ?

Astuce
Non, il n'y a pas de sandbox : chaque template envoyé coûte des crédits. Mais vous pouvez tout tester à très bas coût : ping, lecture, création de templates et réponses dans les 24 h ne débitent rien ou presque, et un envoi refusé ne coûte rien.

Scénario

Vous intégrez l'API et vous voulez essayer vos appels avant de dépenser. Vous cherchez un mode « sandbox » ou « test ». Il n'y en a pas. Aucun drapeau ne bascule les envois en faux : un template envoyé part vraiment chez le destinataire et débite vraiment vos crédits. Un compte neuf démarre à zéro crédit, sans crédits d'essai offerts.

Ce que vous pouvez faire, c'est tester presque tout pour presque rien.

Ce qui ne coûte rien

AppelDébit
GET /v1/ping : la clé est-elle valable ?Aucun
GET /v1/balance, /v1/pricing, /v1/numbers, /v1/templates, /v1/logsAucun
POST /v1/templates : créer un template (et le voir approuvé ou refusé)Aucun chez Geskap
GET /v1/messages/inbound : relire les messages reçusAucun
Un envoi refusé avant le débit (variable manquante, template non approuvé, mauvais from)Aucun
Un envoi que Meta refuse (502)Remboursé

Le parcours de test le moins cher

1. GET /v1/ping                       la clé marche
2. POST /v1/templates                 créez votre template, attendez APPROVED (aucun débit)
3. Depuis VOTRE téléphone, écrivez au numéro connecté
                                      → un message.inbound arrive sur votre webhook, la fenêtre de 24 h s'ouvre
4. POST /v1/messages/reply            répondez dans les 24 h (tarif réduit)
5. POST /v1/messages/interactive      testez boutons et listes dans la même fenêtre
6. POST /v1/messages (template)       un seul envoi, vers un numéro que vous contrôlez

curl

curl -X GET "https://wa-api.geskap.com/v1/ping" \
  -H "Authorization: Bearer $GESKAP_API_KEY"

Node.js

const res = await fetch("https://wa-api.geskap.com/v1/ping", {
  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/ping");
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/ping",
    headers={"Authorization": f"Bearer {os.environ['GESKAP_API_KEY']}"},
    timeout=15,
)
print(res.status_code, res.json())

Les étapes 4 et 5 utilisent la réponse libre : son tarif est de 1 crédit pour 4 messages par défaut, et son débit ne bloque jamais, même à solde nul (il charge 0 si le solde ne suffit pas). Vous pouvez donc tester toute une conversation, boutons compris, sans avoir acheté de crédits. Voir Coût d'un message.

Tester l'envoi d'un template au moindre coût

L'étape 6 est la seule qui coûte vraiment. Lisez d'abord le prix : GET /v1/pricing, puis le plus petit pack : GET /v1/credits/packs. Envoyez une fois, à un numéro que vous contrôlez, avec une idempotency_key : si votre test se rejoue, rien n'est renvoyé ni redébité (voir Ne jamais envoyer deux fois).

curl

curl -X POST "https://wa-api.geskap.com/v1/messages" \
  -H "Authorization: Bearer $GESKAP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "to": "+237690000001",
  "idempotency_key": "test-001",
  "template": {
    "name": "rappel_rdv",
    "language": "fr",
    "variables": ["Awa", "demain 9 h"]
  }
}'

Node.js

const res = await fetch("https://wa-api.geskap.com/v1/messages", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.GESKAP_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "to": "+237690000001",
    "idempotency_key": "test-001",
    "template": {
      "name": "rappel_rdv",
      "language": "fr",
      "variables": ["Awa", "demain 9 h"]
    }
  }),
});
console.log(res.status, await res.json());

PHP

$ch = curl_init("https://wa-api.geskap.com/v1/messages");
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer " . getenv("GESKAP_API_KEY"),
    "Content-Type: application/json",
  ],
  CURLOPT_POSTFIELDS => json_encode([
    "to" => "+237690000001",
    "idempotency_key" => "test-001",
    "template" => [
      "name" => "rappel_rdv",
      "language" => "fr",
      "variables" => ["Awa", "demain 9 h"],
    ],
  ]),
]);
$res = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), " ", $res;

Python

import os, requests

res = requests.request(
    "POST",
    "https://wa-api.geskap.com/v1/messages",
    headers={"Authorization": f"Bearer {os.environ['GESKAP_API_KEY']}"},
    json={
        "to": "+237690000001",
        "idempotency_key": "test-001",
        "template": {
            "name": "rappel_rdv",
            "language": "fr",
            "variables": ["Awa", "demain 9 h"],
        },
    },
    timeout=15,
)
print(res.status_code, res.json())

Meta peut aussi facturer l'envoi sur votre compte Meta : voir Coût d'un message.

Tester votre webhook

Il n'y a pas d'événement de test fabriqué par l'API. Deux moyens :

GET /v1/logs?category=webhook montre la réponse de votre serveur à chaque message.inbound tenté.

Outils

La collection Postman (GET /v1/postman.json, sans clé) charge tous les appels. Pour un test sans risque pour la production, créez une clé dédiée aux essais (voir Clé API restreinte) et révoquez-la après.

Attention
Piège : « pas de sandbox » veut dire que chaque template envoyé est réel : il part chez le destinataire. Ne testez jamais avec une liste de vrais clients.
Attention
Piège : la réponse libre ne marche que si le numéro de test vous a écrit dans les dernières 24 h. Sinon : 400 « Hors de la fenêtre de 24h ». Écrivez-lui d'abord depuis votre téléphone.
Attention
Piège : un compte à zéro crédit peut tester les réponses libres, mais pas les templates : ils répondent 402 « Solde de crédits insuffisant ».

Preuve — vérifié dans le code de l'API : public_api.py, console_api.py, api_send.py, api_credits.py, dev_api_docs.py.