Démarrer

Démarrage rapide

Créez un compte, générez une clé de bac à sable, déclarez un webhook et envoyez votre premier message en quelques minutes.

Mis à jour le 12 novembre 2026Voir en Markdown

Ce parcours utilise le bac à sable : rien n'est facturé et aucun vrai destinataire n'est contacté. Les exemples s'exécutent dans votre terminal ; chaque bloc existe en curl, Node.js, Python et PHP (votre choix de langage est mémorisé).

Définissez d'abord l'adresse de l'API :

bash
export INBOX_API="https://VOTRE-HOTE/api/v1"

Créez votre compte#

La création d'un compte crée aussi son premier membre (propriétaire) et ouvre une session.

bash
curl -X POST "$INBOX_API/auth/signup" \
  -H "Content-Type: application/json" \
  -d '{
    "accountName": "Acme Software",
    "email": "dev@acme.com",
    "password": "un-mot-de-passe-solide"
  }'
Réponse · 201 Created
{
  "accountId": "bbfa1ecb-9483-4158-8e9a-4437e512b14b",
  "memberId": "e8878e87-7817-4773-8346-fc26a2433aa6",
  "sessionToken": "ses_91bb0d22558b4575a110844d944cca5d8b05e72328b",
  "expiresAt": "2026-12-12T08:33:45.098Z"
}

Le mot de passe doit contenir 10 caractères au minimum. Conservez le sessionToken : c'est la clé de la console, valable 30 jours.

bash
export INBOX_SESSION="ses_…"

Créez une application#

Une application a deux environnements : sandbox pour tester et production pour envoyer à de vrais destinataires. Ils sont strictement séparés.

bash
curl -X POST "$INBOX_API/apps" \
  -H "Authorization: Bearer $INBOX_SESSION" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Mon CRM"
  }'
Réponse · 201 Created
{
  "id": "8b2717b6-be9e-42c7-8889-6e3c6ea4cbe3",
  "name": "Mon CRM",
  "createdAt": "2026-11-12T08:33:45.324Z",
  "environments": [
    {
      "id": "7d3d2aa8-d312-48d7-894c-25b906dfa11a",
      "kind": "sandbox"
    },
    {
      "id": "badd0f25-05da-4716-8c28-f2fe1baba427",
      "kind": "production"
    }
  ]
}

Générez une clé de sandbox#

Choisissez ses portées : une clé ne peut faire que ce que vous lui accordez.

bash
curl -X POST "$INBOX_API/apps/APP_ID/keys" \
  -H "Authorization: Bearer $INBOX_SESSION" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Dev local",
    "environment": "sandbox",
    "scopes": [
      "messages:send",
      "messages:read",
      "connections:manage",
      "connections:read",
      "templates:manage",
      "webhooks:manage",
      "usage:read"
    ]
  }'
Réponse · 201 Created
{
  "id": "5ef37bc9-8aac-43ef-81b1-6bb3bdb66e78",
  "name": "Dev local",
  "prefix": "pk_test_bwcA3X-A",
  "environment": "sandbox",
  "scopes": [
    "messages:send",
    "messages:read",
    "connections:manage",
    "connections:read",
    "templates:manage",
    "webhooks:manage",
    "usage:read"
  ],
  "lastUsedAt": null,
  "revokedAt": null,
  "createdAt": "2026-11-12T08:33:45.382Z",
  "secret": "pk_test_26f602c48c47ef280792fd3a506473688df70b80118"
}
bash
export INBOX_KEY="pk_test_…"

Déclarez l'entreprise de votre client#

Une entreprise connectée représente votre client, propriétaire d'un compte WhatsApp Business. externalRef est votre propre identifiant de ce client.

bash
curl -X POST "$INBOX_API/connected-businesses" \
  -H "Authorization: Bearer $INBOX_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Cabinet Dentaire Zokem",
    "externalRef": "client-42"
  }'
Réponse · 201 Created
{
  "id": "39e2803f-79e7-4e99-8da0-1c15991f5985",
  "name": "Cabinet Dentaire Zokem",
  "externalRef": "client-42",
  "createdAt": "2026-11-12T08:33:45.469Z"
}

Connectez son compte WhatsApp#

Votre client termine l'inscription intégrée de Meta dans le navigateur ; vous recevez un code, un wabaId et un phoneNumberId que vous transmettez à l'API. Voir Connecter un compte WhatsApp.

bash
curl -X POST "$INBOX_API/connected-businesses/BUSINESS_ID/waba-connections" \
  -H "Authorization: Bearer $INBOX_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "AQBx7…",
    "wabaId": "102290129340398",
    "phoneNumberId": "106540352242922",
    "mode": "cloud_api"
  }'
Réponse · 201 Created
{
  "id": "b76a1f98-53d6-4078-8d28-6406482daabb",
  "wabaId": "102290129340398",
  "status": "active",
  "mode": "cloud_api",
  "phoneNumber": {
    "id": "4d8e654e-d744-4bf3-8211-9ceffcccfe87",
    "phoneNumberId": "106540352242922",
    "displayNumber": "+237 6 52242922",
    "verifiedName": "Cabinet Test",
    "qualityRating": "GREEN"
  }
}

Notez l'id du numéro (phoneNumber.id) : c'est lui qui désigne le numéro d'envoi.

Recevez les événements#

Déclarez la destination de vos webhooks. Le secret de signature n'est affiché qu'une fois.

bash
curl -X POST "$INBOX_API/webhook-endpoints" \
  -H "Authorization: Bearer $INBOX_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://api.exemple.com/webhooks/inbox",
    "events": [
      "message.received",
      "message.delivered",
      "message.failed"
    ]
  }'
Réponse · 201 Created
{
  "id": "bc06ae32-7564-46d5-89fb-a9869019aa8e",
  "url": "https://api.exemple.com/webhooks/inbox",
  "events": [
    "message.received",
    "message.delivered",
    "message.failed"
  ],
  "status": "active",
  "consecutiveFailures": 0,
  "disabledReason": null,
  "createdAt": "2026-11-12T08:33:45.704Z",
  "secret": "whsec_b4ac869893324714f88bfd25026b3e2e2891bb8c087"
}

Vérifiez que votre serveur répond bien, avec un événement de test signé :

bash
curl -X POST "$INBOX_API/webhook-endpoints/ID/test" \
  -H "Authorization: Bearer $INBOX_KEY"
Réponse · 200 OK
{
  "ok": true,
  "statusCode": 200,
  "durationMs": 3,
  "error": null
}

Envoyez votre premier message#

bash
curl -X POST "$INBOX_API/messages" \
  -H "Authorization: Bearer $INBOX_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: rdv-2026-11-14-client-42" \
  -d '{
    "phoneNumberId": "4d8e654e-d744-4bf3-8211-9ceffcccfe87",
    "to": "+237600000000",
    "type": "template",
    "template": {
      "name": "rappel_rdv",
      "language": "fr",
      "components": [
        {
          "type": "body",
          "parameters": [
            {
              "type": "text",
              "text": "Awa"
            },
            {
              "type": "text",
              "text": "14 novembre à 10 h"
            }
          ]
        }
      ]
    }
  }'
Réponse · 202 Accepted
{
  "id": "d5ad1e3e-6ab9-4f7f-8e4e-b17104a7bd00",
  "direction": "outbound",
  "status": "queued",
  "type": "template",
  "phoneNumberId": "4d8e654e-d744-4bf3-8211-9ceffcccfe87",
  "to": "237600000000",
  "waMessageId": null,
  "content": {
    "type": "template",
    "template": {
      "name": "rappel_rdv",
      "language": "fr",
      "components": [
        {
          "type": "body",
          "parameters": [
            {
              "type": "text",
              "text": "Awa"
            },
            {
              "type": "text",
              "text": "14 novembre à 10 h"
            }
          ]
        }
      ]
    }
  },
  "error": null,
  "createdAt": "2026-11-12T08:33:45.855Z",
  "sentAt": null,
  "deliveredAt": null,
  "readAt": null
}

La réponse est immédiate (202, statut queued) : l'envoi réel est asynchrone. Suivez le statut avec GET /messages/{id} ou, mieux, avec vos webhooks.

Simulez une réponse du client#

Sans téléphone, faites « arriver » un message : votre webhook message.received se déclenche exactement comme en production.

bash
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"
  }'
Réponse · 201 Created
{
  "messageId": "3f3baf5a-f93e-42e8-8263-ce62dc4aadd6",
  "from": "237611111111",
  "status": "received",
  "simulated": true
}

Et ensuite#