Questions · Updated 2026-09-28

How do I know if my email was delivered?

Your email was delivered when GET /emails/{id} reports status delivered and GET /emails/{id}/events records email.delivered. Delivered means the receiving server accepted the message, not that a person read it. A webhook on email.delivered from POST /webhooks tells you without polling.

Your email was delivered when GET /emails/{id} reports status delivered and GET /emails/{id}/events holds an email.delivered event. delivered is the receiving server's acceptance of the message; it is not a person opening it, and it says nothing about which folder the message landed in. To hear about it without polling, register an endpoint with POST /webhooks subscribed to email.delivered, and the payload's data carries the email_id and the tags you sent.

The statuses

The status field on GET /emails/{id} moves from queued or scheduled to sent and then delivered, or ends at delivery_delayed, bounced, complained, failed, canceled or suppressed. The two to tell apart are sent and delivered. GET /emails/{id}/explain on a sent message says "On its way: our mail servers have it, and delivery events follow as the receiving server answers." So sent is a message that has left, and delivered is the answer coming back. last_event on the same response names the most recent event, and GET /emails?status=delivered lists the messages that have reached that state.

curl -sS -X GET https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/events \
  -H "Authorization: Bearer $AGENTISEND_API_KEY"
200
{
  "data": [],
  "has_more": true,
  "next_cursor": "string",
  "object": "string"
}
Response

The events log

GET /emails/{id}/events is the record. Its summary is "Every event recorded for one message, oldest first, with the provider detail." Each row has type, occurred_at, detail and provider_message_id. A message that was accepted shows email.queued or email.scheduled, then email.sent, then email.delivered. When the last row is something else, GET /emails/{id}/explain returns verdict, what_happened, evidence, retryable and actions, each action with a do sentence and a call naming method, path and body. A bounced message gets verdict bounce and is the subject of Why did my email bounce?. A delivery_delayed message gets verdict delay, and retries continue on their own. email.failed means the message never left, and the explain action is to retry with the same Idempotency-Key.

Hearing about it

POST /webhooks takes url and events. Subscribe to email.delivered, email.bounced, email.complained, email.delivery_delayed and email.failed to cover every outcome, or * for everything. Every email.* payload carries email_id and tags in data, so a handler can update your own record from the payload alone. A delivery your endpoint does not acknowledge with a success status is retried on a fixed schedule, and the same event id can arrive twice, so store the id and ignore a repeat. Webhooks has the signature check and the retry schedule.

To see the whole sequence without mailing anyone, send to success@simulator.agentisend.com: the message moves through email.sent to email.delivered, webhooks included, with "simulated": true in the data.

Next