Deliver Capsule policy-violation notifications to any HTTPS endpoint you control, such as a SOAR playbook, an incident-management tool, or an internal service.
When a policy you've linked is violated, Capsule sends an HTTP POST with a JSON body to your webhook URL. The body describes the violation - severity, policy, affected entity - with a link back into the Capsule portal.
You can add more than one custom webhook and link each to different policies. For example, high-severity violations can go to your SOAR while everything else goes to a ticketing endpoint.
Capsule policy violation
→ Capsule POSTs a JSON event to your HTTPS URL
→ your endpoint returns a 2xxBefore you begin, ensure you have:
- An HTTPS endpoint reachable from the public internet that accepts
POSTrequests with a JSON body - Any credentials the endpoint expects, such as a bearer token or API key, which Capsule will send as a request header
- A Capsule Security account with admin access
Capsule only delivers to URLs that meet these rules. A URL that breaks one is rejected when you save it.
- The URL uses
https://and is at most 2,048 characters. - It does not embed credentials (
https://user:password@...). Send them as a header instead. - Its host resolves only to public IP addresses. Private, loopback, link-local, and reserved addresses are blocked, and the check runs again on every delivery.
Your endpoint must answer with a 2xx status. Capsule does not follow redirects, so a 3xx counts as a failure. Each request times out after 15 seconds.
- Log in to the Capsule Security portal.
- Go to Settings → Notifications.
- Click Add channel and choose Custom webhook.
- Enter a display name (how this channel appears in Capsule) and the webhook URL.
- Optionally, add headers to send with every request, such as
Authorization: Bearer <token>. You can add up to 20 headers. - Click Save & Test.
Use headers to authenticate Capsule to your endpoint. Capsule sets Content-Type: application/json itself, so you can't override it, or Host, Content-Length, Transfer-Encoding, or Connection. Header names must be unique.
Paths and query strings often carry a token, so Capsule never shows the full URL after you save it. The channel shows only the URL's origin (for example https://hooks.acme.com/…). Header values are write-only: Capsule shows the header names but never the values.
When you Edit a channel, re-enter the full URL. Leave a header value blank to keep the stored value, or enter a new one to rotate it.
Save & Test sends a test event ("eventType": "test") to your endpoint. A passing test means your endpoint returned a 2xx. Check the receiving system to confirm it handled the event the way you expect.
A custom webhook only receives notifications for the policies you link to it. On the policy edit screen, add the webhook channel to the policy's notification channels - the same way you link any other notification destination. A channel with no linked policies stays idle.
Every request is a POST with Content-Type: application/json, plus any headers you configured.
{
"source": "capsule",
"eventId": "6f1c2a9e-4b7d-4e2a-9a51-0c3f8d2e7b14",
"eventType": "policy_violation",
"timestamp": "2026-10-28T09:15:00.000Z",
"title": "Sensitive data shared with an external AI tool",
"summary": "A prompt containing source code was sent to an unapproved AI tool.",
"severity": "high",
"link": "https://<your-capsule-portal>/...",
"fields": {
"policyName": "Block source code to external AI",
"policyId": "8d3e...",
"entityName": "jane@acme.com",
"entityId": "a41b...",
"issueId": "c92f..."
},
"pendingSummaries": []
}| Field | Description |
|---|---|
source | Always capsule. |
eventId | Unique ID of the notification. It stays the same across automatic retries, so use it to deduplicate. |
eventType | policy_violation, policy_violation_summary, or test. |
timestamp | When the violation occurred, in ISO 8601 UTC. |
title | Short headline of the violation. |
summary | Description of the violation. |
severity | Severity of the violation, or null. |
link | URL of the violation in the Capsule portal, or null. |
fields | Policy, entity, and issue identifiers. Any of them can be null. |
pendingSummaries | Titles of violations held back during the cooldown window. Empty unless eventType is a summary. |
To avoid flooding your endpoint, Capsule sends at most one notification per policy and entity per hour. Violations for the same policy and entity that occur within that hour are held back. The next notification after the hour carries their titles in pendingSummaries and has "eventType": "policy_violation_summary".
The test event has "eventType": "test", null severity, link, and fields, and an empty pendingSummaries.
The URL is rejected when saving. The URL isn't https://, embeds credentials, can't be resolved, or resolves to a private or reserved address. Use a publicly reachable HTTPS URL.
The test fails with "The webhook rejected the credentials". Your endpoint returned 401 or 403. Update the auth header value and test again.
The test fails with "The webhook rejected the request". Your endpoint returned 400 or a redirect (3xx). Check the URL and headers. If the endpoint redirects, use the final URL instead.
The channel row shows an Error state. Capsule flips a channel to Error when a delivery fails and records a reason. The usual causes are an endpoint that was removed (404), revoked credentials, or an endpoint that is down. Fix the endpoint or Edit the channel. Saving a changed URL or headers returns the channel to Active.
Duplicate URL rejected. Capsule rejects a URL that another custom webhook channel already uses, including the query string. To change which policies notify an endpoint, edit the policies linked to the existing channel.
Rate limiting or transient failures. On a timeout, a network error, a 429, or a 5xx, Capsule retries automatically up to 3 times with backoff. It honors a Retry-After header up to 60 seconds. Persistent failures surface as an Error state on the channel row.
For help with this integration:
- Email: support@capsule.security
- Include: Your organization ID, the affected channel's display name, and any error shown on the channel row