Workshop can POST events to an HTTPS endpoint of your choosing as they happen, letting you forward Workshop activity into your own systems — SIEMs, ticketing, chat, or custom automation. Each delivery is signed following the Standard Webhooks specification so your receiver can verify it genuinely came from Workshop.
There are three independent webhook sources. Each has its own destination URL, signing secret, and delivery filters, so you can send different event types to different endpoints (or the same one).
Source
Fires when
Filter
Audit events
Any change is made to Workshop (rules, settings, tags, etc.)
Event type
Signal reports
A detection signal report is first received, and again on each triage state change
Report state
Software approvals
A piece of software is approved through an approval workflow for the first time
Fires once for every audit event — the same record of every change made to Workshop that appears in the audit log, whether the change was made through the UI or the API. See the Audit documentation for the full list of audit event types.
By default every audit event is delivered. You can narrow delivery to specific event types; leave the filter empty to deliver all of them.
Fires when a detection signal report is first received from a host (state NEW) and again each time a report’s triage state changes (for example when it moves to ACKNOWLEDGED or REMEDIATED).
The state filter applies to both cases — receipt counts as the NEW state. Leave it empty to deliver for every state. The available states are NEW, ACKNOWLEDGED, INVESTIGATING, REMEDIATED, and DISMISSED.
Fires once, the first time a given piece of software (a binary or a bundle) is approved through any approval workflow — self-service, designated approver, or social voting. Subsequent approvals of the same software do not fire. See the Approval Workflows documentation for how approvals work.
This source has no filter. The payload’s requesting_user field identifies who requested the software for self-service and designated-approver workflows; it is empty for social voting, which has no single requester.
Navigate to Settings → Webhooks. Each source is configured in its own section with the following fields:
Enable toggle — turns delivery on or off. Disabling a source stops delivery but keeps its URL and secret so you can re-enable it later without re-entering them.
Destination URL — the HTTPS endpoint that receives deliveries.
Signing secret — the key used to sign every delivery (see Verifying signatures). It must be at least 24 bytes.
Filter — event types (audit events) or states (signal reports), where applicable.
Custom headers (audit events) — additional HTTP headers sent with every delivery, e.g. an Authorization header your receiver expects.
Click Save Changes to apply. Saving requires the write:settings permission.
Each delivery is an HTTP POST with a Content-Type of application/json. The body is a JSON object with exactly one field set, identifying the source:
Field
Source
audit_event
Audit events
signal_report
Signal reports
software_approval
Software approvals
Payloads are serialized from Workshop’s protobuf definitions, so:
Field names are snake_case and enum values are their string names (not numbers).
Every field is emitted even when empty — an unset string is "", a number is 0, a boolean is false, an unset nested object is null, and an empty list is []. Don’t assume a missing field; assume an empty one.
The examples below are trimmed to the fields worth highlighting; a real delivery includes the remaining fields at their empty values as described above.
Workshop signs every delivery using the Standard Webhooks scheme. The signature is an HMAC-SHA256 over the string {webhook-id}.{webhook-timestamp}.{body}, base64-encoded, and sent in the webhook-signature header as v1,<signature>.
The simplest way to verify is with one of the Standard Webhooks libraries, which handle the signature construction and comparison for you — construct a verifier with your configured secret and pass it the raw request body and headers. Note that the standard verification also enforces a 5-minute timestamp tolerance to guard against replay, so your receiver’s clock should be reasonably in sync.
Deliveries happen asynchronously, off the request path — a webhook failure never blocks or fails the underlying action (for example, an audited change still succeeds even if its webhook can’t be delivered). Delivery is best-effort: failures are logged server-side, but there is no delivery dashboard or manual re-drive.
Retries — after the initial attempt, a failed delivery is retried up to 5 more times (six attempts in total) with exponential backoff (starting at 100ms, capped at 30s). Retries happen on connection errors, HTTP 429, and 5xx responses.
Success — any 2xx response is treated as success. Redirects are not followed.
Timeouts — each attempt has its own 30s timeout, and the whole delivery — loading settings, building the client, and all attempts with their backoffs — is bounded to 60s.
Payload size — deliveries are capped at 1MB. A payload larger than that is dropped rather than sent.
Your endpoint should acknowledge quickly with a 2xx and do any heavy processing asynchronously.
Webhook settings can also be managed through the API:
GetWebhookSettings retrieves the current configuration for every source. Requires the read:settings permission. The write-only signing secret is never included in the response.
UpdateWebhookSettings replaces the configuration for every source. Requires the write:settings permission.
Because UpdateWebhookSettingsreplaces the entire configuration, include every source you want to keep in each call — omitting a source clears it. Sending an empty secret for a source keeps its existing secret rather than clearing it.