Skip to content

Webhooks overview

Webhooks let Puck push events to your systems the moment something happens — an investigation completes, a critical finding surfaces, an agent drops off the fleet. No polling required.

How delivery works

Every time a matching event fires, Puck creates a delivery and POSTs a JSON envelope to your registered URL. Delivery is at-least-once: if your endpoint does not respond with a 2xx status, Puck retries with exponential backoff before eventually dead-lettering the delivery. Because of the at-least-once guarantee, your handler should deduplicate on the event_id field in the envelope.

{
"event_id": "018f2e3a-1c47-7a12-b321-aabbccddeeff",
"event_type": "investigation.completed",
"emitted_at": "2026-05-03T14:22:01Z",
"api_version": "v1",
"data": { ... }
}

Every delivery carries four HTTP headers:

HeaderContents
X-Puck-SignatureHMAC-SHA256 signature for authenticity — see Signature verification
X-Puck-Event-IdStable UUID; dedupe on this
X-Puck-Event-Typee.g. investigation.completed
X-Puck-Delivery-IdUnique per attempt; useful for delivery-log correlation

Subscriptions

A subscription binds a target URL to one or more event types and an optional filter set:

  • events — which event types to deliver (e.g. ["investigation.completed", "finding.discovered"]).
  • min_severity — only deliver if the event’s severity meets or exceeds this threshold (low / medium / high / critical). Useful for routing critical findings to PagerDuty without the noise of routine completions.
  • tags — only deliver if the event carries all specified key: value tag pairs. Useful for per-team or per-account routing.
  • secret — per-subscription HMAC key for signature verification. Generated by Puck on creation; never returned again after that initial response.

You can hold multiple subscriptions pointing at different URLs with different filter sets — for example, one subscription per SIEM destination and one for a Slack bot that only wants critical findings.

When to use webhooks vs the API

Use webhooks when you want Puck to tell you when something happens — send a Slack message when a chain is confirmed, open a Jira ticket when a critical finding arrives, trigger a SOAR playbook when an investigation completes.

Use the REST API when you want to query for a set of results — pull all findings from the last 7 days, fetch investigation status on demand, list all connected agents. The API is pull; webhooks are push.

The two are complementary: a common pattern is to receive an investigation.completed webhook and then call GET /v1/investigations/:id to fetch the full narrative.

Security model

  • HTTPS is required. Puck rejects subscriptions with http:// URLs at creation time.
  • Every delivery is signed. Verifying the signature before processing any payload is strongly recommended.
  • Replay attacks are mitigated: the signature embeds a Unix timestamp, and Puck’s verification libraries reject deliveries whose timestamp is more than 5 minutes old.