Fouten en limieten van een e-mail-API: statuscodes, retries en monitoring

Wat elke respons van de Inbixio-API betekent, welke fouten je opnieuw probeert en welke je oplost, hoe maandlimieten werken en hoe je bezorging in productie bewaakt.

Eén e-mail versturen in een demo is eenvoudig. Honderdduizend per maand versturen in productie betekent dat je voorbereid moet zijn op de momenten dat het misgaat: een ingetrokken sleutel, een verlopen creditcard, een maand die eerder op is dan verwacht, een mailserver die een slechte dag heeft.

Deze gids legt elke respons uit die het verzend-endpoint van Inbixio teruggeeft, wat je code met elke respons moet doen en hoe je de bezorging in de gaten houdt zodra je live bent.

Twee fasen: geaccepteerd, dan afgeleverd

Een aanroep van POST /api/send-email/ verloopt in twee fasen:

  1. Het API-verzoek. Inbixio controleert je sleutel, de rechten ervan, je abonnement, je maandelijkse verbruik en de request body. Is alles in orde, dan geeft de API 200 terug en zet het bericht in de wachtrij.
  2. Bezorging. Even later maakt Inbixio verbinding met je SMTP-server en draagt het bericht over. Elk bericht wordt vastgelegd als verzonden of mislukt, en die resultaten voeden de cijfers op je dashboard.

Een 200 betekent dus “geaccepteerd voor bezorging”, niet “in de inbox”. Problemen in fase 1 komen terug als HTTP-fouten die je code kan afhandelen. Problemen in fase 2, zoals een verkeerd SMTP-wachtwoord, zie je terug in het percentage mislukte bezorgingen op het dashboard. Inbixio doet per bericht één bezorgpoging; een mislukte bezorging wordt niet opnieuw geprobeerd.

Elke respons, en wat je ermee doet

Status Body Betekenis Wat je code moet doen
200 {"message": "Email queued successfully."} Geaccepteerd Klaar
400 {"error": "to_email, subject, and message are required."} Een veld ontbreekt of is leeg Verzoek corrigeren; niet opnieuw proberen
400 {"error": "to_email must be a single valid email address."} Niet precies één geldig adres Verzoek corrigeren; niet opnieuw proberen
400 {"error": "subject must be a single line of at most 500 characters."} Onderwerp te lang of bevat een regeleinde Verzoek corrigeren; niet opnieuw proberen
400 {"error": "message must be text of at most 1,000,000 characters."} Body te groot Verzoek corrigeren; niet opnieuw proberen
400 {"error": "No SMTP configuration found. Please add an email server first."} Geen server gekoppeld Voeg een server toe in het dashboard
401 {"detail": "API key missing"} Geen X-API-Key-header Configuratie corrigeren; niet opnieuw proberen
401 {"detail": "Invalid API key"} Verkeerde, vernieuwde of verwijderde sleutel Sleutel bijwerken; je team waarschuwen
401 {"detail": "API key access not allowed"} De sleutel is uitgeschakeld Een andere sleutel gebruiken; je team waarschuwen
402 {"error": "An active subscription is required to send emails."} Abonnement niet actief Facturatie in orde maken; je team waarschuwen
403 {"error": "This API key does not have send permission."} Sleutel mist Send (versturen) Send inschakelen of een andere sleutel gebruiken
429 {"error": "Monthly email limit reached for your plan.", "limit": 25000, "sent": 25000} Limiet van het abonnement bereikt Upgraden, of mail aanhouden tot de volgende maand; niet opnieuw proberen
429 {"detail": "Request was throttled. Expected available in 12 seconds."} Te veel verzoeken met deze sleutel in korte tijd (rate limit) Wachten zoals de Retry-After-header aangeeft, dan opnieuw proberen
503 {"error": "Too many emails are waiting to be sent. Please retry in a few seconds."} Tijdelijk druk Wachten zoals de Retry-After-header aangeeft, dan opnieuw proberen
5xx / timeout — Tijdelijk probleem Opnieuw proberen met backoff

Foutmeldingen staan bij de meeste responses onder error en bij authenticatiefouten onder detail, dus lees ze allebei uit:

const body = await res.json().catch(() => ({}));
const reason = body.error ?? body.detail ?? res.statusText;

Probeer alleen opnieuw wat later kan slagen

Een 401 honderd keer opnieuw proberen maakt de sleutel niet geldig; het vult alleen je logs. Verdeel fouten in twee groepen:

  • Opnieuw proberen: netwerkfouten, timeouts, 5xx-responses en de rate-limit-429 (die met een detail-melding). Wacht zo lang als de Retry-After-header aangeeft, gebruik anders exponential backoff met jitter, en geef het na een paar pogingen op.
  • Niet opnieuw proberen: 400, 401, 402, 403 en de maandlimiet-429 (die met limit en sent). Hiervoor is een mens of een ander verzoek nodig. Log ze duidelijk zichtbaar en stuur een waarschuwing bij 401, 402 en de maandlimiet-429, want die leggen al je e-mail stil.
// 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');
}

Over dubbele e-mails: als een verzoek een timeout krijgt, kan het toch geaccepteerd zijn. Opnieuw proberen kan dan dezelfde e-mail twee keer versturen. Bij betaalbewijzen en meldingen is dat meestal acceptabel; bij alles waarbij een dubbele e-mail gebruikers in verwarring zou brengen, leg je in je eigen database vast wat je hebt verzonden en controleer je dat vóór een nieuwe poging.

Maandlimieten

Elk abonnement bevat een aantal e-mails per maand: 25.000 bij Starter en 150.000 bij Growth. Inbixio telt de succesvol verzonden e-mails in de huidige kalendermaand. Bereik je de limiet, dan geven verzendingen 429 terug met je limit en het huidige aantal sent, totdat de volgende maand begint of je upgradet.

Wacht niet op de 429:

  • De pagina API Keys (API-sleutels) toont een kaart Usage Limit (verbruikslimiet) met het aantal verzonden e-mails van deze maand tegenover de limiet van je abonnement.
  • Zet een herinnering om het te controleren rond 80% van je limiet, en plan een upgrade vóór een grote lancering of import.
  • Voor een stapsgewijze schatting van je volume, zie een e-mail-API-abonnement kiezen.

Mislukte bezorgingen (fase 2)

Als de API een bericht heeft geaccepteerd maar je SMTP-server het weigerde, telt het als een mislukte bezorging. Het dashboard toont het percentage Failed Deliveries (mislukte bezorgingen) over de afgelopen 7 dagen in plaats van een lijst met afzonderlijke berichten, dus houd dat percentage in de gaten en controleer je serverinstellingen als het stijgt. De gebruikelijke oorzaken:

  • Authenticatie mislukt: het wachtwoord van de mailbox is gewijzigd, of de provider vereist nu een app-wachtwoord.
  • Verbindingsproblemen: de host of poort in je serverinstellingen klopt niet.
  • Limieten van de provider: je mailprovider heeft het dagelijkse verzendvolume van de mailbox begrensd.
  • Geweigerde ontvanger: je server weigerde het adres tijdens het verzenden. Bounces die later als e-mail binnenkomen, gaan naar de verzendende mailbox en niet naar Inbixio, dus controleer ook die inbox.

De oplossing zit bijna altijd in Email Servers (e-mailservers) of bij je mailprovider. SMTP-instellingen uitgelegd behandelt de meest voorkomende gevallen.

Wat je in productie bewaakt

Je Inbixio-dashboard geeft je de basis:

  • Email Sent (verzonden e-mails) en het percentage Failed Deliveries over de afgelopen 7 dagen, elk met de verandering ten opzichte van de 7 dagen daarvoor.
  • Avg Latency (gemiddelde latency): hoe lang je SMTP-server erover doet om mail te accepteren. Een plotselinge stijging gaat vaak vooraf aan mislukkingen.
  • Grafieken van API- en e-mailvolume over het hele jaar, om trends en seizoenspieken te zien.
  • Logs (logboeken) van elke API-aanroep: event-ID, endpoint, methode, statuscode, responstijd en tijdstempel.

Houd aan jouw kant het aantal niet-200-responses per statuscode bij en stuur een waarschuwing zodra 401, 402 of de maandlimiet-429 opduiken. Die betekenen dat alle e-mail is gestopt, en je gebruikers merken dat eerder dan je logs.

Checklist

  • Behandel 200 als “in de wachtrij”; controleer bezorgresultaten op het dashboard
  • Lees zowel error als detail uit foutresponses
  • Probeer alleen netwerkfouten, timeouts, 5xx, 503 en de rate-limit-429 opnieuw, met inachtneming van Retry-After
  • Stuur een waarschuwing bij 401, 402 en de maandlimiet-429
  • Houd de kaart Usage Limit in de gaten vóór lanceringen en imports
  • Bewaak het percentage Failed Deliveries en corrigeer SMTP-instellingen direct

Verstuur het met Inbixio

Koppel je eigen SMTP-server, maak een API-sleutel met beperkte rechten aan en verstuur vanuit elke programmeertaal met één HTTPS-verzoek.

Account aanmaken Bekijk prijzen