Skip to content

Webhooks and event destinations

Route minimized BIMP events to signed webhooks, Slack, or Discord.

Event destinations send selected BIMP changes to the systems that need them. Generic webhooks receive a signed public event contract. Slack and Discord receive concise provider-native messages instead of the raw event.

Use event delivery for integration signals, not as a replacement system of record. Consumers should retrieve current BIMP state when a workflow needs more detail than the minimized event contains.

Organization owners and Security Administrators configure credentials under Settings → Integrations → Event destinations. A destination has one of three kinds:

  • Webhook sends a structured CloudEvents JSON document to a generic HTTPS endpoint.
  • Slack sends a minimized Slack message to a hooks.slack.com/services/ incoming-webhook URL.
  • Discord sends a minimized Discord message to a Discord /api/webhooks/ URL.

Endpoint URLs are encrypted and are never returned after creation. BIMP shows only a masked origin or provider-specific preview. Replace an endpoint through the explicit replacement action; generic webhook signing secrets use the separate rotation action and are shown only once.

A destination can have multiple event rules. Rules can cover the organization, events routed to one team, or one Policy Group. Policy Groups inherit the organization’s default notification team, can select a different team, or can explicitly disable inherited notification routing. Teams are notification audiences; they do not own or authorize Policy.

Generic webhooks include the Standard Webhooks headers:

webhook-id: <CloudEvent id>
webhook-timestamp: <Unix seconds>
webhook-signature: v1,<base64 signature>

Verify the exact request body before parsing it, reject stale timestamps, and deduplicate with webhook-id. During the compatibility period, BIMP also sends x-bimp-event-id, x-bimp-timestamp, and x-bimp-signature; new consumers should use the standard headers. Rotating a secret invalidates the previous secret immediately.

Generic destinations receive a structured CloudEvents 1.0 JSON document. BIMP projects a public payload before signing it. Public contracts contain resource IDs, state transitions, safe action names, and occurrence times. They exclude email addresses, actor identifiers, provider credentials, branch and file paths, raw errors, and arbitrary internal metadata.

Routing context such as the effective notification team is used internally and is not automatically copied into the delivered event. Slack and Discord never receive the raw CloudEvent; they receive a concise provider-native summary and an optional BIMP link.

The initial public catalog is:

  • bimp.policy_group.created|updated|published|deleted
  • bimp.policy_mapping.created|updated|deleted
  • bimp.snooze_request.created|reviewed|status_changed|reopened
  • bimp.remediation_pr.state_changed

Snooze Request events are the public projection of BIMP’s current internal Exception-review compatibility model. Commands, delivery telemetry, audit projections, onboarding progress, provider webhook receipts, administrative identity events, and raw background failures are internal-only and cannot be selected or replayed to a destination. Use GET /api/v1/event-types as the authoritative discoverable public catalog.

BIMP treats any 2xx response as success. A 410 Gone response disables the destination. 429 Too Many Requests and retryable 5xx or network failures use bounded exponential backoff; a valid Retry-After value is honored within the maximum delay. Requests have connection and response timeouts, do not follow redirects, and are retried at most four times after the initial attempt.

Failed attempts remain visible on the Event destinations page and eventually become dead letters. An administrator can replay a matching public event by its CloudEvent ID. Replays reuse the event ID, allowing receivers to retain their normal idempotency handling.

Customer endpoints must use HTTPS. Before every request BIMP validates the URL, resolves and pins DNS, and rejects loopback, link-local, private, reserved, or mixed public/private answers to protect against SSRF and DNS rebinding.

Use the Event destinations page to inspect attempts and dead letters. Queue a test delivery after creating or replacing an endpoint, then confirm the receiver validated the signature and recorded the CloudEvent ID.

Replay a public event by CloudEvent ID when a receiver missed or rejected it. The replay uses the same event ID, so normal idempotency handling should absorb duplicates without inventing a second business event.

Rotate a generic webhook secret when its handling boundary changes. Rotation invalidates the previous secret immediately, so coordinate the receiver update rather than leaving both values active “for a bit”. BIMP shows the new secret only once.