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

# Webhooks

Marmar supports **multiple webhooks per tenant**, allowing you to route assessment notifications to different endpoints based on your architecture.

## Creating Webhooks

Create webhooks via `POST /v1/webhooks`. The secret is auto-generated and returned only in the creation response:

```json theme={null}
// Request
{
  "name": "Production Handler",
  "url": "https://your-server.com/webhooks/marmar",
  "events": ["assessment.completed"]
}

// Response
{
  "webhook": {
    "id": "abc-123",
    "name": "Production Handler",
    "url": "https://your-server.com/webhooks/marmar",
    "events": ["assessment.completed"],
    "status": "active",
    "createdAt": "2026-01-13T00:00:00Z"
  },
  "secret": "f47ac10b-58cc-4372-a567-0e02b2c3d479-ab12cd34ef56..."
}
```

**Important:** Store the `secret` securely—it won't be shown again.

## Managing Webhooks

| Endpoint                                   | Description                         |
| ------------------------------------------ | ----------------------------------- |
| `GET /v1/webhooks`                         | List all webhooks                   |
| `GET /v1/webhooks/{id}`                    | Get a specific webhook              |
| `PATCH /v1/webhooks/{id}`                  | Update name, URL, events, or status |
| `DELETE /v1/webhooks/{id}`                 | Delete a webhook                    |
| `POST /v1/webhooks/{id}/regenerate-secret` | Get a new secret (invalidates old)  |

### Status Values

* `active` — Webhook receives deliveries
* `paused` — Temporarily disabled
* `disabled` — Permanently disabled

## Signature Verification

Each delivery includes headers:

* `X-Marmar-Event`: Event type (e.g., `assessment.completed`)
* `X-Marmar-Timestamp`: Unix timestamp in seconds
* `X-Marmar-Signature`: `v1=` + HMAC-SHA256 hex digest
* `X-Marmar-Webhook-Id`: ID of the webhook that triggered delivery

Verify signatures using constant-time comparison:

```typescript theme={null}
const expected = crypto
  .createHmac('sha256', webhookSecret)
  .update(timestamp + '.' + body)
  .digest('hex');
const isValid = `v1=${expected}` === signature;
```

Reject payloads older than 5 minutes or with invalid signatures.

## Retries

Failed deliveries (non-2xx, timeout, network error) retry with exponential backoff up to 15 minutes.
