MarmunkDevelopers
Answers

Accepted is not delivered.

Every email API reports status, but few are precise about what each status proves. The distinction is not pedantry: it determines what your code can safely assume — and what an AI agent acting on your behalf can safely tell your users.

01

The three statuses

Marmunk traces every message through three states, each gated by real evidence:

queued — Marmunk durably recorded the send intent. The write survived in the queue before the API returned 202 Accepted. Nothing has contacted any email provider yet.

submitted — the email provider (for example Amazon SES) accepted the message for sending. The provider has nottold you anything about the recipient's mailbox yet.

delivered— normalized provider evidence shows the provider handed the message to the recipient's mail exchanger. This is the only state that says the email reached the receiving infrastructure.

02

What each status proves

Accepted/queued proves intent was recorded. It is safe to conclude: your business operation triggered a send, and the request will not be lost. It is not safe to conclude: the recipient got anything, the provider saw anything, or the address was even well-formed.

Submitted proves provider acceptance.The provider validated the message and accepted it into its own queue. Bounces, spam placement, and deferrals can still happen — provider acceptance is the start of the provider's responsibility, not the end of the story.

Delivered proves handoff, not engagement.Delivery evidence comes from provider events, normalized into a uniform stream (Marmunk signs these events and replays them over webhooks). A "delivered" email can still be filtered by the recipient's client, or land in a spam folder. No API can prove a human read a message — only engagement signals can suggest that.

03

Why agents make this worse

When an LLM agent sends email, it summarizes outcomes back to users. An agent that reads "202 Accepted" and reports "the email was delivered" has fabricated evidence — confidently, in plain English, to a user who has no reason to doubt it.

This is a trust-boundary problem, not a UX detail. The safe agent loop is: send, store the returnedmsg_*id, poll the trace or await the signed webhook, and only then report the outcome in the status's own vocabulary. Marmunk's MCP tools return the status terms themselves so the model can quote them instead of paraphrasing upward.

The same logic drives Marmunk's approval boundary: an agent can state outcomes, but it cannot upgrade them, and it cannot approve sending capacity for itself. Out-of-band human approval governs production sending regardless of what the agent observed.

04

How to handle it correctly

Treat queued as a receipt for your business record, submittedas the provider's acknowledgment, and deliveredas the only state that means "reaching the recipient." Concretely:

Store the msg_* id next to your business entity at send time. Trace a specific message with GET /v1/email-traces/{referenceId}, or subscribe to the signed webhook stream and consume each normalized event exactly once. For agent-driven flows, use the trace tool after sending and report the status verbatim.

Read the send-debugging guide for the trace workflow, and webhooks for consuming signed delivery events.