Envoyer un e-mail dans une démo, c’est facile. En envoyer cent mille par mois en production impose d’anticiper les moments où tout se passe mal : une clé révoquée, une carte expirée, un mois qui se termine plus tôt que prévu, un serveur de messagerie dans un mauvais jour.
Ce guide explique chaque réponse renvoyée par le point de terminaison d’envoi d’Inbixio, ce que votre code doit faire dans chaque cas, et comment surveiller la livraison une fois en production.
Deux étapes : accepté, puis délivré
Un appel à POST /api/send-email/ se déroule en deux étapes :
- La requête API. Inbixio vérifie votre clé, ses permissions, votre abonnement, votre consommation du mois et le corps de la requête. Si tout est en ordre, il renvoie
200et met le message en file d’attente. - La livraison. Un instant plus tard, Inbixio se connecte à votre serveur SMTP et lui transmet le message. Chaque message est enregistré comme envoyé ou en échec, et ces résultats alimentent les chiffres de votre tableau de bord.
Un 200 signifie donc « accepté pour livraison », pas « arrivé en boîte de réception ». Les problèmes de l’étape 1 reviennent sous forme d’erreurs HTTP que votre code peut traiter. Ceux de l’étape 2, comme un mot de passe SMTP erroné, apparaissent dans le taux d’échec de livraison du tableau de bord. Inbixio effectue une seule tentative de livraison par message ; il ne relance pas une livraison échouée.
Chaque réponse, et que faire
| Statut | Corps | Signification | Ce que doit faire votre code |
|---|---|---|---|
200 |
{"message": "Email queued successfully."} |
Accepté | Rien de plus |
400 |
{"error": "to_email, subject, and message are required."} |
Un champ est manquant ou vide | Corriger la requête ; ne pas relancer |
400 |
{"error": "to_email must be a single valid email address."} |
Pas exactement une adresse valide | Corriger la requête ; ne pas relancer |
400 |
{"error": "subject must be a single line of at most 500 characters."} |
Objet trop long ou contenant un saut de ligne | Corriger la requête ; ne pas relancer |
400 |
{"error": "message must be text of at most 1,000,000 characters."} |
Corps trop volumineux | Corriger la requête ; ne pas relancer |
400 |
{"error": "No SMTP configuration found. Please add an email server first."} |
Aucun serveur connecté | Ajouter un serveur dans le tableau de bord |
401 |
{"detail": "API key missing"} |
Pas d’en-tête X-API-Key |
Corriger la configuration ; ne pas relancer |
401 |
{"detail": "Invalid API key"} |
Clé erronée, renouvelée ou supprimée | Mettre à jour la clé ; alerter l’équipe |
401 |
{"detail": "API key access not allowed"} |
La clé a été désactivée | Utiliser une autre clé ; alerter l’équipe |
402 |
{"error": "An active subscription is required to send emails."} |
Abonnement inactif | Régulariser la facturation ; alerter l’équipe |
403 |
{"error": "This API key does not have send permission."} |
La clé n’a pas Send | Activer Send ou utiliser une autre clé |
429 |
{"error": "Monthly email limit reached for your plan.", "limit": 25000, "sent": 25000} |
Limite de l’offre atteinte | Passer à l’offre supérieure, ou retenir les envois jusqu’au mois suivant ; ne pas relancer |
429 |
{"detail": "Request was throttled. Expected available in 12 seconds."} |
Trop de requêtes avec cette clé en peu de temps (limitation de débit) | Attendre le délai de l’en-tête Retry-After, puis relancer |
503 |
{"error": "Too many emails are waiting to be sent. Please retry in a few seconds."} |
Temporairement surchargé | Attendre le délai de l’en-tête Retry-After, puis relancer |
5xx / timeout |
— | Problème temporaire | Relancer avec backoff |
Les messages d’erreur arrivent sous error pour la plupart des réponses et sous detail pour les erreurs d’authentification : lisez donc les deux.
const body = await res.json().catch(() => ({}));
const reason = body.error ?? body.detail ?? res.statusText;
Ne relancez que ce qui peut réussir plus tard
Relancer cent fois un 401 ne rendra pas la clé valide ; cela ne fera que remplir vos journaux. Répartissez les erreurs en deux groupes :
- À relancer : erreurs réseau, timeouts, réponses
5xxet le429de limitation de débit (celui avec un messagedetail). Attendez la durée indiquée par l’en-têteRetry-After, sinon utilisez un backoff exponentiel avec jitter, et abandonnez après quelques tentatives. - À ne pas relancer :
400,401,402,403et le429de limite mensuelle (celui aveclimitetsent). Ils nécessitent une intervention humaine ou une autre requête. Journalisez-les de façon bien visible, et déclenchez une alerte sur401,402et le429de limite mensuelle, car ils bloquent tous vos e-mails.
// 5xx and the short-term rate limit can succeed later; the monthly limit (body has `limit`) can't.
const retryable = (status, body) => status >= 500 || (status === 429 && body.limit === undefined);
export async function sendWithRetry(payload, attempts = 4) {
for (let i = 0; i < attempts; i++) {
let res;
try {
res = await fetch('https://backend.inbixio.com/api/send-email/', {
method: 'POST',
headers: { 'X-API-Key': process.env.INBIXIO_API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
signal: AbortSignal.timeout(15_000),
});
} catch (err) {
if (i === attempts - 1) throw err; // network error or timeout: retry
}
if (res?.ok) return res.json();
if (res) {
const body = await res.json().catch(() => ({}));
if (!retryable(res.status, body)) {
throw new Error(`Inbixio ${res.status}: ${body.error ?? body.detail ?? res.statusText}`);
}
}
const retryAfter = Number(res?.headers.get('Retry-After')) * 1000;
const delay = retryAfter || Math.min(30_000, 1000 * 2 ** i) * (0.5 + Math.random()); // 0.5s–30s with jitter
await new Promise((r) => setTimeout(r, delay));
}
throw new Error('Inbixio: gave up after retries');
}
À propos des doublons : si une requête expire, elle a peut-être quand même été acceptée. La relancer pourrait alors envoyer deux fois le même e-mail. Pour des reçus et des notifications, c’est généralement acceptable ; pour tout ce qui pourrait dérouter vos utilisateurs en double, enregistrez ce que vous avez envoyé dans votre propre base de données et vérifiez-le avant de relancer.
Limites mensuelles
Chaque offre inclut un nombre d’e-mails par mois : 25 000 avec Starter et 150 000 avec Growth. Inbixio compte les e-mails envoyés avec succès au cours du mois calendaire en cours. Une fois la limite atteinte, les envois renvoient 429 avec votre limit et votre compteur sent actuel, jusqu’au début du mois suivant ou jusqu’à ce que vous changiez d’offre.
N’attendez pas le 429 :
- La page API Keys (clés API) affiche une carte Usage Limit (limite d’utilisation) avec le nombre d’envois du mois par rapport à la limite de votre offre.
- Programmez-vous un rappel pour la consulter vers 80 % de votre limite, et prévoyez un changement d’offre avant un gros lancement ou un import important.
- Pour estimer votre volume pas à pas, consultez choisir une offre d’API e-mail.
Échecs de livraison (étape 2)
Lorsque l’API a accepté un message mais que votre serveur SMTP l’a refusé, il compte comme un échec de livraison. Le tableau de bord affiche le taux de Failed Deliveries (échecs de livraison) des 7 derniers jours plutôt qu’une liste de messages individuels : surveillez donc ce taux et vérifiez les paramètres de votre serveur lorsqu’il augmente. Les causes habituelles :
- Échec d’authentification : le mot de passe de la boîte mail a changé, ou le fournisseur exige désormais un mot de passe d’application.
- Problèmes de connexion : l’hôte ou le port indiqué dans les paramètres du serveur est incorrect.
- Limites du fournisseur : votre fournisseur de messagerie a plafonné l’envoi quotidien de la boîte.
- Destinataire refusé : votre serveur a refusé l’adresse pendant l’envoi. Les rebonds qui arrivent plus tard sous forme d’e-mails sont adressés à la boîte d’envoi, pas à Inbixio : vérifiez donc aussi cette boîte.
La solution se trouve presque toujours dans Email Servers (serveurs e-mail) ou chez votre fournisseur de messagerie. Les paramètres SMTP expliqués couvre les cas les plus courants.
Que surveiller en production
Votre tableau de bord Inbixio vous fournit l’essentiel :
- Email Sent (e-mails envoyés) et le taux de Failed Deliveries des 7 derniers jours, chacun avec l’évolution par rapport aux 7 jours précédents.
- Avg Latency (latence moyenne) : le temps que met votre serveur SMTP à accepter le courrier. Une hausse soudaine précède souvent les échecs.
- Des graphiques de volume d’API et d’e-mails sur l’année, pour repérer les tendances et les pics saisonniers.
- Logs (journaux) de chaque appel d’API : identifiant d’événement, point de terminaison, méthode, code de statut, temps de réponse et horodatage.
De votre côté, suivez le nombre de réponses autres que 200 par code de statut et déclenchez une alerte dès qu’apparaissent 401, 402 ou le 429 de limite mensuelle. Ils signifient que tous les e-mails sont bloqués, et vos utilisateurs s’en apercevront avant vos journaux.
Checklist
- Considérer
200comme « en file d’attente » ; vérifier les résultats de livraison dans le tableau de bord - Lire à la fois
erroretdetaildans les réponses d’erreur - Ne relancer que les erreurs réseau, les timeouts, les
5xx, les503et le429de limitation de débit, en respectantRetry-After - Déclencher une alerte sur
401,402et le429de limite mensuelle - Garder un œil sur la carte Usage Limit avant les lancements et les imports
- Surveiller le taux de Failed Deliveries et corriger rapidement les paramètres SMTP
Envoyez-le avec Inbixio
Connectez votre propre serveur SMTP, créez une clé API aux droits limités et envoyez depuis n’importe quel langage en une seule requête HTTPS.