> ## Documentation Index
> Fetch the complete documentation index at: https://pigeonpost-developer.27communication.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Events

> Every event the engine sends, and what's in it.

## The envelope

Every call to your endpoint carries one event, always in the same envelope:

```json theme={null}
{
  "object": "Event",
  "id": "evt_7c1d2e3f4a5b46c7d8e9f0a1b2c3d4e5",
  "type": "email.new",
  "created_at": "2026-10-06T09:12:03Z",
  "account_id": "acc_ba1fa6938d8548298e8ce62e4b4b4e99",
  "endpoint_id": "we_e3f1a2b4c5d64e7f8a9b0c1d2e3f4a5b",
  "data": { "email": { "object": "Email", "…": "…" } }
}
```

| Field | |
| - | - |
| `object` | Always `Event` |
| `id` | The event's `evt_…` id. The same on every endpoint the event goes to, and on every retry |
| `type` | The event, for example `email.new` |
| `created_at` | When it happened |
| `account_id` | The account it's about (`acc_…`) |
| `endpoint_id` | The endpoint this call is for (`we_…`) |
| `data` | Depends on `type` (below) |

Events go out for changes **after** the account connected. An endpoint only receives the events in its `trigger_events`.

## Email events

`data` is `{ "email": … }`: the full [email object](/emails/retrieve).

| Event | When |
| - | - |
| `email.new` | A new email arrived in the mailbox, or was sent (through the API, or by the user from their own email app). Sent emails have `role: "SENT"`; `origin` is `api` when sent through this API |
| `email.new.bounce` | A new email that is a bounce: a delivery status report, or an email from `mailer-daemon` or `postmaster`. Sent instead of `email.new` |
| `email.update` | Read, unread, starred, unstarred, moved to another folder, archived, or moved to trash |
| `email.delete` | Deleted for good at the provider (for example, emptied from Trash) |
| `email.draft.new` | A new draft appeared in the Drafts folder. `data.email` is a Draft (`object: "Draft"`, with its `draft_id`) |
| `email.draft.delete` | A draft left the Drafts folder: deleted, or sent |

```json email.new theme={null}
{
  "object": "Event",
  "id": "evt_7c1d2e3f4a5b46c7d8e9f0a1b2c3d4e5",
  "type": "email.new",
  "created_at": "2026-10-06T09:12:03Z",
  "account_id": "acc_ba1fa6938d8548298e8ce62e4b4b4e99",
  "endpoint_id": "we_e3f1a2b4c5d64e7f8a9b0c1d2e3f4a5b",
  "data": {
    "email": {
      "object": "Email",
      "id": "email_94a0d77db739407e932c3b97fef44aac",
      "account_id": "acc_ba1fa6938d8548298e8ce62e4b4b4e99",
      "subject": "Meeting tomorrow",
      "from_attendee": { "display_name": "Ana Lee", "identifier": "ana@example.com" },
      "to_attendees": [{ "display_name": "", "identifier": "sales@acme.com" }],
      "date": "2026-10-06T09:12:00Z",
      "role": "INBOX",
      "unread": true,
      "body": "<p>Hi, see the agenda attached.</p>",
      "has_attachments": true,
      "attachments": [{ "id": "att_6f2e8c1a0d4b4f7e9a512c3b8d7e1f00", "name": "agenda.pdf", "extension": "pdf", "size": 48211, "mime": "application/pdf", "cid": null, "inline": false }],
      "origin": "external",
      "tracking_id": null,
      "…": "…"
    }
  }
}
```

The email in `data.email` is complete, body and attachment list included, so most apps don't need to call the API again. Attachments themselves are [downloaded separately](/emails/attachments).

## Folder events

`data` is `{ "folder": … }`: the [folder object](/emails/folders).

| Event | When |
| - | - |
| `email.folder.create` | A folder was created (for Gmail, a label shown in IMAP) |
| `email.folder.update` | A folder was renamed, or its role or parent changed |
| `email.folder.delete` | A folder was deleted |

```json email.folder.create theme={null}
{
  "object": "Event",
  "id": "evt_1a2b3c4d5e6f47a8b9c0d1e2f3a4b5c6",
  "type": "email.folder.create",
  "created_at": "2026-10-06T10:30:00Z",
  "account_id": "acc_ba1fa6938d8548298e8ce62e4b4b4e99",
  "endpoint_id": "we_e3f1a2b4c5d64e7f8a9b0c1d2e3f4a5b",
  "data": {
    "folder": { "object": "Folder", "id": "fld_4d5e6f7a8b9c40d1e2f3a4b5c6d7e8f9", "account_id": "acc_ba1fa6938d8548298e8ce62e4b4b4e99", "provider_id": "Clients", "name": "Clients", "role": "UNKNOWN", "parent_id": null, "nb_mails": 0, "nb_unread": 0 }
  }
}
```

A new account's existing folders don't send folder events when it first syncs.

## Tracking events

| Event | When |
| - | - |
| `tracking.open` | A tracked email was opened |
| `tracking.click` | A tracked link was clicked |

`data` is `{ tracking_id, label, message_id, email_id, date, ip, user_agent }`, plus `url` for clicks. See [Open and click tracking](/emails/tracking#events).

## Account events

| Event | When | `data` |
| - | - | - |
| `account.add` | A new account was connected | `{ "account": Account, "state": "…" }` |
| `account.reconnect` | An account was reconnected, or a connected mailbox was connected again | `{ "account": Account, "state": "…" }` |
| `account.remove` | An account was removed | `{ "account": { id, user_id, name, provider } }` |
| `account.status.running` | The status became `running` | `{ status, previous_status, status_detail }` |
| `account.status.errored` | The status became `errored` | `{ status, previous_status, status_detail }` |
| `account.status.disconnected` | The status became `disconnected` | `{ status, previous_status, status_detail }` |
| `account.initial_sync.running` | The [initial sync](/accounts/initial-sync) (import of existing mail) started | `{ "initial_sync": { status, started_at, completed_at, days, imported } }` |
| `account.initial_sync.completed` | The initial sync finished: fetch the imported mail with [List emails](/emails/list) | `{ "initial_sync": { … } }` |
| `account.initial_sync.failed` | The initial sync gave up after 5 failed tries | `{ "initial_sync": { … } }` |

`state` is the value you passed in the [auth intent](/accounts/imap) (`POST /api/v1/auth/intent`). Use it to find your user.

```json account.add theme={null}
{
  "object": "Event",
  "id": "evt_3f4a5b6c7d8e49f0a1b2c3d4e5f6a7b8",
  "type": "account.add",
  "created_at": "2026-10-06T09:01:30Z",
  "account_id": "acc_ba1fa6938d8548298e8ce62e4b4b4e99",
  "endpoint_id": "we_e3f1a2b4c5d64e7f8a9b0c1d2e3f4a5b",
  "data": {
    "account": {
      "object": "Account",
      "id": "acc_ba1fa6938d8548298e8ce62e4b4b4e99",
      "user_id": "ana@acme.com",
      "name": "ana@acme.com",
      "provider": "imap",
      "status": "running",
      "status_detail": "",
      "is_locked": false,
      "metadata": {},
      "connection_params": {
        "mail": {
          "imap_host": "imap.acme.com", "imap_port": 993, "imap_user": "ana@acme.com", "imap_encryption": "SSL",
          "smtp_host": "smtp.acme.com", "smtp_port": 465, "smtp_user": "ana@acme.com", "smtp_encryption": "SSL"
        }
      },
      "created_at": "2026-10-06T09:01:28Z",
      "last_synced_at": null
    },
    "state": "user-42"
  }
}
```

```json account.status.disconnected theme={null}
{
  "object": "Event",
  "id": "evt_2b3c4d5e6f7a48b9c0d1e2f3a4b5c6d7",
  "type": "account.status.disconnected",
  "created_at": "2026-10-06T11:02:16Z",
  "account_id": "acc_ba1fa6938d8548298e8ce62e4b4b4e99",
  "endpoint_id": "we_e3f1a2b4c5d64e7f8a9b0c1d2e3f4a5b",
  "data": {
    "status": "disconnected",
    "previous_status": "running",
    "status_detail": "the mail provider rejected the credentials: invalid_grant"
  }
}
```

See [Account status](/accounts/status) for each status and what to do. For `disconnected`, ask the user for the new password and [reconnect the account](/accounts/imap#reconnect-or-change-settings).

Imported mail from an [initial sync](/accounts/initial-sync) sends **no** `email.new`; `account.initial_sync.completed` tells you when to fetch it:

```json account.initial_sync.completed theme={null}
{
  "object": "Event",
  "id": "evt_5d6e7f8a9b0c41d2e3f4a5b6c7d8e9f0",
  "type": "account.initial_sync.completed",
  "created_at": "2026-10-06T09:03:10Z",
  "account_id": "acc_ba1fa6938d8548298e8ce62e4b4b4e99",
  "endpoint_id": "we_e3f1a2b4c5d64e7f8a9b0c1d2e3f4a5b",
  "data": {
    "initial_sync": {
      "status": "completed",
      "started_at": "2026-10-06T09:01:32Z",
      "completed_at": "2026-10-06T09:03:10Z",
      "days": 30,
      "imported": 412
    }
  }
}
```

## Headers

| Header | |
| - | - |
| `X-Email-Engine-Event` | The event type, for example `email.new` |
| `X-Email-Engine-Delivery` | The id of this call (`whc_…`), the same as in the [delivery log](/webhooks/overview#delivery-log). It's the same on every retry |
| `X-Email-Engine-Signature` | `sha256=…`. See [Verify signatures](/webhooks/signatures) |

Your endpoint's own `headers` are sent too.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.