Delivery Status

mails-agent tracks the full lifecycle of every message. Inbound emails arrive with a single status, while outbound emails progress through multiple states as they are queued, sent, and delivered (or fail).

Status Values

StatusDirectionDescription
receivedInboundEmail was received by mails-agent and stored. This is the only status for inbound messages.
sentOutboundEmail accepted by mails-agent and sent via Resend. This is the initial outbound status.
deliveredOutboundRecipient's mail server accepted the email. This is the terminal success state.
queuedOutboundDelivery is temporarily delayed by the recipient's mail server (queued for retry).
bouncedOutboundRecipient's mail server rejected the email (invalid address, full mailbox, etc.).
complainedOutboundRecipient marked the email as spam.
failedOutboundEmail could not be sent (API error, validation failure, rate limit exceeded).

Status Flow

Outbound emails progress through statuses in this order:

sent --> delivered                (success path)
sent --> queued --> delivered              (delayed then delivered)
sent --> bounced                  (hard/soft bounce)
sent --> complained               (spam report)
failed                            (immediate failure)

How Tracking Works

Resend webhook callbacks

mails-agent uses Resend as the outbound email provider. Resend sends webhook callbacks to mails-agent whenever a message status changes. These webhooks are automatically configured when you set up your Resend API key.

Important: You must set the RESEND_WEBHOOK_SECRET Worker secret for delivery tracking to work. Without it, all Resend webhook callbacks are rejected with 503. Get your webhook signing secret from the Resend dashboard under Webhooks.

wrangler secret put RESEND_WEBHOOK_SECRET

The webhook events processed are:

SSE events

Every status change fires a Server-Sent Event on the /v1/events stream. Your agent can listen for these events in real time without polling:

curl -s -N -H "Authorization: Bearer $API_KEY" \
  "https://mails-worker.genedai.workers.dev/v1/events"

Status change events look like this:

event: message.delivered
data: {
  "event": "message.delivered",
  "email_id": "msg_abc123",
  "mailbox": "[email protected]",
  "status": "delivered",
  "timestamp": "2026-04-01T12:30:05Z"
}

User webhooks

If you have configured a webhook URL (via PATCH /v1/mailbox or mails webhook set), mails-agent will also POST delivery status changes to your endpoint:

POST https://your-server.com/webhook
Content-Type: application/json

{
  "event": "message.bounced",
  "email_id": "msg_abc123",
  "mailbox": "[email protected]",
  "status": "bounced",
  "timestamp": "2026-04-01T12:30:05Z"
}

Checking Status via API

You can check the current delivery status of any message by fetching it:

GET/v1/email?id=msg_abc123 — Get email with delivery status
curl -s -H "Authorization: Bearer $API_KEY" \
  "https://mails-worker.genedai.workers.dev/v1/email?id=msg_abc123"
{
  "id": "msg_abc123",
  "from_address": "[email protected]",
  "to_address": "[email protected]",
  "subject": "Partnership proposal",
  "status": "delivered"
}

Handling Failures

Bounces

A bounced status means the recipient's mail server rejected the email. Common causes:

mails-agent does not automatically retry bounced emails. Your agent should handle bounces by notifying the user or trying an alternative contact method.

Complaints

A complained status means the recipient reported your email as spam. To maintain good deliverability:

Failures

A failed status means the email was never sent. This typically happens due to validation errors (invalid from address, missing required fields) or rate limiting. Check the error message in the API response for details.

Suppression List

Bounced and complained recipients are automatically added to a suppression list. Sending to a suppressed address returns 400 with an error message indicating the suppression reason.