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

# Policy webhooks

> Send signed policy decision events to your HTTPS endpoint.

Open **Integrations** to connect an HTTP webhook for your workspace. It covers all workspace projects. Workspace owners and admins can manage connections; current members can view their configuration and delivery history.

<Note>
  Connection tests work independently of policy decision ingestion. Automatic decision exports require the verified provider feed, which is still disconnected in the current sandbox deployment. An inference request by itself does not produce an assumed policy outcome.
</Note>

## Connect a destination

1. Select **Add integration**.
2. Enter a connection name and a public HTTPS webhook URL on port 443.
3. Enter a dedicated signing secret containing 32–256 non-space printable characters. Generate a random secret for this purpose; do not reuse an API key or password. Keep the same secret in your receiver's secret manager.
4. Select at least one event class to export.
5. Select **Connect and test**. The connection is saved and one labeled test event is queued. Check its delivery result before relying on the destination.

| Event class | Exported when | Default |
| - | - | - |
| Blocked decisions | The decision action is `blocked`. | On |
| Monitoring matches | At least one monitoring policy reports `matched`. | On |
| Evaluation failures | Checks are partial/failed or a policy reports `evaluation_failed`. | On |
| Allowed decisions | The decision action is `allowed`. | Off |

The filters use OR: a decision matching several selected classes produces one delivery per connection. Test events bypass these filters. Existing decisions are not exported retroactively.

## Manage connections

Select a saved connection to edit its name, URL, signing secret or filters. Leave the signing-secret field blank to keep the saved secret. Save changes before using **Test connection**; tests use the saved configuration. Saved secrets are encrypted and never returned to the browser.

The list shows **Active**, **Disabled** or **Needs attention**, plus the last successful delivery or test time. Delivery history shows attempts, HTTP status and safe error categories. Receiver response bodies are not saved.

Disable a connection to stop pending deliveries, then enable it when ready. Deleting a connection removes it from the list and stops pending deliveries. Configuration edits cancel deliveries queued under the previous configuration. A request already sent to a receiver cannot be recalled.

## Event payload

All events use a versioned JSON envelope. Connection tests have `type: "integration.test"` and `decision: null`:

```json theme={null}
{
  "id": "cccccccc-cccc-4ccc-8ccc-cccccccccccc",
  "schema_version": "1",
  "type": "integration.test",
  "created_at": "2026-10-12T12:00:00Z",
  "organization_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
  "decision": null
}
```

Real decision events use `type: "policy.decision"`. Their `decision` contains the local decision, request and project IDs; evaluation time; action; check status; direction; endpoint; model; classifier latency when available; gate; content kinds; and per-policy results. Each result identifies the local policy ID, name, version, mode and result. See [Decisions](/guides/decisions) for field meanings.

Prompts, generated text, policy rule text, provider credentials and raw provider payloads are excluded. Treat the event's workspace metadata as private data at your destination.

## Verify the signature

Each POST includes:

| Header | Value |
| - | - |
| `Content-Type` | `application/json` |
| `X-Limitless-Delivery` | Stable delivery UUID, matching the envelope's `id`. |
| `X-Limitless-Signature` | `t=<Unix timestamp>,v1=<hex HMAC-SHA256>` |

The signed bytes are the UTF-8 timestamp, a period, the delivery ID, another period, then the **exact raw request body**. Use the signing secret as the HMAC key. Do not parse and re-serialize the JSON before verification. This is the Limitless signature contract; the console workflow follows Abliteration, but their public connector documentation does not specify a wire signature to reproduce.

```js theme={null}
import { createHmac, timingSafeEqual } from "node:crypto";

export function verifyWebhook(rawBody, deliveryId, signature, secret) {
  if (!Buffer.isBuffer(rawBody) || rawBody.length > 512 * 1024) return false;
  if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(deliveryId)) return false;
  const match = /^t=(\d{10}),v1=([0-9a-f]{64})$/.exec(signature ?? "");
  if (!match || Math.abs(Date.now() / 1000 - Number(match[1])) > 300) return false;
  const expected = createHmac("sha256", secret)
    .update(`${match[1]}.${deliveryId}.`)
    .update(rawBody)
    .digest();
  return timingSafeEqual(expected, Buffer.from(match[2], "hex"));
}
```

After verification, parse the JSON and require its `id` to match `X-Limitless-Delivery`. Store that ID with your processing result so repeated delivery cannot trigger duplicate work. Keep your receiver's clock synchronized. Return a 2xx response after durably accepting the event, and acknowledge already-processed IDs with 2xx as well.

## Retries and limits

Delivery is **at least once**. Retries keep the same delivery ID and payload, with a fresh timestamp and signature. A receiver may receive an event again if its acknowledgement or our completion write is lost. Delivery order is not guaranteed.

Network failures, timeouts, HTTP 408/425/429 and 5xx responses retry with bounded backoff, up to six attempts. Other HTTP failures, redirects, invalid destinations and invalid TLS certificates require a configuration fix. An attempt has an eight-second deadline. After fixing a destination, use **Test connection**; failed historical events are not automatically replayed.

Only public HTTPS destinations are supported. URLs with embedded credentials, fragments or nonstandard ports are rejected. DNS is checked and pinned for each attempt; private, loopback, link-local and metadata-service addresses are blocked. Redirects are never followed.

Each workspace supports up to 20 saved connections, 10 connection tests per minute, and 10,000 pending deliveries. Queue overflow is counted and surfaced as **Needs attention**. Delivery history is retained for 30 days; cleanup runs as the worker processes the queue. These limits protect request serving from an unavailable receiver.


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