Bezorgingsmodel
Truncus scheidt de transportlaag van het besturingsvlak. Deze scheiding verklaart wat "deterministische bezorging" in de praktijk betekent.
Architectuur
Transportlaag: AWS SES verzorgt de SMTP-bezorging naar de ontvangende mailservers.
Besturingsvlak (EU): Truncus orkestreert verzendingen, slaat bezorgevenementen op, dwingt idempotentie af, beheert replay en legt de uitkomst van elke e-mail vast.
Jouw systeem communiceert uitsluitend met het besturingsvlak. De transportlaag is een implementatiedetail.
Bezorgingsflow
- Verzendverzoek ontvangen door Truncus
- Validatie (API key, payload, domeinmachtiging)
- Transportpoging via AWS SES
- Uitkomst (bezorging, bounce of klacht) vastgelegd uit SES-feedback
- Event opgeslagen in de EU (Frankfurt)
- Webhook verzonden naar jouw endpoint
Twee verzendroutes
POST /api/v1/emails/send is asynchroon. Het antwoord komt zodra een provider het bericht accepteert of weigert, niet wanneer het bezorgd is. status is sent (geaccepteerd door een provider), queued (tijdelijke fout, retry gepland), scheduled (uitgesteld via send_at), duplicate (idempotency-herhaling), blocked (onderdrukt of domeintype klopt niet) of failed (permanente fout). De bezorguitkomst komt later binnen als event.
POST /api/v1/emails/send_sync wacht tot 25 seconden op dat event en geeft de terminale status terug in hetzelfde verzoek:
| Status | Betekenis |
|---|---|
delivered | Geaccepteerd door de ontvangende mailserver |
bounced | Geweigerd door de ontvangende mailserver |
complained | Ontvanger heeft het bericht als spam gemarkeerd |
pending | Geen event binnen het venster; de e-mail is verstuurd. Opvragen via GET /api/v1/emails/{id} |
delivered betekent dat het bericht is geaccepteerd door de mailserver van de ontvanger. Dit garandeert geen plaatsing in de inbox.
Een bounce-event bevat het bouncetype dat SES meldt (bounce_type: Permanent, Transient of Undetermined) en het bounce_subtype. Permanente bounces en klachten zetten het adres op je suppressielijst.
blocked treedt op vóór elke verzendpoging, op beide routes: het adres is onderdrukt, of het verzenddomein mag dit bericht niet versturen. Het antwoord bevat een machineleesbare code, bijvoorbeeld ALL_RECIPIENTS_SUPPRESSED.
Wat Truncus niet doet
- Geen impliciete retries na een bounce of blokkade
- Geen status-samenvoegen — elke verzending wordt onafhankelijk bijgehouden
- Geen optimistische succesresponses — SES-weigeringen worden doorgegeven
Event-opslag
Alle bezorgevenementen worden opgeslagen in de EU (Frankfurt) en zijn opvraagbaar via API of dashboard. Events worden op alle plannen 90 dagen bewaard.
Events zijn op aanvraag herhaalbaar.
Synchrone vs. asynchrone status
Het antwoord van /emails/send meldt wat er met het verzoek gebeurde (sent, queued, …), niet de bezorguitkomst. SES-feedback is asynchroon en werkt de opgeslagen e-mail bij zodra die binnenkomt. Wil je er in één aanroep op wachten, gebruik dan /emails/send_sync: dat geeft de terminale status terug, of pending als er binnen 25 seconden geen event binnenkwam.
Voor productiesystemen raden we aan bezorgingsstatus via webhooks te consumeren in plaats van de send-response te pollen.