Guides
Connecter un compte WhatsApp
Faites connecter à vos clients leur compte WhatsApp Business par l'inscription intégrée de Meta, puis finalisez la connexion par l'API.
Mis à jour le 12 novembre 2026Voir en Markdown
Chacun de vos clients possède son propre compte WhatsApp Business. Vous le connectez à votre application en deux temps : le client autorise la connexion chez Meta (dans le navigateur), puis votre serveur finalise par l'API.
Le parcours#
1. Votre serveur POST /connected-businesses → crée l'entreprise de votre client
2. Le navigateur Inscription intégrée de Meta → le client autorise, Meta renvoie un code,
l'identifiant du compte WhatsApp et celui du numéro
3. Votre serveur POST …/waba-connections → échange le code, abonne les événements, lit le numéro
4. Votre serveur GET …/phone-numbers → vérifie : numéro, nom vérifié, qualitéCréez l'entreprise de votre client#
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"
}'const res = await fetch(`${process.env.INBOX_API}/connected-businesses`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.INBOX_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"name": "Cabinet Dentaire Zokem",
"externalRef": "client-42"
}),
});
const data = await res.json();import os
import requests
res = requests.post(
f"{os.environ['INBOX_API']}/connected-businesses",
headers={
"Authorization": f"Bearer {os.environ['INBOX_KEY']}",
},
json={
"name": "Cabinet Dentaire Zokem",
"externalRef": "client-42",
},
)
print(res.json())<?php
$ch = curl_init(getenv('INBOX_API') . '/connected-businesses');
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([
'name' => 'Cabinet Dentaire Zokem',
'externalRef' => 'client-42',
]),
]);
$data = json_decode(curl_exec($ch), true);{
"id": "39e2803f-79e7-4e99-8da0-1c15991f5985",
"name": "Cabinet Dentaire Zokem",
"externalRef": "client-42",
"createdAt": "2026-11-12T08:33:45.469Z"
}externalRef est votre propre identifiant de ce client : il doit être unique dans l'environnement et vous permet de retrouver l'entreprise plus tard.
Le client termine l'inscription chez Meta#
Dans le navigateur, votre client se connecte à Meta, choisit ou crée son compte WhatsApp Business et son numéro. À la fin, Meta fournit à votre page trois valeurs :
| Valeur | À quoi elle sert |
|---|---|
code | Échangé par nos serveurs contre le jeton d'accès du client. À usage unique et de courte durée : transmettez-le immédiatement. |
wabaId | Identifiant du compte WhatsApp Business (chiffres uniquement). |
phoneNumberId | Identifiant Meta du numéro (chiffres uniquement). |
Finalisez par l'API#
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"
}'const res = await fetch(`${process.env.INBOX_API}/connected-businesses/BUSINESS_ID/waba-connections`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.INBOX_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"code": "AQBx7…",
"wabaId": "102290129340398",
"phoneNumberId": "106540352242922",
"mode": "cloud_api"
}),
});
const data = await res.json();import os
import requests
res = requests.post(
f"{os.environ['INBOX_API']}/connected-businesses/BUSINESS_ID/waba-connections",
headers={
"Authorization": f"Bearer {os.environ['INBOX_KEY']}",
},
json={
"code": "AQBx7…",
"wabaId": "102290129340398",
"phoneNumberId": "106540352242922",
"mode": "cloud_api",
},
)
print(res.json())<?php
$ch = curl_init(getenv('INBOX_API') . '/connected-businesses/BUSINESS_ID/waba-connections');
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([
'code' => 'AQBx7…',
'wabaId' => '102290129340398',
'phoneNumberId' => '106540352242922',
'mode' => 'cloud_api',
]),
]);
$data = json_decode(curl_exec($ch), true);{
"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"
}
}Nous échangeons le code contre un jeton, abonnons l'application aux événements du compte, lisons les informations du numéro et enregistrons le tout. La réponse donne l'id de la connexion et celui du numéro (phoneNumber.id) : c'est cet identifiant que vous utiliserez pour envoyer des messages.
Vérifiez#
curl "$INBOX_API/connected-businesses/BUSINESS_ID/phone-numbers" \
-H "Authorization: Bearer $INBOX_KEY"const res = await fetch(`${process.env.INBOX_API}/connected-businesses/BUSINESS_ID/phone-numbers`, {
headers: {
Authorization: `Bearer ${process.env.INBOX_KEY}`,
},
});
const data = await res.json();import os
import requests
res = requests.get(
f"{os.environ['INBOX_API']}/connected-businesses/BUSINESS_ID/phone-numbers",
headers={
"Authorization": f"Bearer {os.environ['INBOX_KEY']}",
},
)
print(res.json())<?php
$ch = curl_init(getenv('INBOX_API') . '/connected-businesses/BUSINESS_ID/phone-numbers');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('INBOX_KEY'),
],
]);
$data = json_decode(curl_exec($ch), true);[
{
"id": "b76a1f98-53d6-4078-8d28-6406482daabb",
"wabaId": "102290129340398",
"status": "active",
"mode": "cloud_api",
"phoneNumbers": [
{
"id": "4d8e654e-d744-4bf3-8211-9ceffcccfe87",
"phoneNumberId": "106540352242922",
"displayNumber": "+237 6 52242922",
"verifiedName": "Cabinet Test",
"qualityRating": "GREEN"
}
]
}
]qualityRating est la note de qualité du numéro chez Meta (GREEN, YELLOW, RED) : surveillez-la, une mauvaise qualité réduit vos capacités d'envoi.
Le mode coexistence#
Avec "mode": "coexistence", votre client continue d'utiliser l'application WhatsApp Business sur son téléphone pendant que votre logiciel utilise l'API sur le même numéro. Les messages qu'il envoie depuis son téléphone arrivent chez vous comme les autres. Sans ce mode (cloud_api, par défaut), le numéro n'est utilisable que par l'API.
Plusieurs numéros pour une même entreprise#
Une entreprise peut avoir plusieurs comptes WhatsApp, et un compte plusieurs numéros. Pour ajouter un numéro, refaites l'inscription et appelez de nouveau POST …/waba-connections avec le même wabaId et le nouveau phoneNumberId : le compte est reconnu, son jeton rafraîchi et le numéro ajouté, sans doublon. Reconnecter un numéro déjà connecté n'en ajoute pas et ne compte pas dans la limite.
En production, votre plan limite les numéros par entreprise (1 en Gratuit, 2 en Starter, 3 en Growth, 5 en Scale). Le sandbox n'a pas de limite.
Ce qui est garanti#
- Le jeton Meta de votre client n'est jamais renvoyé par l'API, même chiffré. Il est stocké chiffré, lié à votre compte et à cette connexion.
- Un compte WhatsApp ne peut être connecté qu'une fois sur toute la plateforme. S'il l'est déjà ailleurs, vous obtenez
409 conflict. Cela empêche qu'un tiers détourne les messages d'un autre. - Reconnecter le même compte (jeton expiré, nouvelle autorisation) est possible : le jeton est remplacé, sans doublon de numéro.
- Une entreprise ne voit que son environnement : un compte connecté en sandbox n'existe pas en production.
Erreurs fréquentes#
| Erreur | Cause probable |
|---|---|
400 validation_error | wabaId ou phoneNumberId contient autre chose que des chiffres |
404 not_found | L'entreprise n'existe pas, ou appartient à un autre environnement que celui de la clé |
409 conflict | Ce compte WhatsApp est déjà connecté (à une autre entreprise ou à un autre compte) |
402 plan_limit_reached | Le plan de votre compte n'autorise pas plus d'entreprises connectées en production, ou plus de numéros pour cette entreprise. Le refus intervient avant l'échange du code d'inscription : le code n'est pas consommé |
502 meta_error | Meta a refusé la requête : le plus souvent, le code a expiré ou a déjà servi. Faites refaire l'inscription au client |