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.
This page covers the management API for webhook subscriptions. For the format of incoming deliveries (headers, signatures, retry policy) see the Webhooks guide.
List event types
Scope: webhooks:manage. Returns the full list of event types you can subscribe to, plus a UI grouping.
Response 200
{
"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
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
{
"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
POST /webhooks/subscriptions
Scope: webhooks:manage.
Request body
{
"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 per subscription. |
external_id | no | Strongly recommended. See idempotency note below. |
name | no | Human-readable label, ≤ 255 chars. |
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.
Response 201 (new subscription)
{
"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", "..."]
}
The
secret is returned
only at creation. Store it — it’s needed to verify webhook signatures (see
Verifying the signature). If you lose it, delete the subscription and create a new one.
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
GET /webhooks/subscriptions/{id}
Scope: webhooks:manage. Single subscription.
Delete a subscription
DELETE /webhooks/subscriptions/{id}
Scope: webhooks:manage. Hard-deletes external-platform subscriptions.
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.
Response 200
{ "id": "wh_...", "deleted": true }