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

# Webhooks

> Verify timestamped HMAC-SHA256 signatures against the raw request body.

export const RemoteContract = () => <Warning>
    <strong>Preview surface.</strong> The root package types the intended
    workflow HTTP and SSE API. The reference engine does not ship a compatible
    workflow service today. Do not point it at the stable resident firer or
    <code>nika model serve</code>.
  </Warning>;

<RemoteContract />

The signature verifier is a shipped SDK utility. The service that would send
workflow webhooks remains on the preview horizon.

## Preserve the raw body

```ts theme={"system"}
const rawBody = await request.text()
const signature = request.headers.get('X-Nika-Signature') ?? ''

const valid = await Nika.verifyWebhook(
  rawBody,
  signature,
  process.env.NIKA_WEBHOOK_SECRET!,
)
```

The signed payload is `<timestamp>.<raw body>`. Verify before JSON parsing;
parse and reserialization can change bytes.

## Reject before dispatch

```ts theme={"system"}
if (!valid) {
  return new Response('invalid signature', { status: 401 })
}

const event = JSON.parse(rawBody)
await dispatch(event)
```

The header shape is `t=<unix timestamp>,v1=<hex signature>`. The verifier:

* refuses malformed fields;
* refuses timestamps outside the tolerance;
* computes HMAC-SHA256 with Web Crypto;
* compares equal-length signatures in constant time.

Pass a fourth argument to change the default tolerance:

```ts theme={"system"}
await Nika.verifyWebhook(rawBody, signature, secret, 60)
```

## Test without a service

Build fixture signatures with Web Crypto in application tests. Keep replay
tests for stale timestamps, modified bodies, wrong secrets and malformed
headers.

## Continue

<CardGroup cols={2}>
  <Card title="Security boundary" icon="shield" href="/sdk/operations/security">
    Keep secrets and trust transitions explicit.
  </Card>

  <Card title="Remote errors" icon="triangle-exclamation" href="/sdk/runtime/errors">
    Decide how invalid delivery reaches product state.
  </Card>

  <Card title="Type index" icon="brackets-curly" href="/sdk/reference/types">
    Read the remote event and error shapes.
  </Card>

  <Card title="Source" icon="github" href="https://github.com/supernovae-st/nika-client/blob/main/src/webhook.ts">
    Inspect the exact verifier.
  </Card>
</CardGroup>
