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

# Webhooks and event fields

> The two webhooks Quint offers, how to verify a signed alert delivery, and the fields in each event and audit record.

Quint has two webhook destinations. They sit in different sections of the **Integrations** page and carry different things. Creating or changing either needs the **Admin** or **Owner** role.

## The two webhooks

| | Generic Webhook | Alert Webhook |
| - | - | - |
| Section | **Event export** | **Alert delivery** |
| Carries | Event batches, and the admin audit log as a second stream | Alerts and approval requests, one delivery each |
| Request | `POST` of a JSON array to the **Endpoint URL** you give | `POST` of one JSON object to `<your base>/alerts/<type>` |
| Fields | **Endpoint URL** (required), **Custom headers** (optional) | **Receiver base URL** (required); Quint appends `/alerts/<type>` |
| Authentication | Whatever you put in **Custom headers** | HMAC-SHA256 signature in the `X-Quint-Signature` header, with a per-destination key |
| Key | None | Shown once when created, rotatable with **Rotate key** |
| Before it can be enabled | Nothing | A signed test ping must reach your receiver |
| Audit log stream | Yes, with the header `X-Quint-Stream: admin_audit` on audit batches | No |
| Change the URL | **Edit** | **Replace URL** |

Custom header values on the generic webhook are treated as secrets. Quint does not show them back to you.

## Verify a signed alert delivery

Each alert webhook delivery carries three headers you can check:

| Header | Meaning |
| - | - |
| `Content-Type` | Always `application/json`. |
| `X-Quint-Signature` | `sha256=` followed by the lowercase hex HMAC-SHA256 of the raw request body, keyed with your signing key. |
| `X-Quint-Timestamp` | Unix time, in seconds, when the delivery was signed. The same value is sent on every retry of the same delivery. |
| `X-Quint-Signature-Next` | Present only after you click **Rotate key**. The same body signed with the new key, so you can switch receivers without a gap. |

To verify in plain words:

1. Read the request body as raw bytes. Do not parse and re-serialise it first; any change to the bytes changes the signature.
2. Compute HMAC-SHA256 over those bytes with the key Quint showed you when the destination was created or rotated.
3. Encode the result as lowercase hex and prefix it with `sha256=`.
4. Compare it with `X-Quint-Signature` using a constant-time comparison. Reject the delivery if they differ.
5. If you also want to reject replays, reject a delivery whose `X-Quint-Timestamp` is older than you are willing to accept.

During a rotation, verify against `X-Quint-Signature` with the old key or against `X-Quint-Signature-Next` with the new key. Either one is enough. Each header carries exactly one value; Quint never joins two signatures into one header.

> [!WARNING]
>
> The key is shown once. If you lose it, click **Rotate key** and store the new one. The old key keeps working for 72 hours so your receiver does not drop deliveries while you switch; after that it is dropped on its own.

## Alert delivery body

An alert delivery is one JSON object with these fields. Fields marked optional are omitted when empty.

| Field | Meaning |
| - | - |
| `alert_id` | Identifier of this alert. |
| `org_id` | Identifier of your workspace. |
| `severity` | One of `critical`, `high`, `medium`, `low`. |
| `type` | What raised the alert, for example a refused action, a divergence finding or a risk threshold breach. |
| `subtype` | Optional. The finer kind within the type; for a divergence finding, which risk it is. |
| `event_id` | Identifier of the event that raised the alert. |
| `agent_id` | Identifier of the agent install the event belongs to. |
| `session_id` | Identifier of the session the event belongs to. |
| `tool_name` | The tool the agent called, when the event was a tool call. |
| `risk_score` | Optional. The composite risk score of the event. |
| `message` | A one-line, human-readable description of the alert. |
| `timestamp` | When the alert was raised, in RFC 3339 format. |

Approval request deliveries to an alert webhook use a different body. Field reference: ask your Quint contact.

### Tool supply-chain findings

An alert for a tool supply-chain finding has one of these subtypes: `mcp_tool_redefined` (MCP tool redefined), `mcp_tool_description_injection` (Tool description injection), `agent_builtin_tool_drift` (Built-in tool changed) or, with an upcoming agent release, `mcp_tool_cross_reference` (Tool cross-reference). The alert carries `tool_name` and a one-line `message`; it carries no labels. The message for a cross-reference names both tools and both servers, unless content suppression is on.

With that release, a description flagged the first time Quint saw the tool raises an alert whose message says the tool was first advertised with a description flagged for review. A cross-reference is low severity.

## Exported event fields

Every batch exporter, including the generic webhook, sends events in this shape. The generic webhook sends a JSON array of these objects. Splunk receives each one wrapped in the HTTP Event Collector envelope (`event`, `time`, `index`, `sourcetype`, `source`). Fields marked optional are omitted when empty.

| Field | Meaning |
| - | - |
| `id` | Identifier of the event. |
| `org_id` | Identifier of your workspace. |
| `agent_id` | Optional. Identifier of the agent install. |
| `session_id` | Optional. Identifier of the session. |
| `action_type` | The kind of action: a tool call, a file read or write, a command, a network connection. |
| `tool_name` | Optional. The tool the agent called. |
| `mcp_server` | Optional. The MCP server the tool belongs to, when the call went through one. |
| `arguments` | Optional. The arguments the agent passed, as JSON. |
| `result` | Optional. The result returned to the agent, as JSON. |
| `risk_score_composite` | Optional. The composite risk score, 0 to 100. |
| `decision` | Optional. The policy decision recorded for the action. |
| `platform` | Optional. The agent platform, for example Claude Code or Cursor. |
| `model` | Optional. The model the agent was using. |
| `framework` | Optional. The agent framework, when one was identified. |
| `source_ip` | Optional. The source address the event was received from. |
| `environment` | Optional. An environment label, when one was set. |
| `labels` | Optional. Additional labels, as a JSON object. |
| `created_at` | When the event happened, in RFC 3339 format. |

For a tool supply-chain finding, `labels` holds `divergence_type` (which finding it is), `finding_family` = `supply_chain` and `server_id` (redacted when content suppression is on). With an upcoming agent release `labels` also holds:

| Label | Meaning |
| - | - |
| `audit_basis` | `first_sight` when the description was flagged the first time Quint saw the tool; `change` when it was flagged after it changed. A cross-reference always carries `first_sight`. |
| `referenced_tool` | Cross-reference only. The other server's tool that the description names. |
| `referenced_server` | Cross-reference only. The server that tool belongs to. |

## Admin audit record fields

The second stream every enabled batch exporter receives is the admin audit log: who changed what in the workspace. Token mints, role changes, enforcement changes and sign-ins are recorded here. The generic webhook sends these as a JSON array with the header `X-Quint-Stream: admin_audit`.

| Field | Meaning |
| - | - |
| `id` | Row number of the audit record. |
| `org_id` | Identifier of your workspace. |
| `actor_kind` | Whether a person or a token performed the action. |
| `actor_user_id` | Optional. Identifier of the person. |
| `actor_email` | Optional. Email address of the person. |
| `actor_token_id` | Optional. Identifier of the API token, when a token acted. |
| `action` | What was done. |
| `resource_type` | The kind of thing it was done to. |
| `resource_id` | Optional. Identifier of that thing. |
| `metadata` | Optional. Further detail about the action, as a JSON object. |
| `source_ip` | Optional. Address the request came from. |
| `user_agent` | Optional. Client that made the request. |
| `request_id` | Optional. Identifier of the request, for support. |
| `created_at` | When the action happened, in RFC 3339 format. |

## Rotate key and Replace URL

* **Rotate key** (alert webhook) creates a new signing key and shows it once. Deliveries carry both signatures for 72 hours, as described above. Store the new key and switch your receiver within that window; the old key then lapses on its own.
* **Replace URL** (alert webhook) changes the receiver base URL. Click **Send test** afterwards and confirm the new receiver verifies the signature.
* **Edit** (generic webhook) changes the endpoint URL or custom headers.

## Next

* [Export events to your SIEM](https://docs.quintai.dev/integrations/export-to-your-siem.md)
* [Alerts and approvals in Slack, Teams and PagerDuty](https://docs.quintai.dev/integrations/alerts-in-slack-teams-pagerduty.md)
* [Notifications and built-in alerts](https://docs.quintai.dev/settings/notifications.md)


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