Clés API
Une clé API authentifie vos appels serveur à serveur (POST /v1/emails). Elle est distincte de la session de votre compte, utilisée par le tableau de bord pour gérer domaines, clés et facturation.
Créer une clé
Depuis le tableau de bord, Clés API → Nouvelle clé, donnez-lui un nom qui vous aidera à la reconnaître plus tard (ex. « Serveur de production », « Script de test »). La clé complète a la forme suivante :
zd_live_9fQ2mR7xL0pK4wT8nB1vD6sH3jY5cZ2aE9uI7oP4rN8
Utilisez-la dans l’en-tête Authorization de vos appels à l’API :
Authorization: Bearer zd_live_9fQ2mR7xL0pK4wT8nB1vD6sH3jY5cZ2aE9uI7oP4rN8
Portée par domaine
À la création, vous choisissez les domaines depuis lesquels la clé peut envoyer :
- ✓Tous les domaines vérifiés (par défaut) : la clé peut envoyer depuis n’importe quel domaine vérifié de votre compte, y compris ceux que vous vérifierez plus tard.
- ✓Domaines choisis : un ou plusieurs domaines vérifiés de votre compte. La clé ne peut envoyer que depuis ceux-là. Une clé qui fuite n’expose alors que ces domaines.
La portée est fixée à la création et ne peut plus être modifiée : pour la changer, créez une nouvelle clé et révoquez l’ancienne. La réinitialisation (rotation) d’une clé conserve sa portée. Côté API, POST /v1/api-keys accepte un champ optionnel domainIds (liste d’identifiants de domaines vérifiés, sans doublon) ; absent ou vide, la portée est « tous les domaines ». La réponse et la liste des clés renvoient domainScope (ALL ou SELECTED) et domains (id et name).
Envoi hors de la portée
Si l’adresse from appartient à un domaine que la clé n’est pas autorisée à utiliser, l’API répond 403 avec le code CREDENTIAL_DOMAIN_OUT_OF_SCOPE et un message qui nomme les domaines autorisés :
{
"message": "Cette clé API n'est autorisée que pour le domaine boutique-awa.gn.",
"error": "Forbidden",
"statusCode": 403,
"code": "CREDENTIAL_DOMAIN_OUT_OF_SCOPE",
"errors": [
"Cette clé API n'est autorisée que pour le domaine boutique-awa.gn."
]
}Avec plusieurs domaines, le message devient « Cette clé API n’est autorisée que pour les domaines A, B. ».
Une clé dont tous les domaines ont disparu n’est autorisée pour aucun domaine : tout envoi est refusé avec le même code 403, et le message « Cette clé API n’est autorisée pour aucun domaine : créez-en une nouvelle avec la portée voulue. ». Une sélection est limitée à 50 domaines : au-delà, la création est refusée avec un 400 et le message « Une portée ne peut pas contenir plus de 50 domaines ».
Le bac à sable reste permis
Supprimer un domaine
Avant de supprimer un domaine, le tableau de bord liste les clés API et identifiants SMTP qui lui sont liés. Une clé dont c’est le dernier domaine est révoquée à la suppression (jamais élargie à d’autres domaines) ; une clé qui garde d’autres domaines continue de fonctionner pour ceux-là. Après la suppression, le tableau de bord affiche ce qui a été révoqué.
Permission de lecture
Par défaut, une clé sert à envoyer des emails et à lire le solde. À la création, vous pouvez en plus cocher « Autoriser la lecture », par exemple pour le serveur MCP ou un tableau de bord interne. Côté API, POST /v1/api-keys accepte un champ optionnel canRead (booléen, false par défaut). La réponse de création et la liste des clés renvoient canRead.
Ce réglage est immuable, comme la portée : il ne peut pas être modifié après la création, mais la réinitialisation (rotation) le conserve. Pour changer, créez une nouvelle clé et révoquez l’ancienne.
Routes lisibles par une clé avec lecture
| Endpoint | Description |
|---|---|
| GET /v1/emails | Journal des envois, avec filtres et pagination. |
| GET /v1/emails/:publicId | Détail et état de livraison d’un email. |
| GET /v1/domains | Domaines du compte et leur statut. |
| GET /v1/domains/:id | Statut d’un domaine et enregistrements DNS à créer. |
La lecture est limitée à la portée par domaine de la clé : les listes sont filtrées, total et la pagination ne comptent que les éléments de la portée, et un détail hors portée répond 404.
Clé sans permission de lecture
Sur ces quatre routes, une clé créée sans lecture reçoit un 403 :
{
"message": "Cette clé API n'a pas l'autorisation de lecture : créez une clé avec la lecture autorisée.",
"error": "Forbidden",
"statusCode": 403,
"errors": [
"Cette clé API n'a pas l'autorisation de lecture : créez une clé avec la lecture autorisée."
]
}Le solde reste lisible par toute clé
GET /v1/billing/balance ne demande pas la permission de lecture : toute clé active peut lire le solde.Une clé avec lecture expose des données
Affichage unique
La clé complète n’apparaît qu’au moment de sa création. Une fois l’écran quitté, seul son préfixe (les 12 premiers caractères, ex. zd_live_9fQ2) reste visible dans la liste - suffisant pour identifier une clé, jamais pour l’utiliser. Zendou ne stocke que l’empreinte de la clé, jamais la clé en clair : si vous la perdez, il n’y a aucun moyen de la récupérer, seulement d’en créer une nouvelle.
Copiez-la avant de fermer l'écran
Stockage sûr
Une clé API donne un accès direct à l’envoi d’emails - traitez-la comme un mot de passe.
- ✓Stockez-la dans des variables d’environnement (
.env, secret manager, variables d’environnement de votre plateforme de déploiement) - jamais en dur dans le code source. - ✓Ne la committez jamais dans le dépôt Git, y compris dans l’historique - un secret poussé une seule fois doit être considéré comme compromis et révoqué.
- ✓N’appelez jamais
POST /v1/emailsdepuis du code exécuté dans le navigateur : la clé serait visible dans le code source livré au client. Passez toujours par votre serveur. - ✓Ajoutez
.envà votre.gitignoreavant d’y écrire la moindre clé.
Une clé par environnement
Créez une clé distincte pour chaque environnement (production, tests, script local) plutôt que de réutiliser la même partout. Ainsi, une fuite en environnement de test n’expose pas la production, et révoquer une clé compromise n’interrompt pas les autres.
Lire son solde avec une clé
Une clé API permet aussi de lire le solde de crédits du compte avec GET /v1/billing/balance (toute clé active suffit, quelle que soit sa portée par domaine). Voir Facturation pour la réponse et un exemple.
Révocation
Depuis la liste des clés, « Révoquer » désactive la clé immédiatement et définitivement - l’action est irréversible. Toute requête authentifiée avec une clé révoquée répond 401, avec le message « Clé API invalide ou révoquée ». Révoquer une clé n’affecte pas les emails déjà en file ou déjà envoyés avec.
| Endpoint | Description |
|---|---|
| POST /v1/api-keys | Crée une clé. Corps : { name, domainIds?, canRead? }. La clé complète n’est renvoyée que dans cette réponse, avec sa portée (domainScope, domains) et canRead. |
| GET /v1/api-keys | Liste vos clés (nom, préfixe, dates, statut, portée, lecture) - jamais la clé complète. |
| DELETE /v1/api-keys/:id | Révoque la clé. |
Ces trois endpoints sont authentifiés par la session du tableau de bord (cookie), pas par une clé API - c’est elle qui les gère, pas l’inverse.
Voir aussi Erreurs pour le détail des réponses 401 et 403.