Skip to content

Webhook events

This is the reference for the events SendGrail delivers to your webhooks. For setting one up and verifying signatures, see the Webhooks guide.

Envelope

Every webhook request body has the same three top-level fields:

json
{
  "type": "email.delivered",
  "created_at": "2026-05-21T21:02:38+00:00",
  "data": { }
}
FieldDescription
typeThe event type — one of the values below.
created_atISO 8601 time the event was generated.
dataEvent-specific payload. Email events and domain events have different data shapes.

The event type is also in the Sendgrail-Event-Type request header.

Email events

Fired as a message moves through its lifecycle.

TypeFired when
email.sentSendGrail handed the message to AWS SES.
email.delivery_delayedThe recipient's server temporarily deferred the message; SES keeps retrying.
email.deliveredThe recipient's mail server accepted the message.
email.openedThe recipient opened the message (requires open tracking).
email.clickedThe recipient clicked a tracked link (requires click tracking).
email.bouncedThe message was returned as undeliverable.
email.complainedThe recipient marked the message as spam.
email.failedSendGrail could not send the message.
email.rejectedAWS SES dropped the message before delivery (e.g. its own suppression list, a content scan, or a size limit).
email.suppressedA send was blocked because a recipient was on your suppression list.
email.scheduledReserved — a scheduled send is queued for a future time. Subscribable but not yet emitted.
email.receivedReserved — an inbound message arrived. Subscribable but not yet emitted.

Email event data

json
{
  "type": "email.delivered",
  "created_at": "2026-05-21T21:02:38+00:00",
  "data": {
    "email_id": "a7e2b91c-4d63-4f8a-b0e5-1c9d3f6a2b74",
    "from": "Acme <hello@example.com>",
    "to": ["recipient@example.org"],
    "subject": "Your receipt",
    "status": "delivered",
    "sent_at": "2026-05-21T21:02:36+00:00"
  }
}
FieldDescription
email_idThe message UUID from the original send response. Use it to correlate the event.
fromSender address.
toRecipient addresses.
ccCarbon-copy recipients — present only when the message had cc.
bccBlind-carbon-copy recipients — present only when the message had bcc.
subjectMessage subject.
statusThe message status at the time of the event.
sent_atWhen the message was sent, or null if it hadn't been sent yet.
tagsThe tags supplied at send time — present only when non-empty. Useful for routing events to downstream handlers.
detailOptional. Extra context for the event — see below.

The detail field

Some events include a detail object:

  • email.bounced / email.complained — the relevant sub-payload from AWS SES, when available (bounce type, diagnostic information, and similar).
  • email.suppressed — the suppression reason that blocked the send:
json
{
  "type": "email.suppressed",
  "created_at": "2026-05-21T08:12:32+00:00",
  "data": {
    "email_id": "3f5c9a1e-8b2d-4e6f-9a1c-7d4b2e8f0a63",
    "from": "Acme <hello@example.com>",
    "to": ["bounced@example.org"],
    "subject": "Your receipt",
    "status": "suppressed",
    "sent_at": null,
    "detail": { "reason": "bounce" }
  }
}

Domain events

Fired when a domain on your account changes.

TypeFired when
domain.createdA domain was added to your account.
domain.updatedA domain's status changed — for example, it became verified.
domain.deletedA domain was removed from your account.

Domain event data

json
{
  "type": "domain.updated",
  "created_at": "2026-05-21T09:30:00+00:00",
  "data": {
    "domain_id": 12,
    "name": "mail.example.com",
    "region": "us-east-1",
    "status": "verified",
    "verified_at": "2026-05-21T09:30:00+00:00"
  }
}
FieldDescription
domain_idThe domain's numeric id.
nameThe domain name.
regionThe AWS region the domain sends from.
statuspending, verified or failed.
verified_atWhen the domain verified, or null if it isn't verified.

Contact events

TypeFired when
contact.createdA contact was added to your audience.
contact.updatedA contact's details or subscription changed.
contact.deletedA contact was removed.

Contact event data

json
{
  "type": "contact.created",
  "created_at": "2026-05-21T09:30:00+00:00",
  "data": {
    "contact_id": "contact_9fQ2xL7mA0bWpK3sYd8V",
    "email": "jane@example.com",
    "first_name": "Jane",
    "last_name": "Doe",
    "subscribed": true
  }
}
FieldDescription
contact_idThe contact's public id.
emailThe contact's email address.
first_name / last_namePresent when set, otherwise null.
subscribedWhether the contact is currently subscribed.

Choosing events

You select which event types a webhook receives when you create or edit it. Subscribe only to what you act on — a webhook that just records deliveries doesn't need domain.*, and one that watches for problems may only want email.bounced, email.complained and email.failed.

Not included

Open and click events are not delivered over webhooks — they're visible only in the dashboard. See Open & click tracking.

Transactional email on your own domain.