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

# Webhooks

> Receive real-time event notifications via HTTP.

Toktra sends HTTP POST requests to your endpoint when events occur — policy violations, budget alerts, lockouts, and more. Webhooks are the fastest way to integrate Toktra events into your own systems.

## Register a webhook

```bash theme={null}
POST /v1/webhooks
```

<ParamField body="url" type="string" required>
  Your HTTPS endpoint URL. Must return a `2xx` status within 10 seconds.
</ParamField>

<ParamField body="events" type="array">
  List of event types to subscribe to. Omit to subscribe to all events.
</ParamField>

<ParamField body="description" type="string">
  Optional human-readable label for this webhook.
</ParamField>

### Request

```bash theme={null}
curl -X POST https://api.toktra.io/v1/webhooks \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.example.com/toktra/events",
    "events": ["policy_violation", "budget_exceeded"],
    "description": "Production alert handler"
  }'
```

### Response

```json theme={null}
{
  "id": "wh1a2b3c-0000-0000-0000-000000000001",
  "url": "https://your-app.example.com/toktra/events",
  "events": ["policy_violation", "budget_exceeded"],
  "description": "Production alert handler",
  "signing_secret": "whsec_abc123...",
  "created_at": "2025-01-15T10:00:00Z"
}
```

<Warning>
  Save the `signing_secret` immediately — it is only shown once. You will use it to verify incoming webhook payloads.
</Warning>

***

## Verify webhook signatures

Every webhook request includes an `X-Toktra-Signature` header containing an HMAC-SHA256 signature of the raw request body, signed with your `signing_secret`.

Always verify this signature before processing the payload.

<CodeGroup>
  ```python Python theme={null}
  import hmac
  import hashlib

  def verify_signature(payload_body: bytes, signature_header: str, secret: str) -> bool:
      expected = hmac.new(
          secret.encode(),
          payload_body,
          hashlib.sha256
      ).hexdigest()
      return hmac.compare_digest(f"sha256={expected}", signature_header)

  # In your request handler:
  # signature = request.headers.get("X-Toktra-Signature")
  # if not verify_signature(request.body, signature, WEBHOOK_SECRET):
  #     return 401
  ```

  ```javascript Node.js theme={null}
  const crypto = require("crypto");

  function verifySignature(payloadBuffer, signatureHeader, secret) {
    const expected = "sha256=" + crypto
      .createHmac("sha256", secret)
      .update(payloadBuffer)
      .digest("hex");
    return crypto.timingSafeEqual(
      Buffer.from(expected),
      Buffer.from(signatureHeader)
    );
  }

  // In your request handler:
  // const sig = req.headers["x-toktra-signature"];
  // if (!verifySignature(req.rawBody, sig, process.env.WEBHOOK_SECRET)) {
  //   return res.status(401).end();
  // }
  ```
</CodeGroup>

***

## Event payload format

All webhook payloads share a common envelope:

```json theme={null}
{
  "id": "evt_01945b36-4567-7000-8000-000000000001",
  "type": "policy_violation",
  "created_at": "2025-01-15T10:30:00Z",
  "org_id": "a1b2c3d4-0000-0000-0000-000000000000",
  "data": {
    "alert_id": "al1b2c3d-0000-0000-0000-000000000001",
    "severity": "high",
    "user_id": "u1a2b3c4-0000-0000-0000-000000000001",
    "policy_id": "p1a2b3c4-0000-0000-0000-000000000001",
    "provider": "openai",
    "model": "gpt-4",
    "details": {
      "policy_name": "Restrict GPT-4 to Engineering",
      "department": "marketing"
    }
  }
}
```

## Event types

| Event type         | Triggered when                                  |
| ------------------ | ----------------------------------------------- |
| `policy_violation` | A usage policy fires (alert or block action)    |
| `budget_exceeded`  | An org or department budget limit is reached    |
| `budget_warning`   | Spend reaches 80% of a budget                   |
| `user_locked_out`  | An employee is offboarded and access is revoked |
| `anomaly_detected` | Pre-departure anomaly or unusual usage spike    |
| `device_enrolled`  | A new device completes enrollment               |
| `device_revoked`   | A device certificate is revoked                 |

***

## Retry behavior

If your endpoint returns a non-`2xx` status or times out, Toktra retries with exponential backoff:

| Attempt | Delay      |
| ------- | ---------- |
| 1       | Immediate  |
| 2       | 1 second   |
| 3       | 5 seconds  |
| 4       | 30 seconds |
| 5       | 5 minutes  |

After 5 failed attempts the delivery is marked as failed. You can manually retry failed deliveries from the dashboard or via the API.

***

## View delivery logs

```bash theme={null}
GET /v1/webhooks/{id}/deliveries
```

Returns a paginated list of recent delivery attempts, including HTTP status codes and response bodies.

***

## Test a webhook

Send a test event to verify your endpoint is reachable:

```bash theme={null}
POST /v1/webhooks/{id}/test
```

```bash theme={null}
curl -X POST https://api.toktra.io/v1/webhooks/wh1a2b3c-0000-0000-0000-000000000001/test \
  -H "Authorization: Bearer YOUR_TOKEN"
```

Toktra sends a `ping` event to your endpoint:

```json theme={null}
{
  "id": "evt_test_01945b36",
  "type": "ping",
  "created_at": "2025-01-15T10:00:00Z",
  "org_id": "a1b2c3d4-0000-0000-0000-000000000000",
  "data": {}
}
```
