Erreurs et limites d’une API e-mail : codes de statut, retries et suivi

Ce que signifie chaque réponse de l’API Inbixio, quelles erreurs relancer ou corriger, comment fonctionnent les limites mensuelles et comment suivre la livraison.

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 :

  1. 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 200 et met le message en file d’attente.
  2. 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 5xx et le 429 de limitation de débit (celui avec un message detail). Attendez la durée indiquée par l’en-tête Retry-After, sinon utilisez un backoff exponentiel avec jitter, et abandonnez après quelques tentatives.
  • À ne pas relancer : 400, 401, 402, 403 et le 429 de limite mensuelle (celui avec limit et sent). Ils nécessitent une intervention humaine ou une autre requête. Journalisez-les de façon bien visible, et déclenchez une alerte sur 401, 402 et le 429 de 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 200 comme « en file d’attente » ; vérifier les résultats de livraison dans le tableau de bord
  • Lire à la fois error et detail dans les réponses d’erreur
  • Ne relancer que les erreurs réseau, les timeouts, les 5xx, les 503 et le 429 de limitation de débit, en respectant Retry-After
  • Déclencher une alerte sur 401, 402 et le 429 de 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.

Créer un compte Voir les tarifs