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

# Authentication

> Verify webhook signatures and endpoint URL rules

Verify every delivery before you use it. The signing secret from [Create Webhook](/api-reference/webhooks/create) is shown once. Store it. There is no rotate call. Delete the endpoint and create a new one to get a new secret.

## Headers

| Header           | Description                                |
| ---------------- | ------------------------------------------ |
| `Content-Type`   | `application/json`                         |
| `svix-id`        | Unique message ID                          |
| `svix-timestamp` | Unix timestamp when the message was signed |
| `svix-signature` | Space-separated signatures (`v1,...`)      |

Verify with the raw request body. A parsed JSON body will not match the signature.

## Node.js

```javascript theme={null}
import { Webhook } from "svix"

const secret = process.env.WEBHOOK_SECRET

app.post("/webhooks/beach", (req, res) => {
  const payload = req.rawBody
  const headers = {
    "svix-id": req.headers["svix-id"],
    "svix-timestamp": req.headers["svix-timestamp"],
    "svix-signature": req.headers["svix-signature"],
  }

  const wh = new Webhook(secret)
  let msg
  try {
    msg = wh.verify(payload, headers)
  } catch {
    return res.status(400).send("Invalid signature")
  }

  const { event, data } = msg
  console.log(event, data)
  res.status(200).send("OK")
})
```

## Python

```python theme={null}
from svix.webhooks import Webhook, WebhookVerificationError

secret = os.environ["WEBHOOK_SECRET"]

def handle_webhook(payload: bytes, headers: dict):
    wh = Webhook(secret)
    try:
        msg = wh.verify(payload, headers)
    except WebhookVerificationError:
        return False
    return True
```

Other languages are in the [Svix verifying payloads guide](https://docs.svix.com/receiving/verifying-payloads/how).

## Endpoint URL

`url` must be `https://` and a public hostname. Bare IPs, private or loopback addresses, embedded credentials, and names such as `.local` or `.internal` are rejected.
