RÉFÉRENCE API

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

L’adresse d’expédition de test de votre compte reste utilisable avec toute clé, quelle que soit sa portée, avec la restriction habituelle : vous ne pouvez écrire qu’à l’adresse email de votre compte.

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

EndpointDescription
GET /v1/emailsJournal des envois, avec filtres et pagination.
GET /v1/emails/:publicIdDétail et état de livraison d’un email.
GET /v1/domainsDomaines du compte et leur statut.
GET /v1/domains/:idStatut 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

Si une clé avec lecture fuit, les destinataires et les sujets des envois de sa portée sont exposés. Activez la lecture seulement si vous en avez besoin, et limitez la portée aux domaines utiles.

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

Une fois quitté, l’écran de création ne réaffichera plus jamais la clé complète. Si vous la perdez, révoquez-la et créez-en une nouvelle.

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/emails depuis 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 .gitignore avant 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.

EndpointDescription
POST /v1/api-keysCré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-keysListe vos clés (nom, préfixe, dates, statut, portée, lecture) - jamais la clé complète.
DELETE /v1/api-keys/:idRé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.