Skip to content
Docs

Send workspace and custom events, and read the event stream behind webhooks: deliveries, bounces, opens and more.

Base URLhttps://api.emailit.com/v2AuthenticationErrorsRate limits

Send an event

Records one workspace event (w:<name>) or custom event (c:<name>). Works with API keys that have the full or the events scope. See Event tracking for when to use which. Events are included with Pro, Business and Custom plans, with up to 100 event types on Pro and 1,000 on Business.

  • A workspace event must be defined first. Its properties are checked against the definition.
  • A custom event needs no definition. Its properties can be any JSON object.

System events such as email.delivered are recorded by Emailit and can’t be sent. To record many events in one call, use Send events in a batch.

POST/events

Body parameters

typestringrequired
w:<name> for a workspace event or c:<name> for a custom event, for example c:order.completed. The name has 1 to 100 letters, digits, ., - or _, and starts with a letter or digit.
propertiesobject

The event’s data. Default {}.

  • Workspace events: only the properties of the definition, each with its type. Required properties must be present, null leaves an optional one empty, and dates are stored as ISO 8601 in UTC. See Property types.
  • Custom events: any JSON object, up to 32 KB and 8 levels deep.
emailstring
The email address of the person the event is about. If a contact has this address, the event is attributed to that contact. If none does, the address is still stored, and the event shows on the contact’s activity once you create one.
contact_idstring
The ID of an existing contact (con_…). Takes precedence over email. An ID that doesn’t match a contact in the workspace returns 422.
anonymous_idstring
Your own identifier for a visitor or device, up to 128 characters, for events you can’t tie to a person yet.
occurred_atstring | integer
When it happened: an ISO 8601 date-time or a timestamp in milliseconds. Default: now. Can be in the past, but not more than 24 hours in the future.
contextobject
Where the event happened: page (url, path, title, referrer, search), campaign (source, medium, name, term, content), locale and timezone. Unknown keys are dropped and long values are shortened.

Contacts are only looked up, never created. Emailit doesn’t store IP addresses with events.

Returns

Returns 201 Created with the event: object, id, type, created_at and data. data.object holds what was stored:

objectstring
workspace_event or custom_event.
namestring
The event name without its prefix.
propertiesobject
The validated properties.
contactobject | null
id and email of the contact the event belongs to. id is null when only the email is known. null when you sent neither.
anonymous_idstring | null
The anonymous_id you sent.
occurred_atstring
When it happened, in UTC.
sourcestring
api for this endpoint. Events from the tracking script have js, and test events sent from the dashboard have dashboard.
contextobject
The stored context. Left out when there’s none.

An API key with the events scope can’t read data, so it gets the event back without data, which holds the contact matched by email.

Status When
400 The body isn’t a JSON object.
403 The API key’s scope is neither full nor events, or the plan doesn’t include workspace and custom events: on Pay as you go, error is plan_required and required_plan is pro. Nothing is stored.
422 The event is invalid. errors is keyed by field, such as type or properties.total, and message repeats the first problem. Also returned for a w: event that isn’t defined, for a contact_id that doesn’t match a contact, and for a type the workspace hasn’t sent before once it uses its plan’s number of event types (100 on Pro, 1,000 on Business).
429 Too many requests in a minute, or the workspace reached its daily fair use limit for workspace and custom events (code: events_daily_limit). Nothing is stored. Try again after the number of seconds in the retry-after header.
POST/events
Terminal
curl -X POST https://api.emailit.com/v2/events \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "c:order.completed",
    "email": "jane@example.com",
    "properties": { "order_id": "1001", "total": 59.9, "currency": "EUR" },
    "occurred_at": "2026-10-19T09:30:00Z"
  }'
JSON
{
  "object": "event",
  "id": "evt_2yJm3Rk8VbN1sQ5tLwX7eZhD4cF",
  "type": "c:order.completed",
  "created_at": "2026-10-19T09:30:02.114000+00:00",
  "data": {
    "object": {
      "object": "custom_event",
      "name": "order.completed",
      "properties": { "order_id": "1001", "total": 59.9, "currency": "EUR" },
      "contact": { "id": "con_2wPq7Lm3XcN8bV1zKd4RtY6sHf9", "email": "jane@example.com" },
      "anonymous_id": null,
      "occurred_at": "2026-10-19T09:30:00.000Z",
      "source": "api"
    }
  }
}

Send events in a batch

Records up to 100 workspace and custom events in one request, for example when your backend syncs orders on a schedule. Works with API keys that have the full or the events scope, on Pro, Business and Custom plans.

The batch is all or nothing. If any event is invalid, none is stored, and the response lists every problem by the event’s position in the list.

POST/events/batch

Body parameters

eventsobject[]required
1 to 100 events. Each one takes the same fields as Send an event: type, properties, email, contact_id, anonymous_id, occurred_at and context.

Returns

Returns 201 Created with the stored events in data, in the order you sent them. Each item has object (event), id, type and created_at. Use Retrieve an event to read one with its data.

Status When
400 events is missing, empty or has more than 100 items.
403 The API key’s scope is neither full nor events, or the plan doesn’t include workspace and custom events: on Pay as you go, error is plan_required and required_plan is pro. Nothing is stored.
422 At least one event is invalid. Nothing is stored. errors is keyed by events.<index>.<field>, for example events.3.properties.total, counting from 0, and message repeats the first problem. An event of a type the workspace hasn’t sent before is invalid once the workspace uses its plan’s number of event types (100 on Pro, 1,000 on Business).
429 Too many requests in a minute, or the batch would take the workspace over its daily fair use limit for workspace and custom events (code: events_daily_limit). Nothing is stored. Try again after the number of seconds in the retry-after header.
POST/events/batch
Terminal
curl -X POST https://api.emailit.com/v2/events/batch \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      { "type": "c:order.completed", "email": "jane@example.com", "properties": { "order_id": "1001", "total": 59.9 } },
      { "type": "c:order.completed", "email": "omar@example.com", "properties": { "order_id": "1002", "total": 18 } },
      { "type": "w:customer.type", "contact_id": "con_2wPq7Lm3XcN8bV1zKd4RtY6sHf9", "properties": { "segment": "b2b" } }
    ]
  }'
JSON
{
  "data": [
    { "object": "event", "id": "evt_2yJm3Rk8VbN1sQ5tLwX7eZhD4cF", "type": "c:order.completed", "created_at": "2026-10-19T09:30:02.114000+00:00" },
    { "object": "event", "id": "evt_2yJm3Sa1XcP4uW8rMyB6fGjK0nT", "type": "c:order.completed", "created_at": "2026-10-19T09:30:02.114000+00:00" },
    { "object": "event", "id": "evt_2yJm3Td5ZeQ7vX2sNzC9hHkL3pU", "type": "w:customer.type", "created_at": "2026-10-19T09:30:02.114000+00:00" }
  ]
}

List events

Returns the events in your workspace, newest first. Every webhook delivery is built from one of these events, so you can use this endpoint to backfill events your endpoint missed. Requires an API key with full scope.

GET/events

Query parameters

pageinteger

Page number, starting at 1. Default 1. Pages deeper than 2,500 events ((page - 1) × limit > 2500) return 422.

limitinteger

Events per page, from 1 to 100. Default 100.

typestring

Event type, or a comma-separated list of types, for example email.delivered,email.bounced. Workspace and custom events keep their prefix, for example c:order.completed. See Event types.

scopestring

Only events of these scopes, comma-separated: system (events Emailit records, such as email.delivered), workspace (workspace-defined events, w:<name>) and custom (custom events, c:<name>). For example scope=workspace,custom. Default: every scope. An unknown scope returns 400.

include_databoolean

Set to true to include each event’s data payload. Default false, which returns only object, id, type and created_at.

matchstring

all (default) requires every filter. or matches any filter. See Filtering.

orderstring

Sort key for this list. See the sort keys below.

directionstring

asc or desc.

Filters and sort

List filters are one layer of key.condition=value query parameters. See Filtering for match, order, direction and the condition list per type.

Filter keys

KeyTypeConditionsNotes
typestringexact, not_exact, contains, not_contains, starts_with, ends_with, empty, not_empty
created_atdateexact, before, after, empty, not_empty

Sort keys

Pass order as one of these keys and direction as asc or desc: type, created_at

Without a created_at filter, the list only covers the last 2 days. To look further back, add one, for example created_at.after=2026-09-01T00:00:00Z. Older events are available for as long as your plan’s data retention keeps them.

Returns

Returns 200 OK with the events in data, plus next_page_url and previous_page_url (null at either end). The page URLs keep type, scope, limit and include_data.

Returns 422 with code: "events_offset_too_large" when the page is too deep. Narrow the date range or the types instead of paging further.

GET/events
Terminal
curl -X GET "https://api.emailit.com/v2/events?type=email.delivered" \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json"
JSON
{
  "data": [
    {
      "object": "event",
      "id": "evt_2xLc9Rr4Tn6Wb1Qm8Ks3Vf0Hd7a",
      "type": "email.delivered",
      "created_at": "2026-10-01T10:02:15.912000+00:00"
    }
  ],
  "next_page_url": "/v2/events?page=2&limit=100&type=email.delivered",
  "previous_page_url": null
}

Retrieve an event

Returns one event with its full data payload. The id is the same value webhooks send as event_id, so you can look up any event you received. Requires an API key with full scope.

GET/events/:id

Path parameters

idstringRequired

Event ID, for example evt_2xLc9Rr4Tn6Wb1Qm8Ks3Vf0Hd7a.

Returns

Returns 200 OK with the event: object (event), id, type, data and created_at. data.object has the same shape as in the webhook payload for that type; see the webhook event reference.

For workspace (w:) and custom (c:) events, data.object holds object (workspace_event or custom_event), name, properties, contact, anonymous_id, occurred_at, source, identity_verified for tracking script events that name a contact, and, when there is one, context. See Send an event.

Returns 404 with error: "Event not found" if the ID doesn’t exist in your workspace.

GET/events/{id}
Terminal
curl https://api.emailit.com/v2/events/evt_2xLc9Rr4Tn6Wb1Qm8Ks3Vf0Hd7a \
  -H "Authorization: Bearer your_api_key"
JSON
{
  "object": "event",
  "id": "evt_2xLc9Rr4Tn6Wb1Qm8Ks3Vf0Hd7a",
  "type": "email.delivered",
  "data": {
    "object": {
      "id": "em_2xLc8Mm3Pq5Vn0Ra7Jt2Wd9Fb4e",
      "object": "email",
      "from": "hello@acme.com",
      "to": "ada@example.com",
      "subject": "Your order has shipped",
      "status": "delivered",
      "meta": { "order_id": "1042" },
      "updated_at": "2026-10-01T10:02:14.307000+00:00",
      "created_at": "2026-10-01T10:02:11.583000+00:00"
    }
  },
  "created_at": "2026-10-01T10:02:15.912000+00:00"
}

Was this page helpful?

Thanks for the feedback.

Thanks, we read every message.