Developer guideEvents
Events and timeline
Every step of an email on Couryo, with time, receiving server, SMTP code, the original response and a plain-language explanation.
Every email has a timeline. Each event carries the time, the receiving server, the SMTP code, the server's original response and a plain-language explanation in your account's language.
See the timeline#
curl https://api.couryo.com/v1/emails/msg_9w2k7c1x0d4e5f6g \
-H "Authorization: Bearer $COURYO_API_KEY" \
-H "Accept-Language: en"{
"id": "msg_9w2k7c1x0d4e5f6g",
"from": "Acme Store <orders@example.com>",
"to": ["ana@example.com"],
"subject": "Your order 1042 is confirmed",
"stream": "transactional",
"status": "delivered",
"tags": { "type": "order" },
"metadata": { "order_id": "1042" },
"created_at": "2026-10-07T18:30:00Z",
"events": [
{ "id": "evt_1a", "type": "accepted", "at": "2026-10-07T18:30:00Z" },
{ "id": "evt_1b", "type": "queued", "at": "2026-10-07T18:30:00Z" },
{ "id": "evt_1c", "type": "sent", "at": "2026-10-07T18:30:01Z", "recipient": "ana@example.com" },
{
"id": "evt_1d",
"type": "delivered",
"at": "2026-10-07T18:30:02Z",
"recipient": "ana@example.com",
"mx": "gmail-smtp-in.l.google.com",
"provider": "gmail",
"smtp_code": "250 2.0.0",
"smtp_response": "250 2.0.0 OK 1791484202 a1b2c3d4e5f6 - gsmtp",
"explanation": "Gmail accepted the message."
}
]
}Event types#
| Event | Meaning |
|---|---|
accepted |
the API received and validated the request |
queued |
the email is in the queue (or waiting for scheduled_at) |
sent |
it left Couryo for the receiving server |
delivered |
the receiving server accepted the message |
deferred |
the receiver asked to try later (4xx code); Couryo retries on its own |
bounced |
the receiver refused it for good (5xx code) |
complained |
the recipient marked it as spam |
opened |
the email was opened (marketing stream only; imprecise, because some mail apps open everything on their own) |
clicked |
a link was clicked (marketing stream only) |
suppressed |
not sent because the address is on the suppression list |
failed |
not sent: the content was stopped by the intake check (phishing, a blocklisted link) or the send failed; the reason is in the event |
"Delivered" means the receiving server accepted it. Whether it landed in the inbox or in spam is not reported per message by any provider. That is why the dashboard shows delivery split by provider; reputation tracking by the deliverability agent is coming soon.
Email status#
The status field summarizes the timeline: queued, sent, delivered, deferred, bounced, complained, failed, suppressed or captured (test key, not delivered).
Providers#
The provider field groups the destination: gmail, microsoft, yahoo, uol, bol, terra, locaweb or other. The dashboard shows delivery split by provider.
Bounces: permanent, temporary and blocks#
- Permanent (
5.1.x, user or domain does not exist): the address goes to the suppression list right away. - Temporary (
4.x.x): Couryo retries on its own. If the same address bounces on 3 different days (within 14 days), it is suppressed. - Policy block (
5.7.x, responses mentioning "blocked" or "spam"): not the recipient's fault. The address is not suppressed and the bounce does not count toward your bounce rate.
List events#
GET /v1/events (read scope) lists events for all emails in the project, newest first, each with its email_id. Useful if you missed webhooks or prefer to poll. Filters: type (for example bounced) and email_id.
curl "https://api.couryo.com/v1/events?type=bounced&limit=50" \
-H "Authorization: Bearer $COURYO_API_KEY"{ "data": [{ "id": "evt_7d3k9s0a2m5n8b1c", "email_id": "msg_9w2k7c1x0d4e5f6g", "type": "bounced", "at": "2026-10-07T18:31:04Z", "recipient": "maria@company.com", "smtp_code": "550 5.1.1" }], "has_more": true }For the next page, pass starting_after with the id of the last item.
How long it is kept#
The timeline is available for your plan's log retention: 7 days on Free, 30 days on Pro and 90 days on Scale.