> For a complete index of all SignalWire documentation pages, fetch https://signalwire.com/docs/llms.txt

# validate_request

> Legacy-compatible webhook validator accepting a raw body or parsed form params.

[validate-webhook-signature]: /docs/server-sdks/reference/python/core/security/validate-webhook-signature

A legacy-compatible signature validator with a drop-in shape for callers migrating from
the Compatibility SDK. It accepts either a raw request body or pre-parsed form
parameters. When given a raw body string it delegates to
[`validate_webhook_signature`][validate-webhook-signature]; when given parsed form params
it validates them directly.

For new custom servers, prefer [`validate_webhook_signature`][validate-webhook-signature]
and pass the raw request body. Use `validate_request` when you only have access to
pre-parsed form parameters.

## **Parameters**

Your Signing Key from the Dashboard. A missing or empty value raises `ValueError`.

The signature header value. A missing or empty value returns `False`.

The full URL SignalWire POSTed to.

Either a raw body `str` (delegates to
[`validate_webhook_signature`][validate-webhook-signature]) or pre-parsed form params
as a dict or list of `(key, value)` tuples. `None` is treated as empty params. Any
other type raises `TypeError`.

## **Returns**

`bool` — `True` on a signature match, `False` otherwise.

## **Example**

```python {11-16}
from fastapi import FastAPI, Request, Response, status
from signalwire.core.security import validate_request

app = FastAPI()
SIGNING_KEY = "PSK_your_signing_key"

@app.post("/compat-webhook")
async def compat_webhook(request: Request):
    form = await request.form()
    signature = request.headers.get("x-signalwire-signature", "")

    if not validate_request(
        signing_key=SIGNING_KEY,
        signature=signature,
        url=str(request.url),
        params_or_raw_body=dict(form),
    ):
        return Response(status_code=status.HTTP_403_FORBIDDEN)

    return {"ok": True}
```