Une API JSON sur HTTPS. 32 points de terminaison, tous versionnés sous /v1. Dernière mise à jour 1 novembre 2026.
Chaque requête porte une clé d'API comme jeton bearer. Les clés sont créées sous Clés d'API et affichées une seule fois.
Authorization: Bearer zm_live_...
Une clé porte un ensemble de portées; une requête hors de celles-ci est refusée par un 403 insufficient_scope qui nomme la portée attendue.
| Portée | Permet |
|---|---|
email:messages.send | Envoyer du courrier. |
email:messages.read | Lire un message ou un destinataire. |
email:domains.read | Lister et inspecter les domaines d'envoi. |
email:domains.write | Ajouter, vérifier et retirer des domaines. |
email:suppressions.read | Lister les suppressions. |
email:suppressions.write | Ajouter, retirer et importer des suppressions. |
email:stats.read | Statistiques, quota et état d'envoi. |
email:webhooks.read | Lister les points de terminaison de webhooks. |
email:webhooks.write | Créer, modifier, supprimer et tester des points de terminaison. |
email:sandbox.write | Ajouter un destinataire de test vérifié en mode bac à sable. |
iam:users.read | Lister les membres de l'équipe et les invitations. |
iam:users.write | Inviter, changer un rôle, retirer un membre. |
403 et ne devez pas en conclure que les portées ne sont pas appliquées. Créez une nouvelle clé pour en obtenir une avec portées.Une erreur est du JSON avec un code machine stable et une phrase pour un humain. Faites correspondre sur error; message peut être reformulé ou traduit.
{
"error": "insufficient_scope",
"message": "This API key lacks the email:messages.send scope."
}
| Statut | Signifie |
|---|---|
| 200 | Succès. |
| 201 | Créé — domaine, suppression, point de terminaison ou invitation. |
| 401 | En-tête Authorization absent, mal formé ou inconnu. |
| 403 | insufficient_scope — la clé est valide mais n'a pas la portée requise. |
| 404 | not_found — aucun message, domaine, point de terminaison ou utilisateur sur ce compte. |
| 422 | La requête a été comprise et refusée. Voir le code d'erreur. |
| 429 | Débit limité, ou la limite d'envoi quotidienne du compte est atteinte. |
| 500 | Notre faute. Vous pouvez réessayer. |
Les codes possibles sur un 422 comprennent invalid_from, invalid_email, invalid_domain, invalid_url, subject_too_long, body_too_large, file_too_large, reserved_header, too_many_headers et duplicate_header. Quelques validations plus anciennes retournent error sous forme de phrase sans code; traitez une valeur error non reconnue comme un refus à ne pas réessayer tel quel.
List-Unsubscribe, Content-Type, From et tout ce qui commence par X-Zedmail-. Un retour chariot ou un saut de ligne dans une valeur d'en-tête est également refusé; nous ne nettoyons jamais pour envoyer quand même.Envoyez un en-tête Idempotency-Key et une nouvelle tentative de la même requête n'enverra pas un second message. Les clés sont mémorisées pendant 24 heures.
Idempotency-Key: order-18472-receipt
C'est une protection contre le double envoi, non un cache de réponses : une requête qui arrive pendant que la première est encore en vol est refusée plutôt que servie depuis un envoi inachevé.
| Limite | Valeur |
|---|---|
| Objet | 998 bytes |
| Corps HTML | 1 MB |
| Corps texte | 1 MB |
| Messages par lot | 50 |
| En-têtes personnalisés par message | 10 |
| Nom d'en-tête personnalisé | 64 bytes |
| Valeur d'en-tête personnalisé | 200 bytes |
| Tous les en-têtes personnalisés | 2048 bytes |
Une adresse par requête. Un 2xx signifie que nous avons accepté le message et en avons pris la responsabilité, non qu'il est arrivé — interrogez le message ou prenez un webhook pour cela.
| Méthode | Chemin | Portée | Fait |
|---|---|---|---|
| POST | /v1/email/send |
email:messages.send |
Envoyer un message. |
| POST | /v1/email/batch |
email:messages.send |
Jusqu'à 50 messages en une requête. Retourne un tableau results dans l'ordre d'envoi; un message invalide n'invalide pas les autres. |
| Champ | Type | Requis | Notes |
|---|---|---|---|
to |
string | oui | Adresse du destinataire. Une par requête; utilisez /v1/email/batch pour plusieurs. |
subject |
string | — | Jusqu'à 998 octets. |
html |
string | — | Corps HTML. Au moins un de html ou text est requis. |
text |
string | — | Corps en texte brut. Généré depuis html s'il est omis. |
reply_to |
string | — | Adresse de réponse. |
tags |
array | — | Vos propres étiquettes, retournées dans les webhooks et les statistiques. Privées — jamais mises sur le réseau. |
headers |
object | — | En-têtes personnalisés, nom/valeur. Les noms réservés sont refusés par un 422 plutôt qu'ignorés en silence. |
attachments |
array | — | Objets avec filename, content_type, content en base64, et éventuellement cid pour les images en ligne. |
language |
string | — | en ou fr. Définit la langue du pied de page que nous ajoutons. |
L'adresse from est définie sur la clé, non dans la requête : une clé divulguée ne peut donc pas envoyer au nom d'un autre.
# Envoyer un message curl -X POST https://zedmail.com/v1/email/send \ -H "Authorization: Bearer $ZEDMAIL_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: order-18472-receipt" \ -d '{ "to": "jane@example.com", "subject": "Your receipt", "html": "<p>Thank you.</p>", "tags": ["receipt"] }' => 200 { "status": "queued", "message_id": "msg_4f68af67910b67a097" }
/v1/email/{id} répond à « qu'est-il arrivé à ce message ». /v1/recipients/{email} répond à « cette personne l'a-t-elle reçu », ce que le premier ne peut pas, car celui qui demande a rarement un identifiant de message.
| Méthode | Chemin | Portée | Fait |
|---|---|---|---|
| GET | /v1/email/{id} |
email:messages.read |
Un message : état, horodatages, détail du rejet le cas échéant. |
| GET | /v1/recipients/{email} |
email:messages.read |
Tout ce qui est connu d'une adresse, du plus récent au plus ancien. Paramètres limit et offset. |
| État | Signifie |
|---|---|
queued | Accepté, en attente de remise au serveur de messagerie. Quelques secondes — facile à manquer en test. |
sent | Remis, en attente d'un résultat. L'état normal en transit, et celui que vous verrez le plus. Résolu en quelques secondes d'ordinaire, mais un serveur destinataire qui diffère sans cesse peut retenir un message ici jusqu'à trois jours — ne traitez pas sent comme un échec. |
delivered | Le serveur destinataire l'a accepté. Définitif. |
bounced | Refusé comme non livrable; le destinataire est supprimé. Définitif. |
blocked | Non envoyé, car le chiffrement du transport n'a pu être assuré. L'adresse reste valide et n'est jamais supprimée. Définitif, mais vous pouvez réessayer une fois leur serveur corrigé. |
complained | Le destinataire l'a marqué comme indésirable; il est supprimé. Définitif. |
Seuls les quatre derniers sont définitifs. blocked est celui qu'on oublie : le message n'a pas été envoyé parce que le chiffrement du transport n'a pu être établi, donc l'adresse reste bonne.
Une adresse supprimée est refusée avant toute tentative d'envoi. Les raisons sont bounce, complaint, unsubscribe, manual et soft_bounce_threshold. Un message blocked ne crée jamais de suppression — l'adresse reste valide.
| Méthode | Chemin | Portée | Fait |
|---|---|---|---|
| GET | /v1/suppressions |
email:suppressions.read |
Lister. Paramètres reason, page, per_page. |
| POST | /v1/suppressions |
email:suppressions.write |
Ajouter. email et reason. |
| DELETE | /v1/suppressions/{email} |
email:suppressions.write |
Retirer. Les plaintes et certaines lignes verrouillées sont réservées à l'opérateur et ne seront pas retirées. |
| POST | /v1/suppressions/import |
email:suppressions.write |
Importation en masse. |
Ces routes gèrent les points de terminaison. Les charges utiles, le schéma de signature et le calendrier des nouvelles tentatives sont documentés sur la page Webhooks de votre compte, où les exemples peuvent nommer vos propres points de terminaison et votre secret.
| Méthode | Chemin | Portée | Fait |
|---|---|---|---|
| GET | /v1/webhooks |
email:webhooks.read |
Lister les points de terminaison. |
| POST | /v1/webhooks |
email:webhooks.write |
Créer. url (HTTPS) et events. |
| PUT | /v1/webhooks/{id} |
email:webhooks.write |
Modifier url, events ou is_active. |
| DELETE | /v1/webhooks/{id} |
email:webhooks.write |
Supprimer. |
| POST | /v1/webhooks/{id}/test |
email:webhooks.write |
Envoyer une livraison de test à ce point de terminaison. |
Vous ne pouvez envoyer que depuis un domaine que vous avez vérifié. La vérification contrôle DKIM, SPF et DMARC comme un destinataire les lit.
| Méthode | Chemin | Portée | Fait |
|---|---|---|---|
| GET | /v1/domains |
email:domains.read |
Lister les domaines et leur état de vérification. |
| POST | /v1/domains |
email:domains.write |
Ajouter. domain. Retourne les enregistrements DNS à publier. |
| GET | /v1/domains/{id} |
email:domains.read |
Un domaine, avec chaque enregistrement et s'il résout actuellement. |
| POST | /v1/domains/{id}/verify |
email:domains.write |
Revérifier le DNS maintenant. |
| DELETE | /v1/domains/{id} |
email:domains.write |
Retirer. |
Les paramètres from et to acceptent AAAA-MM-JJ. Les trois routes /v1/account/* reprennent la forme de leurs équivalents chez Amazon SES, pour qu'une migration conserve ses appels existants.
| Méthode | Chemin | Portée | Fait |
|---|---|---|---|
| GET | /v1/stats |
email:stats.read |
Envoyés, livrés, rejetés, plaintes sur une période. |
| GET | /v1/stats/bounces |
email:stats.read |
Rejets, avec type et code. |
| GET | /v1/stats/complaints |
email:stats.read |
Plaintes. |
| GET | /v1/account/quota |
email:stats.read |
Limite d'envoi quotidienne et ce qu'il en reste. |
| GET | /v1/account/sending |
email:stats.read |
Si l'envoi est activé, en pause ou en bac à sable. |
| GET | /v1/account/statistics |
email:stats.read |
Compteurs glissants. |
Invitations et membres. Les routes /invites sont déclarées avant /{id} et les identifiants sont contraints en UUID, de sorte que le segment littéral invites ne peut jamais être lu comme un identifiant d'utilisateur.
| Méthode | Chemin | Portée | Fait |
|---|---|---|---|
| GET | /v1/users |
iam:users.read |
Lister les membres. |
| GET | /v1/users/{id} |
iam:users.read |
Un membre. |
| PATCH | /v1/users/{id} |
iam:users.write |
Changer un rôle. role. |
| DELETE | /v1/users/{id} |
iam:users.write |
Retirer un membre. |
| GET | /v1/users/invites |
iam:users.read |
Lister les invitations en cours. |
| POST | /v1/users/invites |
iam:users.write |
Inviter quelqu'un. email et role. |
| DELETE | /v1/users/invites/{id} |
iam:users.write |
Révoquer une invitation. |
Un nouveau compte n'envoie qu'aux adresses qu'il a vérifiées. Ceci en ajoute une.
| Méthode | Chemin | Portée | Fait |
|---|---|---|---|
| POST | /v1/sandbox/recipients |
email:sandbox.write |
Ajouter un destinataire de test. email. Une confirmation leur est envoyée. |
/mcp — une enveloppe JSON-RPC sur ces points de terminaison pour les agents, filtrée par les mêmes portées.Quelque chose manque ou est inexact ici ? Dites-le-nous et ce sera corrigé — cette page est vérifiée contre le routeur à chaque déploiement, mais seul le code dit ce qu'il fait.