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

# Verify signatures

> How to verify webhook delivery signatures to ensure authenticity.

Every webhook delivery includes an `X-Webhook-Signature` header containing an HMAC-SHA256 signature of the request body. You should verify this signature to confirm the payload was sent by Timeless and has not been tampered with.

## Signature format

The header value has the format:

```
sha256=<hex-encoded HMAC-SHA256 digest>
```

The HMAC is computed using the webhook's `secret` (returned when you [created the webhook](/api-reference/webhooks/create-webhook)) as the key and the raw JSON request body as the message.

## Verification examples

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

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

      received = signature_header.removeprefix("sha256=")

      return hmac.compare_digest(expected, received)
  ```

  ```javascript JavaScript theme={null}
  const crypto = require("crypto");

  function verifySignature(payload, signatureHeader, secret) {
    const expected = crypto
      .createHmac("sha256", secret)
      .update(payload)
      .digest("hex");

    const received = signatureHeader.replace("sha256=", "");

    return crypto.timingSafeEqual(
      Buffer.from(expected),
      Buffer.from(received)
    );
  }
  ```
</CodeGroup>

<Warning>
  Always use a constant-time comparison function (like `hmac.compare_digest` or `crypto.timingSafeEqual`) to prevent timing attacks.
</Warning>

## Webhook payload

The request body is a JSON object whose structure depends on the webhook event type. For example, meeting-related events include the same fields as a meeting in the [List meetings](/api-reference/meetings/list-meetings) response (`id`, `title`, `status`, `participants`, `host`, `documents`). Refer to the documentation for each event type for its specific payload format.

## Delivery behavior

* Deliveries time out after 10 seconds.
* A delivery is considered successful if your endpoint returns a `2xx` status code.
* Failed deliveries are retried up to 3 times with increasing delays (1s, 10s, 60s).
* Retries occur for server errors (5xx), rate limits (429), and network failures. Client errors (4xx other than 429) are not retried.
