> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gork.email/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook Event Types

> The five live email lifecycle events and their exact payload schemas.

Gork emits five events. Subscribe per endpoint with `subscribedEvents` (or `"*"` for all). Every delivery also carries `X-Gork-Event` with the event name, so one endpoint can route on the header.

## email.received

A new inbound email arrived, was parsed, sanitized, and stored. This is the event that wakes your agent.

```json theme={null}
{
  "event": "email.received",
  "message": {
    "id": "msg_908123acdf00000000000001",
    "inboxId": "inb_728af980b4e0000000000001",
    "threadId": "thd_128bca90f400000000000001",
    "agent": { "id": "agt_128bca90f400000000000001", "name": "Alex (SDR)" },
    "from": { "address": "prospect@acmecorp.com", "name": "Marcus Reid" },
    "to": ["alex@outbound.yourdomain.com"],
    "subject": "Re: Partnership proposal",
    "text": "Hi Alex,\n\nWe would love to connect this week.",
    "html": "<p>Hi Alex,<br/><br/>We would love to connect this week.</p>",
    "attachmentsCount": 0,
    "receivedAt": "2026-09-22T12:34:56.789Z"
  },
  "sender": {
    "kind": "human",
    "confidence": "low",
    "evidence": []
  }
}
```

`agent` is `null` when the inbox has no agent attached. `sender.kind` is `human`, `agent`, or `automated` — classified from automation headers (`Auto-Submitted`, `X-Autoreply`, `Precedence`) and out-of-office subject patterns, with the supporting `evidence` included. Branch on it: an `automated` sender is usually an out-of-office reply, not a human waiting for an answer.

## email.sent

An outbound send through `POST /v1/messages/send` was accepted by the provider.

```json theme={null}
{
  "event": "email.sent",
  "message": {
    "id": "msg_908123acdf00000000000002",
    "inboxId": "inb_728af980b4e0000000000001",
    "threadId": "thd_128bca90f400000000000001",
    "to": ["prospect@acmecorp.com"],
    "subject": "Re: Partnership proposal",
    "status": "delivered",
    "providerMessageId": "01000123456789ab-abcdef01-2345-6789-abcd-ef0123456789-000000",
    "sentAt": "2026-09-22T12:35:10.000Z"
  }
}
```

## email.bounced

The recipient mail server rejected the message. `reason` is `hard_bounce` (permanent — the address is automatically suppressed) or `soft_bounce` (transient — the message status is updated but the address is not suppressed). `messageId` is the Gork message id when the bounce could be matched to a sent message, otherwise `null`.

```json theme={null}
{
  "event": "email.bounced",
  "email": "gone@example.com",
  "reason": "hard_bounce",
  "diagnostic": "smtp; 550 5.1.1 user unknown",
  "messageId": "msg_908123acdf00000000000002",
  "timestamp": "2026-09-22T12:36:00.000Z"
}
```

## email.complained

A recipient flagged the message as spam via a feedback loop. The address is automatically suppressed — stop mailing it.

```json theme={null}
{
  "event": "email.complained",
  "email": "annoyed@example.com",
  "reason": "complaint",
  "diagnostic": null,
  "messageId": "msg_908123acdf00000000000002",
  "timestamp": "2026-09-22T12:37:00.000Z"
}
```

## email.unsubscribed

A recipient completed one-click unsubscribe. The address is suppressed with reason `unsubscribed` — remove it from future campaigns.

```json theme={null}
{
  "event": "email.unsubscribed",
  "email": "tired@example.com",
  "organizationId": "org_9f2c41ab77d04e1c90ab33de",
  "unsubscribedAt": "2026-09-22T12:38:00.000Z"
}
```

<Note>
  Deliveries are at-least-once: a crash between the customer POST and bookkeeping can redeliver the same attempt. Dedupe on `X-Gork-Delivery`, which is stable per delivery attempt.
</Note>
