Skip to content
couryo

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.

View as Markdown

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
curl https://api.couryo.com/v1/emails/msg_9w2k7c1x0d4e5f6g \
  -H "Authorization: Bearer $COURYO_API_KEY" \
  -H "Accept-Language: en"
Response
{
  "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
curl "https://api.couryo.com/v1/events?type=bounced&limit=50" \
  -H "Authorization: Bearer $COURYO_API_KEY"
Response
{ "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.