Envoyer un email
POST /v1/emails accepte l'envoi et répond immédiatement : la distribution effective est traitée en file d'attente, avec relances automatiques en cas d'échec temporaire.
Essayez tout de suite, sans domaine
Pas encore de domaine vérifié ? Zendou fournit une adresse d’expédition de test, prête à l’emploi dès qu’une clé API existe - copiable sur Clés API. Elle n’est pas reproduite ici : ainsi cette page reste toujours exacte, même si Zendou change un jour de domaine d’expédition partagé.
curl -X POST https://api.zendou.app/v1/emails \
-H "Authorization: Bearer zd_live_votre_cle" \
-H "Content-Type: application/json" \
-d '{
"from": "adresse affichée sur /dashboard/cles-api",
"to": "vous@votre-adresse-de-compte.gn",
"subject": "Mon premier email Zendou",
"html": "<p>Ça marche déjà, avant même de vérifier un domaine.</p>"
}'Une seule limite
Paramètres du corps
| Nom | Type | Requis | Description |
|---|---|---|---|
from | string | Oui | Expéditeur. « adresse@domaine » ou « Nom <adresse@domaine> ». Le domaine doit être un domaine vérifié de votre compte. |
to | string | Oui | Destinataire. « adresse@domaine » ou « Nom <adresse@domaine> ». Un seul destinataire, pas de liste ni de séparateur en v1. Le journal, la liste de suppression et le bac à sable travaillent sur l'adresse seule, en minuscules. |
replyTo | string | Non | Adresse à laquelle les réponses doivent arriver. « adresse@domaine » ou « Nom <adresse@domaine> ». Soumise à la même règle que from : le domaine doit être vérifié et rattaché à votre compte, sinon l'envoi est refusé en 403. |
headers | objet | Non | En-têtes personnalisés, de la forme { "X-Nom": "valeur" }. 20 au plus. Seuls List-Unsubscribe, List-Unsubscribe-Post et les en-têtes X-* (hors X-SES-*) sont autorisés ; les noms ne tiennent pas compte de la casse et ne peuvent pas être en double. Voir la section « En-têtes personnalisés ». |
subject | string | Oui | Sujet de l'email. Entre 1 et 300 caractères. |
html | string | Non* | Corps HTML de l'email. Limité à 500 Ko (mesurés en octets UTF-8). |
text | string | Non* | Corps texte brut de l'email. Limité à 500 Ko (mesurés en octets UTF-8). |
* Au moins l’un des deux champs html ou text est obligatoire.
Formats d’adresse
Les champs from, to et replyTo acceptent deux formes : adresse@domaine ou Nom <adresse@domaine>. Le champ to accepte lui aussi les deux formes, avec un seul destinataire. Règles :
- le chevron fermant doit terminer la valeur : rien ne peut suivre
>; - le nom peut être entre guillemets, et doit l’être s’il contient l’un des caractères
" ( ) , : ; < > @ [ \ ], par exemple"Awa, Boutique" <no-reply@boutique-awa.gn>(dans du JSON, les guillemets s’échappent avec\) ; - la partie avant le
@n’est pas acceptée entre guillemets ; - le nom d’affichage est limité à 128 caractères (un accent ou un emoji compte pour 1) : au-delà, l’API répond 400 avant tout débit, par exemple « Le nom d’affichage de l’adresse d’expédition est trop long : il ne doit pas dépasser 128 caractères. » ;
- un nom avec des accents (par exemple « Boutique Awa Diallo ») peut être envoyé tel quel : Zendou l’encode pour la messagerie ;
- l’adresse est ramenée en minuscules, et pour
frometreplyTole domaine doit être vérifié sur votre compte ; - le journal, la liste de suppression et le bac à sable travaillent sur l’adresse seule, en minuscules, sans le nom.
"from": "Boutique Awa <no-reply@boutique-awa.gn>", "replyTo": "support@boutique-awa.gn", "to": "Awa Diallo <client@exemple.gn>"
En-têtes personnalisés
Le champ headers ajoute des en-têtes à l’email. Règles :
- 20 en-têtes au plus ;
- noms autorisés :
List-Unsubscribe,List-Unsubscribe-PostetX-*horsX-SES-*(X-seul est refusé), sans tenir compte de la casse, sans doublon ; - nom de 126 caractères au plus ;
- valeur en ASCII imprimable uniquement (ni accent, ni saut de ligne), 995 caractères au plus ;
- nom et valeur réunis : 996 caractères au plus.
Toute autre valeur donne une réponse 400 avant tout débit de crédit. Le relais SMTP transmet les en-têtes tels quels, à l’exception de Bcc, Return-Path, Sender et des Resent-*, qu’il retire.
Désinscription en un clic
Pour les envois réguliers (rappels, bilans, lettres d’information), Gmail et Yahoo exigent la désinscription en un clic pour les envois en volume. Ajoutez les deux en-têtes ci-dessous, puis traitez la désinscription de votre côté : Zendou ne gère pas vos listes d’abonnés.
curl -X POST https://api.zendou.app/v1/emails \
-H "Authorization: Bearer zd_live_votre_cle" \
-H "Content-Type: application/json" \
-d '{
"from": "Boutique Awa <no-reply@boutique-awa.gn>",
"to": "cliente@exemple.gn",
"subject": "Votre bilan de la semaine",
"html": "<p>Voici votre bilan.</p>",
"headers": {
"List-Unsubscribe": "<https://boutique-awa.gn/desinscription?id=abc123>, <mailto:desabonnement@boutique-awa.gn>",
"List-Unsubscribe-Post": "List-Unsubscribe=One-Click"
}
}'Exemple de requête
curl -X POST https://api.zendou.app/v1/emails \
-H "Authorization: Bearer zd_live_votre_cle" \
-H "Content-Type: application/json" \
-d '{
"from": "Boutique Awa <no-reply@boutique-awa.gn>",
"to": "cliente@exemple.gn",
"replyTo": "support@boutique-awa.gn",
"subject": "Votre commande est confirmée",
"html": "<p>Merci pour votre commande, elle est en préparation.</p>"
}'Exemple de réponse
Toute requête acceptée répond 202 Accepted - y compris quand le destinataire est bloqué : l’email est alors tracé avec le statut suppressed, sans être mis en file ni facturé.
{
"id": "e_7f3a91c2b8d1",
"status": "queued"
}{
"id": "e_1a2b3c4d5e6f",
"status": "suppressed"
}Codes d’erreur
| Code | Cas | Message renvoyé | Marche à suivre |
|---|---|---|---|
| 400 | Adresse d'expédition illisible | « L'adresse d'expédition est invalide : utilisez « adresse@domaine » ou « Nom <adresse@domaine> ». » | Corrigez le format du champ from. |
| 400 | Adresse destinataire illisible | « L'adresse du destinataire est invalide : indiquez une seule adresse comme « client@exemple.gn ». » | Le champ to n'accepte qu'un seul destinataire, sous la forme adresse@domaine ou Nom <adresse@domaine>. |
| 400 | Adresse de réponse (replyTo) illisible | « L'adresse de réponse (reply-to) est invalide : utilisez « adresse@domaine » ou « Nom <adresse@domaine> ». » | Corrigez le format du champ replyTo, ou omettez-le. |
| 400 | En-têtes personnalisés invalides | « L'en-tête « X-SES-Foo » n'est pas autorisé. Seuls List-Unsubscribe, List-Unsubscribe-Post et les en-têtes X-* (hors X-SES-*) peuvent être personnalisés. » | Corrigez le champ headers selon les règles de la section « En-têtes personnalisés », ou omettez-le. |
| 400 | Sujet vide ou trop long | « Le sujet est obligatoire et ne doit pas dépasser 300 caractères. » | Renseignez subject avec 1 à 300 caractères. |
| 400 | Ni html ni text fourni | « Fournissez au moins un contenu : « html » ou « text ». » | Ajoutez au moins l'un des deux champs dans le corps de la requête. |
| 400 | Contenu trop volumineux | « Chaque contenu (« html », « text ») est limité à 500 Ko. » | Réduisez la taille du contenu - par exemple en hébergeant les images à part plutôt qu'en base64 inline. |
| 401 | Clé API absente, inconnue ou révoquée | « Clé API invalide ou révoquée » | Vérifiez l'en-tête Authorization: Bearer zd_live_…. Générez une nouvelle clé si nécessaire. |
| 402 | Solde de crédits insuffisant | « Crédits insuffisants : rechargez votre compte pour continuer à envoyer. » | Rechargez votre solde (voir Facturation). |
| 403 | Domaine d'envoi non vérifié | « Le domaine d'envoi n'est pas vérifié : ajoutez-le à votre compte et validez ses enregistrements DNS avant d'envoyer. » | Suivez le guide de vérification de domaine avant de réessayer. |
| 403 | Domaine de l'adresse de réponse (replyTo) non vérifié | « L'adresse de réponse (reply-to) doit utiliser un domaine vérifié de votre compte : ajoutez-le et validez ses enregistrements DNS avant d'envoyer. » | Vérifiez le domaine de l'adresse replyTo, comme pour from, ou omettez ce champ. |
| 403 | Envoi test vers un autre destinataire que son propre compte | « Depuis l'adresse de test, vous ne pouvez écrire qu'à l'adresse email de votre compte. Vérifiez un domaine pour écrire à vos utilisateurs. » | Envoyez à votre propre adresse de compte, ou vérifiez un domaine pour écrire à vos utilisateurs. |
| 403 | Compte suspendu | « Ce compte est suspendu » | Le compte a été suspendu automatiquement pour protéger la réputation d'envoi (taux de rebonds ou de plaintes trop élevé). Contactez le support. |
| 429 | Limite journalière atteinte | « Limite journalière atteinte : réessayez demain ou demandez une augmentation de quota. » | Réessayez le lendemain (minuit UTC) - la limite augmente automatiquement avec l'ancienneté et le volume du compte. |
Voir Erreurs pour la référence complète de tous les codes HTTP de l’API, toutes routes confondues.
Statuts d’un email
Un envoi accepté suit normalement le cycle QUEUED → SENT → DELIVERED. Les statuts suivants marquent une sortie de ce cycle :
| Statut | Signification |
|---|---|
| QUEUED | L'email a été accepté et débité d'un crédit. Il attend d'être traité par la file d'envoi. |
| SENT | L'email a été remis à Amazon SES pour distribution. |
| DELIVERED | Le serveur du destinataire a confirmé la réception. Fin normale du cycle. |
| BOUNCED | Le message a rebondi. Un rebond dur (adresse inexistante) ajoute automatiquement l'adresse à votre liste de suppression ; un rebond transitoire (boîte pleine, serveur indisponible) est seulement enregistré. |
| COMPLAINED | Le destinataire a signalé l'email comme spam. L'adresse est ajoutée automatiquement à la liste de suppression. |
| SUPPRESSED | L'envoi a été bloqué avant la mise en file car l'adresse est sur une liste de suppression (la vôtre ou globale à la plateforme). Non facturé. |
| REJECTED / FAILED | L'email n'a pas pu être délivré : message rejeté par Amazon SES, ou abandon après plusieurs tentatives d'envoi. |
Effet sur la réputation