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

# Webhook Notifications

Webhook notifications let your backend react to events in your Membrane workspace — connections being created, disconnected, or archived.

## Setup

Configure a webhook URL in the Console under [Settings > Webhook Notifications](https://console.getmembrane.com/w/0/settings/webhook-notifications). Membrane sends a POST request to your URL whenever a matching event occurs.

## Event Types

### Connection Events

| Event                     | When it fires                                                    |
| ------------------------- | ---------------------------------------------------------------- |
| `connection.created`      | A new connection is established (OAuth completed, API key saved) |
| `connection.disconnected` | A connection lost access (token expired, credentials revoked)    |
| `connection.reconnected`  | A previously disconnected connection is restored                 |
| `connection.deleted`      | A connection is archived                                         |

### Flow Run Events

| Event               | When it fires                      |
| ------------------- | ---------------------------------- |
| `flowRun.queued`    | A flow run is queued for execution |
| `flowRun.started`   | A flow run begins executing        |
| `flowRun.completed` | A flow run finishes successfully   |
| `flowRun.failed`    | A flow run fails with an error     |
| `flowRun.stopped`   | A flow run is manually stopped     |

### Alert Events

| Event           | When it fires                          |
| --------------- | -------------------------------------- |
| `alert.created` | An alert is created or becomes ongoing |

## Payloads

Each webhook POST body contains an `eventType` field and a `data` object. The shape of `data` depends on the event category.

### Connection events

```json theme={null}
{
  "eventType": "connection.created",
  "data": {
    "connection": {
      "id": "con_abc123",
      "integrationId": "int_xyz789",
      "integrationKey": "slack",
      "name": "Slack",
      "disconnected": false,
      "tenantId": "tenant-123"
    }
  }
}
```

### Flow run events

```json theme={null}
{
  "eventType": "flowRun.completed",
  "data": {
    "flowRun": {
      "id": "fr_abc123",
      "connectionFlowId": "cf_xyz789",
      "integrationFlowId": "if_abc456",
      "state": "completed",
      "startTime": "2024-01-15T10:30:00.000Z",
      "endTime": "2024-01-15T10:30:05.123Z",
      "startNodeKey": "trigger",
      "launchedBy": { "type": "app-event-trigger" }
    }
  }
}
```

The `flowRun.failed` event includes an `errors` array on the flow run object with details about what went wrong.

### Alert events

```json theme={null}
{
  "eventType": "alert.created",
  "data": {
    "alert": {
      "id": "alrt_abc123",
      "type": "connection_disconnected",
      "severity": "warning",
      "description": "Slack connection lost access",
      "status": "ongoing",
      "workspaceId": "ws_xyz789",
      "workspaceUrl": "https://console.getmembrane.com/w/org-workspace-id",
      "createdAt": "2024-01-15T10:30:00.000Z"
    }
  }
}
```

## Handling Webhooks

Example Express.js endpoint:

```typescript theme={null}
app.post('/api/membrane-webhook', async (req, res) => {
  const { eventType, data } = req.body

  switch (eventType) {
    case 'connection.created':
      // Run an action on the new connection
      const membrane = new MembraneClient({ token: process.env.MEMBRANE_ACCESS_TOKEN })
      await membrane
        .action('send-slack-message')
        .run({ channel: 'general', text: 'Your app is now connected!' }, { connectionId: data.connection.id })
      break
    case 'connection.disconnected':
      // Notify user to reconnect
      break
    case 'flowRun.failed':
      // Log or alert on flow run failure
      console.error('Flow run failed', data.flowRun.errors)
      break
    case 'alert.created':
      // Forward alert to your monitoring system
      break
  }

  res.sendStatus(200)
})
```

## Retry Behavior

If your endpoint returns a non-2xx status code, Membrane retries with exponential backoff.

## See Also

* [Connections](/docs/how-membrane-works/connections) — connection lifecycle and management
* [Events](/docs/how-membrane-works/events) — data events from external apps (distinct from webhook notifications)
