Démarrer
Authentification et clés
Clés API, session de la console, portées, environnements et bonnes pratiques de sécurité.
Mis à jour le 12 novembre 2026Voir en Markdown
Deux sortes d'identifiants#
| Session de la console | Clé API | |
|---|---|---|
| Forme | ses_… | pk_test_… (sandbox) ou pk_live_… (production) |
| Sert à | Gérer votre compte : applications, clés, facturation, journaux | Appeler l'API depuis votre serveur : connexions, messages, templates, webhooks, usage |
| Obtenue par | POST /auth/signup ou POST /auth/login | POST /apps/{appId}/keys |
| Durée | 30 jours, révocable (POST /auth/logout) | Jusqu'à révocation |
| En-tête | Authorization: Bearer ses_… | Authorization: Bearer pk_… |
Les routes de la section « Authentification », « Applications », GET /billing/overview et GET /logs/requests utilisent la session. Toutes les autres utilisent une clé API. Chaque page de la référence indique son mode d'authentification.
La console utilise les mêmes routes#
Les routes de l'API à clé (connexions, messages, templates, webhooks, usage) acceptent aussi la session de la console, avec un en-tête X-Environment-Id qui désigne l'environnement visé (l'identifiant d'un environnement est renvoyé par GET /apps). Le membre connecté a alors toutes les portées de son compte. C'est ce que fait la console de Bref Point Inbox. Ces appels ne figurent pas dans le journal des appels, réservé aux clés API.
Pour un usage depuis votre serveur, utilisez toujours une clé : elle limite ses droits par portée et son environnement est fixé.
Créer une clé#
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"
]
}'const res = await fetch(`${process.env.INBOX_API}/apps/APP_ID/keys`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.INBOX_SESSION}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"name": "Dev local",
"environment": "sandbox",
"scopes": [
"messages:send",
"messages:read",
"connections:manage",
"connections:read",
"templates:manage",
"webhooks:manage",
"usage:read"
]
}),
});
const data = await res.json();import os
import requests
res = requests.post(
f"{os.environ['INBOX_API']}/apps/APP_ID/keys",
headers={
"Authorization": f"Bearer {os.environ['INBOX_SESSION']}",
},
json={
"name": "Dev local",
"environment": "sandbox",
"scopes": [
"messages:send",
"messages:read",
"connections:manage",
"connections:read",
"templates:manage",
"webhooks:manage",
"usage:read",
],
},
)
print(res.json())<?php
$ch = curl_init(getenv('INBOX_API') . '/apps/APP_ID/keys');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('INBOX_SESSION'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Dev local',
'environment' => 'sandbox',
'scopes' => [
'messages:send',
'messages:read',
'connections:manage',
'connections:read',
'templates:manage',
'webhooks:manage',
'usage:read',
],
]),
]);
$data = json_decode(curl_exec($ch), true);{
"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"
}Les portées#
Une clé ne peut faire que ce que vous lui accordez. Un appel qui exige une portée absente de la clé est refusé avec 403 forbidden, et le message nomme la portée manquante.
| Portée | Autorise |
|---|---|
messages:send | Envoyer des messages (POST /messages) et utiliser le simulateur du bac à sable |
messages:read | Lire un message ou l'historique (GET /messages) |
connections:manage | Créer des entreprises connectées et connecter des comptes WhatsApp |
connections:read | Lister les entreprises connectées, leurs comptes et leurs numéros |
templates:manage | Créer, lister, synchroniser et supprimer des templates |
webhooks:manage | Gérer les destinations de webhooks et consulter/rejouer les livraisons |
usage:read | Lire la consommation (GET /usage) |
Les environnements#
Chaque application a un environnement sandbox et un environnement production. Une clé appartient à un seul environnement et ne voit que ses données : entreprises connectées, numéros, messages, destinations de webhooks.
- Une clé
pk_test_…ne peut jamais toucher la production, et inversement. - Le simulateur du bac à sable refuse les clés de production (
403 sandbox_only). - Le bac à sable n'est ni limité, ni facturé.
Utiliser une clé#
curl "$INBOX_API/messages" -H "Authorization: Bearer $INBOX_KEY"Une clé absente, invalide ou révoquée donne 401 unauthorized.
{
"error": {
"code": "unauthorized",
"message": "Clé API requise (Authorization: Bearer pk_…)",
"requestId": "req_1c1b9300-f2d4-4387-88b8-7d66222d7497"
}
}Lister et révoquer#
curl "$INBOX_API/apps/APP_ID/keys" \
-H "Authorization: Bearer $INBOX_SESSION"const res = await fetch(`${process.env.INBOX_API}/apps/APP_ID/keys`, {
headers: {
Authorization: `Bearer ${process.env.INBOX_SESSION}`,
},
});
const data = await res.json();import os
import requests
res = requests.get(
f"{os.environ['INBOX_API']}/apps/APP_ID/keys",
headers={
"Authorization": f"Bearer {os.environ['INBOX_SESSION']}",
},
)
print(res.json())<?php
$ch = curl_init(getenv('INBOX_API') . '/apps/APP_ID/keys');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('INBOX_SESSION'),
],
]);
$data = json_decode(curl_exec($ch), true);[
{
"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"
}
]lastUsedAt indique la dernière utilisation : une clé jamais utilisée depuis des semaines est une bonne candidate à la révocation.
curl -X DELETE "$INBOX_API/apps/APP_ID/keys/KEY_ID" \
-H "Authorization: Bearer $INBOX_SESSION"const res = await fetch(`${process.env.INBOX_API}/apps/APP_ID/keys/KEY_ID`, {
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.INBOX_SESSION}`,
},
});
const data = res.status;import os
import requests
res = requests.delete(
f"{os.environ['INBOX_API']}/apps/APP_ID/keys/KEY_ID",
headers={
"Authorization": f"Bearer {os.environ['INBOX_SESSION']}",
},
)
print(res.status_code)<?php
$ch = curl_init(getenv('INBOX_API') . '/apps/APP_ID/keys/KEY_ID');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('INBOX_SESSION'),
],
]);
curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE);(aucun contenu)La révocation est immédiate et définitive.
Bonnes pratiques#
- Appelez l'API depuis votre serveur, jamais depuis un navigateur ou une application mobile. Une clé placée dans du code client est publique. L'API n'autorise d'ailleurs pas les appels depuis un navigateur (pas de CORS).
- Stockez les clés dans des variables d'environnement ou un gestionnaire de secrets, jamais dans le code source ni dans un dépôt.
- Utilisez une clé par service et par environnement : vous pourrez en révoquer une sans interrompre les autres.
- Tournez vos clés : créez la nouvelle, déployez-la, vérifiez que
lastUsedAtde l'ancienne ne bouge plus, puis révoquez-la. - Surveillez le journal des appels : chaque appel y apparaît avec son statut et son
requestId.