Skip to content

The event object

An event is a named thing that happens to a contact — user.created, order.completed — optionally with a schema describing the payload it carries. Events are what automation triggers listen for.

Fields

The object returned by GET /v1/events/{id}, and by create, update and list.

FieldTypeDescription
objectstringAlways "event".
idstringEvent identifier — an opaque, prefixed string, evt_…. Stable for the life of the event, and the value you pass as a cursor when paginating.
namestringThe dotted identifier, e.g. user.created. Unique within your team, and usable in place of the id on every event endpoint. Never starts with the reserved sendgrail. namespace.
schemaobject | nullA flat map of field name → type describing the payload — see below. null when the event has no schema and accepts any payload.
created_atstringISO 8601 timestamp of when the event was defined.
updated_atstringISO 8601 timestamp of the last schema change; equal to created_at until the first one.

A delete returns a stub rather than the object — { object, id, deleted: true }. See Delete an event.

schema is one level deep

schema maps each expected field to a type. There are four types, and the value is always a type name — never a nested object.

TypePayload valueNotes
stringa JSON string
numbera JSON number
booleantrue / false
datea JSON stringISO 8601, e.g. 2026-07-17T09:30:00Z.
json
"schema": {
  "plan": "string",
  "seats": "number",
  "trial": "boolean",
  "signed_up_at": "date"
}

When an event is sent, its payload is validated against this map: a field of the wrong type is a 422. Fields the schema doesn't list are allowed through — the schema is a floor, not a whitelist. An event with "schema": null accepts any payload.

The name is the identity

name is unique within your team, which is what makes it usable as a path parameter: GET /v1/events/user.created works without you looking the id up first, the same way a contact endpoint accepts an email address. The name is fixed once created — to change the shape, update the schema; to change the name, create a new event.

Ids are opaque

evt_… is a prefixed string and nothing more — this API is Resend-inspired but not identical, and its ids are its own. Don't parse the part after the prefix or assume it sorts; treat the whole thing as a token. Automations carry auto_…, runs carry run_…, on the same principle.

Auto-created events

An event doesn't have to be defined before it is sent. Send an event with an unknown name and SendGrail creates the event with "schema": null — after which it is a first-class object here, listed and retrievable like any other.

Transactional email on your own domain.