> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tallwatch.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Template variables

> Every variable you can interpolate in a webhook Handlebars template, with its type and an example value.

This is the complete set of variables available inside a webhook [Handlebars template](/webhooks/templates). They mirror the [canonical payload](/webhooks/payload) one-to-one, so anything you see in the default body, you can interpolate. Use dot-notation for nested fields: `{{monitor.name}}`, `{{incident.status}}`.

<Tip>
  The dashboard ships the same list behind the **Insert variable** popover on the channel form, and the live preview renders against the example values below. This page is the standalone reference for the same set.
</Tip>

The example values come from a sample `incident.opened` event. On other events some fields shift: `incident.resolved_at` and `incident.duration_sec` populate on resolve, `incident` and `check` are `null` on a `test` event. The per-event behavior is documented field-by-field on the [Payload page](/webhooks/payload).

## Top level

| Variable          | Type              | Example                    |
| ----------------- | ----------------- | -------------------------- |
| `{{event}}`       | string            | `incident.opened`          |
| `{{occurred_at}}` | string (ISO 8601) | `2026-06-10T14:32:08.000Z` |

`event` is one of `incident.opened`, `incident.acknowledged`, `incident.resolved`, `incident.escalated`, `incident.flapping`, `monitor.paused`, `monitor.resumed`, or `test`.

## `org`

The workspace that owns the monitor.

| Variable       | Type          | Example                                |
| -------------- | ------------- | -------------------------------------- |
| `{{org.id}}`   | string (UUID) | `00000000-0000-0000-0000-0000000000aa` |
| `{{org.slug}}` | string        | `acme`                                 |
| `{{org.name}}` | string        | `Acme Inc`                             |

## `monitor`

The monitor the event is about. Always present, even on a `test` event (a synthetic demo monitor).

| Variable           | Type          | Example                                |
| ------------------ | ------------- | -------------------------------------- |
| `{{monitor.id}}`   | string (UUID) | `00000000-0000-0000-0000-000000000000` |
| `{{monitor.name}}` | string        | `API production`                       |
| `{{monitor.type}}` | string        | `http`                                 |
| `{{monitor.url}}`  | string        | `https://api.example.com/health`       |

`monitor.type` is one of `http`, `tcp`, `ping`, `dns`, `ssl`, `keyword`, `heartbeat`. `monitor.url` is present only for `http` and `keyword` monitors; it renders empty for the others.

## `incident`

The incident this event belongs to. Present on every `incident.*` event; `null` on `test`. Reference its fields without guarding only when you know the event carries an incident.

| Variable                       | Type                      | Example                                |
| ------------------------------ | ------------------------- | -------------------------------------- |
| `{{incident.id}}`              | string (UUID)             | `00000000-0000-0000-0000-000000000001` |
| `{{incident.status}}`          | string                    | `open`                                 |
| `{{incident.opened_at}}`       | string (ISO 8601)         | `2026-06-10T14:32:08.000Z`             |
| `{{incident.acknowledged_at}}` | string (ISO 8601) \| null | `null` until acknowledged              |
| `{{incident.resolved_at}}`     | string (ISO 8601) \| null | `null` while open                      |
| `{{incident.duration_sec}}`    | number \| null            | `null` while open                      |
| `{{incident.failing_regions}}` | string\[]                 | `["fra1", "iad1", "sgp1"]`             |

`incident.status` is one of `open`, `acknowledged`, `resolved`. Region codes are `fra1`, `iad1`, `hil1`, `sgp1`, `syd1`, `gru1`. `failing_regions` is empty on resolve, since every region agrees the monitor is back up.

## `check`

The latest probe behind the event. Present on incident events; `null` on `test`.

| Variable                       | Type           | Example                      |
| ------------------------------ | -------------- | ---------------------------- |
| `{{check.last_response_ms}}`   | number \| null | `8123`                       |
| `{{check.last_error_class}}`   | string \| null | `timeout`                    |
| `{{check.last_error_message}}` | string \| null | `Request timed out after 8s` |

`last_error_class` is a stable category like `timeout`, `dns_resolve`, `tls_cert_invalid`, or `http_status`. Both error fields are `null` on resolve.

## Usage examples

Handlebars renders a missing value as an empty string, so a field that's `null` (like `incident.resolved_at` on an open event) interpolates to nothing rather than the literal `null`. Branch on it instead of comparing strings:

```handlebars theme={null}
{
  "subject": "{{#if incident.resolved_at}}[RESOLVED]{{else}}[OPEN]{{/if}} {{monitor.name}}",
  "regions": "{{#each incident.failing_regions}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}"
}
```

That renders `[OPEN] API production` and `fra1, iad1, sgp1` for the sample event above.

There's no `{{event}}` equality helper, so guard on the field that distinguishes the case. `incident` and `check` are `null` on a `test` event, so a `#if` on either short-circuits cleanly:

```handlebars theme={null}
{
  "text": "{{monitor.name}} is {{incident.status}}",
  {{#if check}}
  "latency_ms": {{check.last_response_ms}},
  {{/if}}
  "event": "{{event}}"
}
```

See [Templates](/webhooks/templates) for full worked examples (Slack, Datadog, Statuspage) and the escaping caveats.
