Webhooks

Write-only HTTP endpoints for raising alerts from anywhere — CI, queue workers, third-party tools, internal scripts.

A webhook is a write-only alert endpoint scoped to a team. You create one in the dashboard, copy its URL identifier, and post signed JSON to it from anywhere — CI pipelines, queue workers, third-party platforms with outbound webhooks, internal scripts. Each POST either creates a new alert or is folded into an existing one.

Anatomy of a webhook

  • URL identifier — a short URL-safe string appended to /api/alerts/trigger/. Treated as a public token; the HMAC signature is what authenticates.
  • Default severity — the severity assigned when the POST doesn't specify one. Individual posts can override it.
  • Filter rules — Sentry-style conditions evaluated against the incoming payload. A rule can drop the alert or override its severity at the edge.
  • Notification policy — which policy pages people for incidents from this webhook. Left unset, the team's default policy applies.
  • Rate cap — each webhook accepts up to 60 requests per minute; requests above that get 429.

Triggering an alert

typescript
import { Zvono } from "@zvono/sdk";
 
const zvono = new Zvono({ secret: process.env.ZVONO_SECRET! });
 
const res = await zvono.alert("deploy-failures", {
  title: "Deploy failed: api-gateway",
  description: "Migration step exited with code 137",
  severity: "sev1",
  group_key: "deploy:api-gateway",
  metadata: {
    commit: "a1b2c3d",
    environment: "production",
    runId: 48211,
  },
});
 
console.log(res.status); // "created" | "occurrence_added" | "filtered" | "reopened"

Field reference

FieldTypeDescription
titlerequiredstringShort label (max 200 chars). Shown in Slack, the dashboard, and notifications.
descriptionstringLong-form context (max 2000 chars). Renders as the alert body in Slack.
severity"sev0" – "sev4"Overrides the webhook default. Drives notification policy routing.
metadataRecord<string, any>Arbitrary payload (max 100 KB, max 10 nesting levels). Available to filter rules.
group_keystringExplicit grouping key. Identical keys collapse into one alert until it's resolved.

Without the SDK

The SDK is just a convenience wrapper — any HTTP client works. POST signed JSON straight to the trigger endpoint: see Trigger alert for the request, headers, and error reference, and Authentication for how to sign the request body.

Filter rules

Every webhook can carry a list of filter rules — conditions evaluated against the incoming payload. Rules can match nested fields, regex patterns, and combinations of logical operators. A rule either drops the alert (returning filtered with a reason) or overrides its severity.

Example: a CI webhook that ignores alerts from feature branches but keeps anything on main:

text
IF metadata.branch != "main" THEN drop with reason "non-main branch"

Filters run before any quota or notification work, so dropped payloads cost nothing.

Sentry

A webhook can be created with Sentry as its source. A Sentry endpoint has its own URL (/api/integrations/sentry/<identifier>) and accepts Sentry's webhook format directly. You don't need code or the SDK. The source can't be changed after the endpoint is created.

  1. Create the endpoint with source Sentry.
  2. In Sentry, go to Settings → Developer Settings → Custom Integrations and create an Internal Integration. Set its webhook URL to the endpoint URL and turn on Alert Rule Action. Save it.
  3. Copy the integration's Client Secret and paste it into the Connect Sentry card on the endpoint page. Requests are verified against Sentry's Sentry-Hook-Signature header, and every request is rejected until the secret is saved.
  4. In any Sentry issue or metric alert rule, add the action Send a notification via your integration.
Sentry sendsZvono does
Issue alert firedCreates an alert. Each Sentry issue groups into one alert. fatal maps to sev1, error to sev2, warning to sev3, info/debug to sev4.
Metric alert critical / warningCreates an alert at sev1 / sev3. Each metric incident groups into one alert, so warning then critical raises the same alert's severity.
Anything else, including resolvesAcknowledged and listed as Ignored in the endpoint history. Resolve the alert in Zvono.

Sentry fields land in metadata (environment, release, level, project, rule, url, tags.*), so filter rules work on them. For example, metadata.environment eq production keeps only production errors. In tag names, dots and other punctuation become underscores, so Sentry's os.name tag is metadata.tags.os_name.

Response shape

json
{
  "alertId": "65f3...",
  "status": "created",
  "message": "Alert created",
  "occurrenceCount": 1,
  "reason": null
}

For the full status enum and grouping behaviour, see Alerts. For request signing details, see Authentication.