---
updatedAt: 2026-09-14T15:54:33.000Z
---

Fetch the complete documentation index at: https://docs.synthesia.io/llms.txt. Use this file to discover all available pages before exploring further. Append .md to any documentation page URL to get its markdown version.

# Verifying Synthesia Signatures

In order to verify that events you receive were sent by Synthesia, they include a signature in the `Synthesia-Signature` header of each event. Construct and verify this signature using a unique secret that we provide for each webhook subscription.

Note that if this signature is compromised, it is critical that you recreate the webhook subscription, else a bad actor would be able to send events to your systems under the guise of Synthesia.

## How do you verify our signatures?

The following steps describe how you may construct the signing signature, allowing for a comparison with the one we provide. If they are the same, you can be confident the event was sent by us.

### Step 1: Fetch the request contents

You need two things from the request; the request timestamp, found in the `Synthesia-Timestamp` header, and the request body.

```python
from flask import request

request_timestamp = request.headers["Synthesia-Timestamp"]
request_body = request.data.decode("utf-8")
```

### Step 2: Create the message

To create the message to be signed, concatenate the timestamp and the request body (the actual JSON payload) using the character `.`:

```python
message = ".".join((request_timestamp, request_body))
```

### Step 3: Construct the signature

Then create the signature, an HMAC created using the SHA256 hash function, by signing the message using the your webhook secret as the signing key.

```python
import hashlib
import hmac

key = "..."  # This is your webhook secret.

signature = hmac.new(
    key.encode("utf-8"),
    message.encode("utf-8"),
    hashlib.sha256,
).hexdigest()
```

### Step 4: Compare the signatures

Compare the computed signature with the one we provide in the `Synthesia-Signature` header.

```python
assert signature == request.headers["Synthesia-Signature"]
```

### Step 5: Compare the timestamps

Optionally, protect yourself from replay attacks by checking that the `Synthesia-Timestamp` is within your tolerance. For example, you might choose to ignore events that were created more than 10 minutes ago.

# Sibling pages

* [Guide: Create a video from a template](https://docs.synthesia.io/reference/guide-create-a-video-from-template.md)
* [Guide: Zapier integration](https://docs.synthesia.io/reference/guide-synthesia-zapier.md)
* [Guide: Dub your videos via Synthesia API](https://docs.synthesia.io/reference/upload-large-files-via-temporary-aws-credentials.md)
* [List of supported voices](https://docs.synthesia.io/reference/voices.md)
* [Webhook events](https://docs.synthesia.io/reference/webhook-events.md)
* [Script supported XML tags](https://docs.synthesia.io/reference/script-supported-xml-tags.md)