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

# Webhook subscriptions

> List supported events and manage subscription destinations programmatically.

This page covers the **management** API for webhook subscriptions. For the format of incoming deliveries (headers, signatures, retry policy) see the [Webhooks guide](/webhooks).

***

## List event types

```http theme={null}
GET /webhooks/events
```

**Scope:** `webhooks:manage`. Returns the full list of event types you can subscribe to, plus a UI grouping.

### Response 200

```json theme={null}
{
  "events": [
    "lead.created", "lead.updated", "lead.stage_changed",
    "lead.assigned", "lead.unassigned",
    "lead.won", "lead.lost", "lead.deleted",
    "lead.note_added", "lead.communication_logged",
    "project.created", "project.updated", "project.deleted",
    "unit.created", "unit.updated", "unit.status_changed"
  ],
  "groups": {
    "Leads": ["lead.created", "lead.updated", "lead.stage_changed", "lead.assigned", "lead.unassigned", "lead.won", "lead.lost", "lead.deleted", "lead.note_added", "lead.communication_logged"],
    "Projects": ["project.created", "project.updated", "project.deleted"],
    "Units": ["unit.created", "unit.updated", "unit.status_changed"]
  }
}
```

Use the `groups` object to build a tidy dropdown in your integration UI. The `events` array is the flat list for validation.

***

## List subscriptions

```http theme={null}
GET /webhooks/subscriptions
```

**Scope:** `webhooks:manage`. Lists subscriptions managed by the calling client (Zapier / Make / API integrations only — dashboard-managed subscriptions stay scoped to the dashboard).

### Response 200

```json theme={null}
{
  "data": [
    {
      "id": "wh_...",
      "target_url": "https://hook.example.com/incoming",
      "events": ["lead.created"],
      "external_id": "make-scenario-42",
      "managed_by": "make",
      "is_active": true,
      "created_at": "2026-04-29T18:04:15.000Z"
    }
  ]
}
```

***

## Create a subscription

```http theme={null}
POST /webhooks/subscriptions
```

**Scope:** `webhooks:manage`.

### Request body

```json theme={null}
{
  "target_url": "https://hook.example.com/incoming",
  "event": "lead.created",
  "external_id": "make-scenario-42",
  "name": "Make: new leads"
}
```

| Field         | Required | Notes                                                       |
| ------------- | -------- | ----------------------------------------------------------- |
| `target_url`  | yes      | HTTPS URL to receive events.                                |
| `event`       | yes      | One [event type](/enums#webhookeventtype) per subscription. |
| `external_id` | no       | Strongly recommended. See idempotency note below.           |
| `name`        | no       | Human-readable label, ≤ 255 chars.                          |

<Tip>**Always pass `external_id`** when you can — it's typically the scenario / zap / flow ID on your side. If the subscription already exists for that `external_id`, the call is idempotent and returns `200` with the existing record instead of `409`. This is what makes Make / Zapier retries safe across replays.</Tip>

### Response 201 (new subscription)

```json theme={null}
{
  "id": "wh_...",
  "target_url": "https://hook.example.com/incoming",
  "event": "lead.created",
  "external_id": "make-scenario-42",
  "managed_by": "make",
  "secret": "<hex secret>",
  "supported_events": ["lead.created", "..."]
}
```

<Warning>The `secret` is returned **only at creation**. Store it — it's needed to verify webhook signatures (see [Verifying the signature](/webhooks#verifying-the-signature)). If you lose it, delete the subscription and create a new one.</Warning>

### Response 200 (idempotent replay)

When the `external_id` already exists for this client, you get the existing subscription with the same body **but no `secret`**. Your stored secret from the original create is still valid.

### Errors

* `403 FORBIDDEN` — `webhooks:manage` scope missing, or webhook-endpoint plan limit reached.

***

## Get a subscription

```http theme={null}
GET /webhooks/subscriptions/{id}
```

**Scope:** `webhooks:manage`. Single subscription.

***

## Delete a subscription

```http theme={null}
DELETE /webhooks/subscriptions/{id}
```

**Scope:** `webhooks:manage`. Hard-deletes external-platform subscriptions.

<Warning>Dashboard-managed subscriptions can only be deleted from the FlowEstate UI — the API returns `403` for those. This protects users from third-party connectors accidentally removing subscriptions they didn't create.</Warning>

### Response 200

```json theme={null}
{ "id": "wh_...", "deleted": true }
```
