# Authentification et clés

> Clés API, session de la console, portées, environnements et bonnes pratiques de sécurité.

## 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](/docs/api) 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](/docs/api/logs), 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é

<ApiExample method="POST" path="/apps/{appId}/keys" />

<Callout type="warning" title="Le secret n'est affiché qu'une seule fois">
Seule une empreinte irréversible est conservée. En cas de perte, créez une nouvelle clé et révoquez l'ancienne. La liste des clés n'affiche que leur **préfixe** (`prefix`) pour les reconnaître.
</Callout>

## 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`) |

<Callout type="tip" title="Moindre privilège">
Donnez à chaque service **seulement** les portées dont il a besoin : le serveur qui envoie des rappels n'a pas besoin de `webhooks:manage`.
</Callout>

## 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](/docs/guides/sandbox) refuse les clés de production (`403 sandbox_only`).
- Le bac à sable n'est ni limité, ni facturé.

## Utiliser une clé

```bash
curl "$INBOX_API/messages" -H "Authorization: Bearer $INBOX_KEY"
```

Une clé absente, invalide ou révoquée donne `401 unauthorized`.

<ErrorExample name="unauthorized" />

## Lister et révoquer

<ApiExample method="GET" path="/apps/{appId}/keys" />

`lastUsedAt` indique la dernière utilisation : une clé jamais utilisée depuis des semaines est une bonne candidate à la révocation.

<ApiExample method="DELETE" path="/apps/{appId}/keys/{keyId}" />

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 `lastUsedAt` de l'ancienne ne bouge plus, puis révoquez-la.
- Surveillez le [journal des appels](/docs/api/logs) : chaque appel y apparaît avec son statut et son `requestId`.

<Callout type="note" title="Secret de webhook">
Le secret `whsec_…` d'une destination de webhook est **différent** d'une clé API : il sert uniquement à vérifier la signature des événements que nous vous envoyons. Voir [Webhooks](/docs/guides/webhooks).
</Callout>
