Outgoing webhooks

Using outgoing webhooks in Better Stack

  1. Go to Incidents -> Integrations β†’ Exporting data and find the Outgoing webhooks section.
  2. Click the Configure button.
  3. Click Add on the card of the webhook type you want: Incident webhook, Monitor webhook, or On-call change webhook.
  4. Enter your Webhook URL. Optionally, pick which events trigger the webhook and customize the request template.
  5. You're done. πŸŽ‰

Incident webhook

You will get a POST request when a new incident is created, acknowledged, resolved, reopened, or commented on. You can fetch the monitor details for the relationships.monitor field using the Monitors API.

When the event is comment, the request body also includes a top-level comment field with the comment's content and author.

Monitor webhook

You will get a POST request when a new monitor is created, updated, paused, unpaused, or deleted.

On-call change webhook

You will get a POST request when an on-call contact changes, or when someone's holiday starts or ends during their shift.

The default body lists everyone on shift in emails. Those of them on holiday are also in on_holiday_emails, and we don't alert them until their holiday ends. The change field is holiday when only a holiday started or ended, and on_call otherwise.

Metadata variables

Use these variables in the request body template of an incident or monitor webhook to send the metadata of the incident or monitor that triggered it. Replace Key with one of your metadata keys, keeping its case.

Variable What it renders
$METADATA.Key Every value of the key as text, separated by commas. Team members, teams, and other items render as their name.
$METADATA.Key.value The plain text values of the key, separated by commas.
$METADATA.Key.name The names of the team members, teams, monitors, on-call calendars, escalation policies, integrations, and Telemetry sources in the key, separated by commas.
$METADATA.Key.email The e-mail addresses of the team members in the key, separated by commas.
$METADATA.Key.values Every value of the key as a JSON array.
$METADATA_ARRAY All metadata as a JSON array.

$METADATA.Key.values and $METADATA_ARRAY replace a whole JSON value, so put them in the template without quotes. The other variables render text and are safe inside quotes.

Request body template of an incident webhook
{
  "incident": "$INCIDENT_ID",
  "severity": "$METADATA.Severity",
  "owner_emails": "$METADATA.Owner.email",
  "owners": $METADATA.Owner.values,
  "metadata": $METADATA_ARRAY
}

For an incident with the metadata Severity: low and Owner: Jane Doe, your server receives:

Output
{
  "incident": "123456",
  "severity": "low",
  "owner_emails": "jane@example.com",
  "owners": [{"type": "User", "item_id": 42, "name": "Jane Doe", "email": "jane@example.com"}],
  "metadata": [
    {"key": "Severity", "values": [{"type": "String", "value": "low"}]},
    {"key": "Owner", "values": [{"type": "User", "item_id": 42, "name": "Jane Doe", "email": "jane@example.com"}]}
  ]
}

Each value in $METADATA.Key.values and $METADATA_ARRAY has the shape of a metadata value in the Metadata API. Plain text is {"type": "String", "value": "low"}. Team members, teams, monitors, and other items carry their type, item_id, and name, plus email for a User. A monitor's type is Endpoint.

Key with spaces or punctuation?

Wrap the variable in curly braces, like ${METADATA.On-call team.values}. Curly braces work for every variable, for example ${INCIDENT_ID}. Also use them when a letter follows the variable.

When the incident or monitor doesn't have the key, $METADATA.Key.values renders [], so the body stays valid JSON. The .value, .name, and .email variables and a braced ${METADATA.Key} render an empty string. A bare $METADATA.Key stays in the body as written.

Using metadata in the webhook URL?

An incident webhook can also use $INCIDENT_ID, $TEAM_ID, and the $METADATA.Key variables in its Webhook URL. We percent-encode the metadata we substitute, so a value with a space or an ampersand keeps the URL valid.

Switch an older webhook to v3

Every outgoing webhook has a metadata_api_version. New webhooks start on v3, which renders the variables as described above. Webhooks that already used a metadata variable when we introduced v3 stay on the legacy v2, so their payloads keep the shape your server expects. Only the metadata variables differ between the versions.

On v2:

  • $METADATA_ARRAY renders one {"key": …, "value": …} entry per value, with "value": null for team members, teams, on-call calendars, escalation policies, and other values that aren't plain text.
  • $METADATA.Key renders only one value of the key, and only when it's plain text.
  • The .value, .name, .email, and .values variables don't exist.
  • Metadata in the webhook URL isn't percent-encoded.

Once your server handles the new shape, set metadata_api_version to v3 with the update outgoing webhook API. The web app has no setting for the version.

Testing webhooks

We recommend using RequestBin or Hookdeck for testing webhooks.

Monitoring webhooks

We recommend Hookdeck to confidently manage webhooks in production.