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

# Webhooks

> Send workspace events to your own URL in real time.

A **webhook** tells Nekt to notify your own system when something happens in the workspace. You register an `https` URL and the events you care about, and whenever one of those events occurs, Nekt sends a signed JSON payload to that URL. Use webhooks to react to pipeline failures, trigger downstream automations, or keep an external system in sync with activity in Nekt.

Find them in **Settings → Webhooks**.

<Info>
  Webhooks are available on **paid plans** (Starter, Growth, and Custom). Only **owners and admins** can view and manage them.
</Info>

<Note>
  Webhooks and [Alerts](/workspace/alerts) complement each other. Alerts send **email** when a pipeline fails; webhooks send a **machine-readable payload** for any subscribed event to a system you control.
</Note>

## How it works

1. You create a webhook with a name, an `https` URL, and a list of events to subscribe to.
2. When a subscribed event happens, Nekt POSTs a signed JSON payload to your URL.
3. Nekt records the result as a **delivery** you can inspect and resend.

Each delivery is signed following the [Standard Webhooks](https://www.standardwebhooks.com/) specification, so your receiver can verify it with any of the published libraries.

## Create a webhook

<Steps>
  <Step title="Open Webhooks">
    Go to **Settings → Webhooks**.
  </Step>

  <Step title="Add the endpoint">
    Enter a **name** and the **`https` URL** that will receive the events. HTTP (non-TLS), localhost, and private addresses are rejected.
  </Step>

  <Step title="Choose events">
    Pick the events to subscribe to from the checklist, grouped by resource. Select at least one.
  </Step>

  <Step title="Save the signing secret">
    After you create the webhook, Nekt shows the **signing secret once**. Copy it and store it securely—you use it to verify payloads, and it is not shown again.
  </Step>
</Steps>

<Warning>
  The signing secret is shown only when you create the webhook or rotate its secret. If you lose it, rotate the secret to get a new one.
</Warning>

## Events

Events are named `resource.action` in the past tense, for example `source.created`, `pipeline_run.failed`, `permission.revoked`, or `user.joined`. The create and edit dialog groups them by resource so you can subscribe to a whole group at once.

| Group | Example events |
| - | - |
| `pipeline_run` | `pipeline_run.succeeded`, `pipeline_run.failed`, `pipeline_run.canceled` |
| `source` / `transformation` / `destination` | `.created`, `.updated`, `.status_updated`, `.trigger_updated`, `.deleted` |
| `layer`, `table`, `volume` | `layer.created`, `table.deleted`, `volume.created` |
| `permission`, `permission_group` | `permission.granted`, `permission.revoked`, `permission_group.created` |
| `invitation`, `user`, `access_request` | `invitation.created`, `user.joined`, `access_request.accepted` |
| `secret`, `mcp_token`, `webhook`, `billing` | `secret.created`, `mcp_token.rotated`, `billing.plan_selected` |

<Note>
  Organization-level events (invitations, access requests, a user joining, billing) are delivered to every subscribing webhook across the organization's workspaces, each with its own `workspace` block in the payload.
</Note>

## Payload and verification

Nekt POSTs a JSON envelope:

```json theme={null}
{
  "id": "6f1c...",
  "event": "pipeline_run.failed",
  "created_at": "2026-10-08T14:03:11+00:00",
  "organization": { "id": "...", "slug": "acme", "name": "Acme" },
  "workspace":    { "id": "...", "slug": "main", "name": "Main" },
  "actor": { "type": "user", "id": 42, "email": "ana@acme.com", "name": "Ana Lima" },
  "data": {  }
}
```

The `data` block carries summary information about the resources the event points at (identifying attributes such as `id`, `slug`, `name`, `status`). A resource's configuration and credentials are never included.

Each request includes signature headers:

| Header | Value |
| - | - |
| `webhook-id` | The delivery id—use it to deduplicate. |
| `webhook-timestamp` | Unix seconds at signing time—reject if older than a few minutes. |
| `webhook-signature` | `v1,<base64 HMAC-SHA256>` over the payload. |
| `User-Agent` | `Nekt-Webhooks/1.0` |

Verify with the reference library:

```python theme={null}
# pip install standardwebhooks
from standardwebhooks import Webhook

Webhook("whsec_...").verify(raw_body, headers)  # raises on a bad signature or stale timestamp
```

<Warning>
  Deliveries are sent **at least once**. A receiver may occasionally get the same `webhook-id` twice—deduplicate on it, and respond with a `2xx` status to acknowledge.
</Warning>

## Manage a webhook

Each webhook's row menu offers:

* **Edit** — change the name, URL, or subscribed events. Editing events replaces the whole selection.
* **Send test event** — queues a `ping` delivery so you can confirm your endpoint receives and verifies it.
* **View deliveries** — the recent deliveries, with event, status, HTTP response code, number of attempts, and sent time. **Resend** any failed delivery.
* **Rotate secret** — generates a new signing secret (shown once). Use it if the secret may have leaked.
* **Remove** — deletes the webhook and its delivery history.

You can also enable or disable a webhook with its toggle. A disabled webhook receives nothing.

## Delivery reliability

* **Retries.** A failed delivery is retried on a schedule spanning about 48 hours (ten attempts, starting seconds apart and widening to hours), so a brief outage on your side recovers on its own.
* **Status.** A webhook is `active`, `failing` (deliveries are currently failing—the tooltip says since when), `disabled` (switched off by a person), or `disabled automatically`.
* **Automatic disable.** If an endpoint fails continuously for **3 days** and at least **3 deliveries** in a row have exhausted their retries, Nekt disables the webhook and shows a banner with the reason. Re-enabling it with the toggle resets its health and resumes deliveries.
* **History.** Delivery records are kept for **30 days**.


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