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

# Webhook reference

> Outbound webhook headers, payload, and signature verification.

Documate delivers events to your HTTPS endpoint with an HMAC signature.

## Verify the signature

Compute HMAC-SHA256 over the **raw request body bytes** with your webhook secret. Compare to `X-Documate-Signature` (`sha256=` + lowercase hex) using a constant-time compare.

<CodeGroup>
  ```bash cURL (openssl) theme={null}
  # BODY_FILE is the exact raw body bytes you received
  SECRET='YOUR_WEBHOOK_SECRET'
  SIG=$(openssl dgst -sha256 -hmac "$SECRET" "$BODY_FILE" | awk '{print $2}')
  echo "sha256=$SIG"
  ```

  ```javascript Node.js theme={null}
  import crypto from 'crypto';

  function verify(secret, rawBody, header) {
    const expected =
      'sha256=' +
      crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
    const a = Buffer.from(expected);
    const b = Buffer.from(String(header || '').trim());
    return a.length === b.length && crypto.timingSafeEqual(a, b);
  }
  ```

  ```python Python theme={null}
  import hashlib
  import hmac

  def verify(secret: str, raw_body: bytes, header: str | None) -> bool:
      digest = hmac.new(secret.encode('utf-8'), raw_body, hashlib.sha256).hexdigest()
      expected = f'sha256={digest}'
      provided = (header or '').strip()
      return hmac.compare_digest(expected, provided)
  ```

  ```csharp C# theme={null}
  using System.Security.Cryptography;
  using System.Text;

  static bool Verify(string secret, byte[] rawBody, string? header)
  {
      var hash = HMACSHA256.HashData(Encoding.UTF8.GetBytes(secret), rawBody);
      var expected = "sha256=" + Convert.ToHexString(hash).ToLowerInvariant();
      var provided = (header ?? string.Empty).Trim();
      var a = Encoding.UTF8.GetBytes(expected);
      var b = Encoding.UTF8.GetBytes(provided);
      return a.Length == b.Length && CryptographicOperations.FixedTimeEquals(a, b);
  }
  ```

  ```php PHP theme={null}
  function verify(string $secret, string $rawBody, ?string $header): bool {
      $digest = hash_hmac('sha256', $rawBody, $secret);
      $expected = 'sha256=' . $digest;
      $provided = trim($header ?? '');
      return hash_equals($expected, $provided);
  }
  ```
</CodeGroup>

## Retries

If your endpoint does not return a successful HTTP status, Documate retries delivery with backoff for a limited number of attempts.

## Related

* [Webhooks guide](/guides/webhooks)
* [Integrations](/guides/integrations)


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