Create and verify a webhook endpoint
- Open Alerts, select New rule, and choose Webhook under Delivery.
- Enter an HTTP or HTTPS endpoint URL.
- Select Generate to create a strong HMAC secret, then copy and store it. The encrypted secret cannot be read back after the endpoint is saved.
- Save the enabled endpoint.
- Select Send test event in its endpoint row.
- Confirm that the inline result shows the receiver’s HTTP status and latency.
- Verify
X-Bisibility-Signatureagainst the raw request body with the copy-pasteable verifier.
webhook.test envelope; see Event envelopes.
After it succeeds, create a webhook-channel rule. Every enabled project endpoint
receives every webhook event; endpoints are not filtered by rule or event name.
Create a rule
- Open Alerts and select New rule.
- Choose all keywords, one keyword, or one tag as the scope.
- Select a condition and enter its threshold when required.
- Select one or more delivery channels.
- Save the rule and leave it enabled.
An incomplete downtrend window or an unranked check with no known position is
treated as unknown, not as recovery. An existing downtrend alert remains open
until five complete checks show that the condition cleared. It can be manually
muted while the state is unknown.
Delivery channels
- In-app: successful external delivery creates an in-app notification and the triggered alert remains visible in the alert feed.
- Email: requires a configured email provider with a
verified sender (
EMAIL_FROM). A user’s alert-email preference can disable delivery. - Slack: Slack tenant delivery is available as an API-only preview.
Workspace installation and channel management are not yet exposed in the
dashboard. Create rules with
channels: ["slack"]through the alert rules API. - Webhook: sends signed JSON to every enabled project endpoint when the rule includes the webhook channel.
WEBHOOK_ALLOW_PRIVATE_NETWORK=1 is limited to trusted
self-hosted networks.
Delivery attempts are recorded for every channel. A failed channel does not
prevent the remaining selected channels from being attempted.
Webhook events
Every outbound webhook is an HTTPPOST with Content-Type: application/json,
X-Bisibility-Timestamp (Unix seconds), and
X-Bisibility-Signature: sha256=<hex digest>. The signature is an HMAC-SHA256
of <timestamp>.<raw request body> using the endpoint secret. Verify the
signature against the raw body before parsing JSON.
An immediate alert uses alert.fired. Manual checks and other non-scheduled
checks stay immediate. All current envelopes use schemaVersion: 3, snake_case
field names, and strict public resource IDs: al_, kw_, prj_, and
alr_. The authoritative example and field contract are under
Webhook endpoints.
Digest event
Scheduled checks queue matching alerts until the digest flush runs. The default flush interval is five minutes and can be changed withALERT_DIGEST_FLUSH_INTERVAL. Alerts are grouped by rule, then one digest is
delivered to each configured channel and enabled webhook endpoint. This means a
consumer can receive one alert.digest containing multiple alerts for a
rule-and-endpoint pair during a flush.
alert.digest has the same version-2, snake_case contract. data.alerts
contains the complete batch, and every item has the same shape as
alert.fired.data. Its aggregate fields are alert_count, project_id,
rule_id, and suppressed_today_count.
Digest jobs contain at most 200 alerts. Any remaining pending alerts wait for a
later flush. Email summaries display the first 20 entries and a +N more line,
but webhook data.alerts is not shortened. alert_count always matches the
length of data.alerts.
Each rule has a daily budget of 20 delivery batches. An immediate alert or one
digest consumes one batch regardless of the number of recipients and channels.
One batch can fan out to every email recipient and enabled webhook endpoint.
When the budget is exhausted, pending alerts are suppressed until 00:00 UTC and
remain visible in the app. A webhook endpoint receives one
alert.daily_cap_reached notice for that rule and day; its data contains
project_id, rule_id, rule_name, and suppressed_count.
suppressed_today_count on a later digest reports alerts already suppressed for
that rule on the current UTC day.
Migration for webhook consumers
Keep handlingalert.fired as one alert per request. Add an alert.digest
branch that verifies the same signature and iterates data.alerts; do not treat
the digest object itself as a single alert. Consumers that only support
alert.fired should ignore unknown event types until they are updated. Handle
alert.daily_cap_reached separately if the integration needs to surface
delivery suppression.