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

# Webhooks

> Receive real-time notifications when events happen in your Encrata workspace.

## Overview

Webhooks let you receive HTTP callbacks when specific events occur in your workspace — like a lookup completing or an API key being created. Instead of polling the API, Encrata pushes event data directly to your server.

## How it works

1. You register a webhook URL in **Settings → Webhooks** on the dashboard.
2. When a subscribed event occurs, Encrata sends a `POST` request to your URL with a JSON payload.
3. Each delivery is signed with HMAC-SHA256 so you can verify it came from Encrata.

## Supported events

| Event                   | Trigger                                      |
| ----------------------- | -------------------------------------------- |
| `lookup.completed`      | An email lookup finishes processing          |
| `monitor.run.completed` | A monitor run finishes with changes detected |
| `apikey.created`        | A new API key is created                     |
| `apikey.revoked`        | An API key is revoked                        |
| `credits.low`           | Workspace credits drop below threshold       |
| `credits.exhausted`     | Workspace credits are fully consumed         |

## Payload format

Every webhook delivery sends a JSON payload in the following shape:

```json theme={"dark"}
{
  "event": "lookup.completed",
  "data": {
    "email": "satya@microsoft.com",
    "lookup_id": "lu_abc123"
  },
  "created_at": "2026-05-02T12:00:00Z"
}
```

## Verifying signatures

Each webhook request includes an `X-Encrata-Signature` header containing the HMAC-SHA256 hex digest of the raw request body, signed with your webhook secret.

To verify:

<CodeGroup>
  ```python Python theme={"dark"}
  import hmac, hashlib

  def verify_signature(payload: bytes, secret: str, signature: str) -> bool:
      expected = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()
      return hmac.compare_digest(expected, signature)
  ```

  ```javascript Node.js theme={"dark"}
  const crypto = require("crypto");

  function verifySignature(payload, secret, signature) {
    const expected = crypto
      .createHmac("sha256", secret)
      .update(payload)
      .digest("hex");
    return crypto.timingSafeEqual(
      Buffer.from(expected),
      Buffer.from(signature)
    );
  }
  ```

  ```go Go theme={"dark"}
  import (
      "crypto/hmac"
      "crypto/sha256"
      "encoding/hex"
  )

  func VerifySignature(payload []byte, secret, signature string) bool {
      mac := hmac.New(sha256.New, []byte(secret))
      mac.Write(payload)
      expected := hex.EncodeToString(mac.Sum(nil))
      return hmac.Equal([]byte(expected), []byte(signature))
  }
  ```
</CodeGroup>

<Warning>
  Always verify signatures before processing webhook payloads. Never trust unverified requests.
</Warning>

## Requirements

* Webhook URLs **must use HTTPS**.
* Your endpoint should return a `2xx` status code within **5 seconds**.
* Failed deliveries are retried with exponential backoff.

## Managing webhooks

You can manage webhooks from the dashboard (**Settings → Webhooks**) or via the API:

| Action          | Method   | Endpoint                                   |
| --------------- | -------- | ------------------------------------------ |
| List webhooks   | `GET`    | `/api/webhooks`                            |
| Create webhook  | `POST`   | `/api/webhooks`                            |
| Get webhook     | `GET`    | `/api/webhooks?id={id}`                    |
| Update webhook  | `PUT`    | `/api/webhooks`                            |
| Delete webhook  | `DELETE` | `/api/webhooks`                            |
| Test webhook    | `POST`   | `/api/webhooks/test`                       |
| List deliveries | `GET`    | `/api/webhooks/deliveries?webhook_id={id}` |

<Info>
  Your webhook secret is shown only once when you create a webhook. Store it securely — you'll need it to verify signatures.
</Info>
