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

# Webhooks Overview

> Receive real-time notifications when Zenstep events occur — broken steps, flow completions, and more.

## What are Zenstep webhooks?

Webhooks allow Zenstep to push event notifications to your server in real time. Instead of polling the API, you register a URL and Zenstep sends an HTTP POST request to it whenever a relevant event occurs.

***

## Supported events

| Event            | Trigger                                                |
| ---------------- | ------------------------------------------------------ |
| `step.broken`    | A step's DOM element cannot be found (health = broken) |
| `step.recovered` | A previously broken step is found again                |
| `flow.completed` | A user completes a flow                                |
| `flow.dismissed` | A user dismisses a flow                                |

<Note>
  Webhook alerts (`step.broken`, `step.recovered`) require the **Grow** plan or
  higher.
</Note>

***

## Setting up a webhook

1. Go to **Settings → Notifications** in the dashboard.
2. Click **Add webhook endpoint**.
3. Enter your endpoint URL (must be HTTPS).
4. Select which events to subscribe to.
5. Click **Save**.

Zenstep will immediately send a test ping to your endpoint to verify it's reachable.

***

## Delivery guarantees

* Webhooks are delivered **at least once** — your endpoint may receive the same event multiple times in rare failure scenarios. Make your handler idempotent.
* Zenstep retries failed deliveries with exponential backoff for up to **72 hours**.
* A delivery is considered successful if your endpoint returns a `2xx` status code within **10 seconds**.

***

## Retry schedule

| Attempt | Delay      |
| ------- | ---------- |
| 1       | Immediate  |
| 2       | 5 minutes  |
| 3       | 30 minutes |
| 4       | 2 hours    |
| 5       | 8 hours    |
| 6       | 24 hours   |
| 7–10    | 24 hours   |

After 10 failed attempts (approximately 72 hours), the delivery is abandoned.

***

## Responding to webhooks

Your endpoint must return a `2xx` status code within **10 seconds**. If you need to do long-running processing, acknowledge the webhook immediately and process asynchronously:

```javascript theme={null}
// Express.js example
app.post("/webhooks/zenstep", express.json(), (req, res) => {
  // Acknowledge immediately
  res.sendStatus(200);

  // Process asynchronously
  processWebhook(req.body).catch(console.error);
});
```

***

## Testing webhooks

Use [ngrok](https://ngrok.com) or [Hookdeck](https://hookdeck.com) to expose a local server during development:

```bash theme={null}
ngrok http 3000
# Then use the ngrok URL as your webhook endpoint in the dashboard
```

Or use the **Test** button next to each webhook endpoint in the dashboard — it sends a sample payload.
