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"
}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.