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

# Events

> Every webhook event and the fields in its payload.

Every delivery has the same envelope. `event` is one of the names below and `data` is that event's payload.

```json theme={null}
{
  "event": "SESSION_COMPLETED",
  "timestamp": "2026-09-17T01:15:02.318Z",
  "data": { ... }
}
```

<ResponseField name="event" type="string" required>
  The event name.
</ResponseField>

<ResponseField name="timestamp" type="string" required>
  When the event was raised, ISO 8601 in UTC.
</ResponseField>

<ResponseField name="data" type="object" required>
  Event-specific payload, documented per event below.
</ResponseField>

Package events describe the package as a whole. Session events describe one recipient's turn on a package. A recipient's `recipientName` and `recipientEmail` are nullable because a session can exist before the recipient is known.

Every event also carries the package's custom field values:

<ResponseField name="metadata" type="object" required>
  The package's custom field values, keyed by the custom field's key. Only fields with a value appear; `{}` when none are set. Keys are managed under **Settings → Custom fields**.
</ResponseField>

The same schemas are published in the OpenAPI spec as `WebhookPayload_<EVENT>` components, so you can generate types for your listener.

## Package events

### PACKAGE\_SENT

Raised once when a package is sent and its signing sessions are created.

<ResponseField name="packageId" type="string" required />

<ResponseField name="packageTitle" type="string" required />

<ResponseField name="signerCount" type="integer" required>
  Number of recipients who must act on the package.
</ResponseField>

<ResponseField name="sessionsSent" type="integer" required>
  Number of sessions invited immediately. Lower than `signerCount` when recipients sign in order.
</ResponseField>

```json theme={null}
{
  "event": "PACKAGE_SENT",
  "timestamp": "2026-09-17T01:12:50.000Z",
  "data": {
    "packageId": "pkg_9f3c2e",
    "packageTitle": "Employment agreement: Ana Reid",
    "signerCount": 2,
    "sessionsSent": 1,
    "metadata": { "employee_id": "E-1042" }
  }
}
```

### PACKAGE\_COMPLETED

Raised when the last recipient finishes and the package becomes `COMPLETED`.

<ResponseField name="packageId" type="string" required />

<ResponseField name="packageTitle" type="string" required />

<ResponseField name="completedAt" type="string" required>
  ISO 8601 timestamp.
</ResponseField>

```json theme={null}
{
  "event": "PACKAGE_COMPLETED",
  "timestamp": "2026-09-17T03:40:11.000Z",
  "data": {
    "packageId": "pkg_9f3c2e",
    "packageTitle": "Employment agreement: Ana Reid",
    "completedAt": "2026-09-17T03:40:10.884Z",
    "metadata": { "employee_id": "E-1042" }
  }
}
```

### PACKAGE\_DECLINED

Raised when a recipient's decline ends the package as `DECLINED`.

<ResponseField name="packageId" type="string" required />

<ResponseField name="packageTitle" type="string" required />

<ResponseField name="reason" type="string | null" required>
  The reason the recipient gave, if any.
</ResponseField>

```json theme={null}
{
  "event": "PACKAGE_DECLINED",
  "timestamp": "2026-09-17T02:05:30.000Z",
  "data": {
    "packageId": "pkg_9f3c2e",
    "packageTitle": "Employment agreement: Ana Reid",
    "reason": "Start date is wrong",
    "metadata": { "employee_id": "E-1042" }
  }
}
```

### PACKAGE\_VOIDED

Raised when a package is voided by a member or through the API.

<ResponseField name="packageId" type="string" required />

<ResponseField name="voidedBy" type="string" required>
  Email address of the member who voided it, or `system`.
</ResponseField>

```json theme={null}
{
  "event": "PACKAGE_VOIDED",
  "timestamp": "2026-09-17T02:30:00.000Z",
  "data": {
    "packageId": "pkg_9f3c2e",
    "voidedBy": "ops@example.com",
    "metadata": { "employee_id": "E-1042" }
  }
}
```

### PACKAGE\_EXPIRED

Raised when a package passes its expiry date unsigned.

<ResponseField name="packageId" type="string" required />

<ResponseField name="packageTitle" type="string" required />

```json theme={null}
{
  "event": "PACKAGE_EXPIRED",
  "timestamp": "2026-10-17T00:00:05.000Z",
  "data": {
    "packageId": "pkg_9f3c2e",
    "packageTitle": "Employment agreement: Ana Reid",
    "metadata": { "employee_id": "E-1042" }
  }
}
```

## Session events

All session events share these fields:

<ResponseField name="packageId" type="string" required />

<ResponseField name="sessionId" type="string" required>
  Matches `recipientSessions[].id` on `GET /api/v1/packages/{packageId}`.
</ResponseField>

<ResponseField name="recipientName" type="string | null" required />

<ResponseField name="recipientEmail" type="string | null" required />

### SESSION\_SENT

Raised when a recipient's invitation is sent. In a sequential package this happens when it becomes their turn.

<ResponseField name="packageTitle" type="string" required />

```json theme={null}
{
  "event": "SESSION_SENT",
  "timestamp": "2026-09-17T01:12:50.000Z",
  "data": {
    "packageId": "pkg_9f3c2e",
    "sessionId": "ses_71ab",
    "recipientName": "Ana Reid",
    "recipientEmail": "ana@example.com",
    "packageTitle": "Employment agreement: Ana Reid",
    "metadata": { "employee_id": "E-1042" }
  }
}
```

### SESSION\_OPENED

Raised when the recipient opens their session. Carries the shared fields only.

```json theme={null}
{
  "event": "SESSION_OPENED",
  "timestamp": "2026-09-17T01:20:14.000Z",
  "data": {
    "packageId": "pkg_9f3c2e",
    "sessionId": "ses_71ab",
    "recipientName": "Ana Reid",
    "recipientEmail": "ana@example.com",
    "metadata": { "employee_id": "E-1042" }
  }
}
```

### SESSION\_COMPLETED

Raised when the recipient finishes their session.

<ResponseField name="packageTitle" type="string" required />

```json theme={null}
{
  "event": "SESSION_COMPLETED",
  "timestamp": "2026-09-17T01:26:02.000Z",
  "data": {
    "packageId": "pkg_9f3c2e",
    "sessionId": "ses_71ab",
    "recipientName": "Ana Reid",
    "recipientEmail": "ana@example.com",
    "packageTitle": "Employment agreement: Ana Reid",
    "metadata": { "employee_id": "E-1042" }
  }
}
```

### SESSION\_DECLINED

Raised when the recipient declines to sign. A `PACKAGE_DECLINED` event follows when the decline ends the package.

<ResponseField name="packageTitle" type="string" required />

<ResponseField name="reason" type="string | null" required>
  The reason the recipient gave, if any.
</ResponseField>

```json theme={null}
{
  "event": "SESSION_DECLINED",
  "timestamp": "2026-09-17T02:05:29.000Z",
  "data": {
    "packageId": "pkg_9f3c2e",
    "sessionId": "ses_71ab",
    "recipientName": "Ana Reid",
    "recipientEmail": "ana@example.com",
    "packageTitle": "Employment agreement: Ana Reid",
    "reason": "Start date is wrong",
    "metadata": { "employee_id": "E-1042" }
  }
}
```
