# SignNow Webhooks

SignNow is an e-signature API. Its webhooks (called event subscriptions) POST a
JSON callback to your URL when documents, document groups or users change.

## When to Use This Skill

* How do I receive SignNow webhooks?
* How do I verify the `X-SignNow-Signature` header?
* Why are my SignNow webhooks unsigned or failing signature verification?
* How do I handle `document.complete` or `document.fieldinvite.signed`?
* What does the SignNow callback payload (`meta` / `content`) look like?

## Set a `secret_key` or Callbacks Are Unsigned

SignNow signs a callback **only** when the event subscription was created with a
`secret_key`. It does not issue one: pass any string up to 300 characters in
`attributes.secret_key` of `POST /v2/event-subscriptions`, or enter one (or click
**Generate New Key**) in the API Dashboard. Without it there is no
`X-SignNow-Signature` header, so verification (including Hookdeck's SignNow
source) fails. Always set one.

## Verification (core)

`X-SignNow-Signature` = **base64** of HMAC-SHA256 over the **raw body**, keyed
with the `secret_key` as UTF-8. No timestamp is part of the signed content.

```javascript
const crypto = require('crypto');

function verifySignNowSignature(rawBody, signature, secret) {
  if (!signature || !secret) return false;
  const expected = crypto.createHmac('sha256', Buffer.from(secret, 'utf8'))
    .update(rawBody)            // exact bytes received, not re-serialized JSON
    .digest('base64');          // base64, not hex
  const a = Buffer.from(signature, 'utf8');
  const b = Buffer.from(expected, 'utf8');
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

// Express: read the raw body for any Content-Type
// app.post('/webhooks/signnow', express.raw({ type: '*/*' }), handler)

```

> **For complete handlers with tests**, see [examples/express/](https://github.com/hookdeck/webhook-skills/tree/main/skills/signnow-webhooks/examples/express/), [examples/nextjs/](https://github.com/hookdeck/webhook-skills/tree/main/skills/signnow-webhooks/examples/nextjs/), [examples/fastapi/](https://github.com/hookdeck/webhook-skills/tree/main/skills/signnow-webhooks/examples/fastapi/).

SignNow has no webhook verification helper in its SDKs, so every example
computes the HMAC directly (`crypto` in Node, `hmac` + `hashlib` in Python).

## Common Event Types

The event name is `meta.event`; entity ids are in `content`.

| Event | Triggered when |
| --- | --- |
| `document.open` | A document was opened |
| `document.update` | A document was edited |
| `document.complete` | All required fields on a document were filled in |
| `document.delete` | A document was deleted |
| `document.fieldinvite.create` / `.sent` | A field invite was created / sent |
| `document.fieldinvite.signed` | A field invite was signed |
| `document.fieldinvite.decline` | A field invite was declined |
| `user.document.complete` | All required fields on a user's document were filled in |
| `document_group.complete` | A document group was completed (or its invite expired) |
| `document_group.invite.signer.complete` | A signer completed all documents in a group invite |

The `user.*` and `document_group.*` families mirror these; see
[references/overview.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/signnow-webhooks/references/overview.md) for the full list and payloads.

## Environment Variables

```bash
# The secret_key you set on the SignNow event subscription
SIGNNOW_WEBHOOK_SECRET=your_event_subscription_secret_key

```

## Local Development

```bash
npx hookdeck-cli listen 3000 signnow --path /webhooks/signnow

```

No account required — the CLI creates a guest account on first run and gives
you a public HTTPS URL plus a web UI for inspecting requests. Use port `8000`
for the FastAPI example.

## Reference Materials

* [references/overview.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/signnow-webhooks/references/overview.md) — Event families, payload structure, retries
* [references/setup.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/signnow-webhooks/references/setup.md) — Creating an event subscription with a `secret_key`
* [references/verification.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/signnow-webhooks/references/verification.md) — Signature details, gotchas, debugging