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

# Webhook Events

> Every event BundleUp can send, when it fires, and what its payload contains.

Every delivery has the same envelope (`action`, `workspaceId`, `webhookId`, `webhookTimestamp`, `data`; see [Webhooks](/docs/guides/webhooks/overview#request-format)). The shape of `data` depends on whether the event is about an integration or a connection.

## Connection events

| Event | Fires when |
| - | - |
| `connection.created` | A user completes the [authorization flow](/docs/guides/auth/authorization-flow), or a connection is created with `POST /v1/connections`. Fires whether or not you exchange the code. |
| `connection.updated` | A connection’s external ID is changed, in the dashboard or with `PATCH /v1/connections/{id}`. |
| `connection.refreshed` | A connection’s access token is refreshed, automatically or from the dashboard. See [Connection lifecycle](/docs/guides/auth/connection-lifecycle). |
| `connection.deleted` | A connection is deleted, in the dashboard or with `DELETE /v1/connections/{id}`. |
| `connection.disabled` | Reserved. Not currently sent: BundleUp doesn’t disable connections automatically. You can subscribe to it now. |

**`data` for connection events:**

```json theme={null}
{
  "id": "conn_abc123",
  "externalId": "user_42",
  "integrationId": "cm0integration789",
  "createdAt": "2026-09-12T18:00:00.000Z",
  "updatedAt": "2026-09-12T18:05:00.000Z",
  "refreshedAt": "2026-09-12T18:05:00.000Z"
}
```

| Field | Description |
| - | - |
| `id` | The connection ID. |
| `externalId` | Your external ID, or `null`. |
| `integrationId` | The integration’s BundleUp ID (not its identifier). Look it up with `GET /v1/integrations/{id}`. |
| `createdAt` | When the connection was created. |
| `updatedAt` | When it last changed. |
| `refreshedAt` | When its token was last refreshed, or `null`. |

For `connection.deleted`, the connection may already be gone when the payload is built, in which case `data` contains only `{ "id": "conn_abc123" }`.

## Integration events

| Event | Fires when |
| - | - |
| `integration.created` | An integration is created in the dashboard. |
| `integration.updated` | An integration’s settings or scopes are changed. |
| `integration.deleted` | An integration is deleted. Its connections are deleted with it. |

**`data` for integration events:**

```json theme={null}
{
  "id": "cm0integration789",
  "type": "github",
  "identifier": "github"
}
```

| Field | Description |
| - | - |
| `id` | The integration’s BundleUp ID. |
| `type` | The provider. |
| `identifier` | The identifier you gave the integration, used in the authorization URL. |

As with connections, `integration.deleted` may carry only `{ "id": "..." }`.

## Handling events

A typical handler only needs to act on a few events:

```typescript theme={null}
switch (event.action) {
  case 'connection.created':
    // Link the connection to your user, using externalId
    await db.connections.upsert({
      id: event.data.id,
      userId: event.data.externalId,
      integrationId: event.data.integrationId,
    });
    break;

  case 'connection.deleted':
    // Stop using it
    await db.connections.delete(event.data.id);
    break;

  default:
    // Ignore events you don't need
    break;
}
```

Subscribe only to the events you handle. You choose them per webhook in **Settings → Webhooks**.


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