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

# Verify signatures

> Recompute an HMAC over the raw captured body and compare it to the signature header

Signers hash the exact body bytes, not a pretty-printed copy. The event `body` text can differ from those bytes once it is decoded or truncated. Download the raw body and hash that.

The signature the sender attached is on the event headers. Compare your HMAC to that header using the scheme the sender documents (hex, base64, or a `t=...,v1=...` value).

## CLI

Wait for the event, then download its raw body. `--file` is required.

```bash theme={null}
export DEVHELM_API_TOKEN=dh_live_xxxxxxxx
devhelm inboxes wait <inbox-id> --timeout-ms 30000 -o json
devhelm inboxes events raw <inbox-id> <event-id> --file body.bin
openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" body.bin
```

`sha256` on the event is the SHA-256 of those same raw bytes. It is not the HMAC.

## TypeScript

```typescript theme={null}
import { Devhelm } from "@devhelm/sdk";

const client = new Devhelm({
  token: process.env.DEVHELM_API_TOKEN!,
});

const event = await client.inboxes.wait("<inbox-id>", { timeoutMs: 30_000 });
const file = await event.raw();
const bytes = await file.arrayBuffer();

const key = await crypto.subtle.importKey(
  "raw",
  new TextEncoder().encode(process.env.WEBHOOK_SECRET),
  { name: "HMAC", hash: "SHA-256" },
  false,
  ["sign"],
);
const mac = await crypto.subtle.sign("HMAC", key, bytes);
console.log(event.id, event.headers, mac.byteLength);
```

`event.raw()` downloads the raw body. `event.headers` is the header map as received, so you can read the signature header next to the MAC.

## Next steps

<CardGroup cols={2}>
  <Card title="Assert in a test" icon="code" href="/testing/webhooks/assert-in-tests">
    Wait for the request before you check the signature.
  </Card>

  <Card title="Webhook Testing API" icon="book" href="/api-reference/webhook-testing">
    Event fields, including headers and the raw download.
  </Card>
</CardGroup>


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