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

# Webhooks

> Receive HTTP callbacks when workflow events happen in Lark.

A webhook posts a signed JSON payload to a URL you control whenever a workflow event fires. Use them to log results into your data warehouse or kick off downstream automation when a test passes or fails.

## Create a webhook

1. Open **Settings → Webhooks** in the [dashboard](https://dashboard.getlark.ai/settings).
2. Click **Add webhook**.
3. Enter the URL Lark should POST to and pick the events you want to receive.
4. Save. Lark shows the **signing secret** once. Copy it now and store it somewhere safe.

You can have up to 5 webhooks per account.

## Events

| Event                          | Fires when                                                        |
| ------------------------------ | ----------------------------------------------------------------- |
| `workflow_execution.success`   | A workflow execution finishes with status `success`.              |
| `workflow_execution.failure`   | A workflow execution finishes with status `failure`.              |
| `workflow_execution.cancelled` | A workflow execution is cancelled.                                |
| `workflow_generation.success`  | Lark finishes generating a deterministic workflow's script.       |
| `workflow_generation.failure`  | Generation could not produce a working script.                    |
| `workflow_repair.success`      | A repair fixed the script and the workflow is ready to run again. |
| `workflow_repair.failure`      | A repair attempt failed.                                          |

## Payload

Every payload uses the same envelope:

```json theme={null}
{
  "event": "workflow_execution.failure",
  "timestamp": "2026-05-01T12:34:56Z",
  "workflow": {
    "id": "wf_abc123",
    "name": "New User Signup",
    "description": "Go to dashboard url and verify that you can sign up as a new user.",
    "secret_context_names": ["dashboard_login"]
  },
  "data": {
    "execution_id": "exec_xyz789",
    "status": "failure",
    "summary": "The signup button did not respond after submission."
  }
}
```

The `data` block depends on the event type and includes the relevant runnable id (`execution_id`, `generation_id`, `repair_id`), its status, timing, and a short summary.

## Verifying signatures

Lark signs every request with HMAC-SHA256 over the raw request body, using your webhook's signing secret. The hex digest arrives in the `X-Lark-Signature` header. Reject requests whose computed signature doesn't match.

<CodeGroup>
  ```python Python theme={null}
  import hashlib
  import hmac

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

  ```javascript Node.js theme={null}
  import crypto from "node:crypto";

  function verify(body, signature, secret) {
    const expected = crypto
      .createHmac("sha256", secret)
      .update(body)
      .digest("hex");
    return crypto.timingSafeEqual(
      Buffer.from(expected),
      Buffer.from(signature),
    );
  }
  ```
</CodeGroup>

Pass the raw request body to `verify`, not a re-serialized object. Re-encoding can change byte ordering and break the signature check.

## Delivery and retries

* Lark expects a `2xx` response within 10 seconds.
* Failed deliveries (timeouts, non-2xx) retry up to 3 times with exponential backoff (10s, 20s, 40s).
* After 3 failed retries Lark drops the delivery and logs the error. The webhook stays active.

## Pausing or removing a webhook

Toggle **Active** off on the webhook row to pause delivery without losing the configuration. Click the trash icon to remove it.
