Site: Planekeeper Docs — Monitor software versions across your stack. Planekeeper tracks releases, gathers version data, and alerts on drift.
Section: Reference > Template variables
Source: https://docs.planekeeper.com/reference/template-variables/
Title: Template variables
Author: Planekeeper
Description: Complete reference of template variables available in notification templates, organized by event category with example snippets.
Word count: 588
Reading time: 3 min

Contents:
- [Common variables](#common-variables)
- [New alert templates](#new-alert-templates)
  - [Additional variables](#additional-variables)
  - [Example: simple text](#example-simple-text)
  - [Example: with acknowledge link](#example-with-acknowledge-link)
- [Acknowledged templates](#acknowledged-templates)
  - [Additional variables](#additional-variables)
  - [Example: conditional text](#example-conditional-text)
- [Resolved templates](#resolved-templates)
  - [Additional variables](#additional-variables)
  - [Example](#example)
- [Template functions](#template-functions)
  - [Using functions in templates](#using-functions-in-templates)
- [Template resolution priority](#template-resolution-priority)
- [Event-to-category mapping](#event-to-category-mapping)
- [Escaping special characters](#escaping-special-characters)

***

# Template variables


Notification templates use Go template syntax to insert dynamic values into webhook payloads. Variables are enclosed in double curly braces: `{{.VariableName}}`.

## Common variables

These variables are available in all template categories.

| Variable | Type | Description |
|----------|------|-------------|
| `{{.IdempotencyKey}}` | string | UUID that remains stable across retries for the same delivery |
| `{{.Event}}` | string | Event type that triggered the notification |
| `{{.Timestamp}}` | string | ISO 8601 timestamp of when the event occurred |
| `{{.Alert.ID}}` | number | Unique alert identifier |
| `{{.Alert.ConfigName}}` | string | Name of the alert configuration |
| `{{.Alert.RuleName}}` | string | Name of the monitoring rule |
| `{{.Alert.RuleType}}` | string | Rule type: `days_behind`, `majors_behind`, or `minors_behind` |
| `{{.Alert.Severity}}` | string | Current severity: `critical`, `high`, or `moderate` |
| `{{.Alert.DiscoveredVersion}}` | string | Version found in your repository |
| `{{.Alert.LatestVersion}}` | string | Latest upstream version available |
| `{{.Alert.BehindBy}}` | number | How far behind (days, major versions, or minor versions) |
| `{{.Alert.ArtifactName}}` | string | Upstream artifact identifier (e.g., `github.com/kubernetes/kubernetes`) |
| `{{.Alert.RepositoryURL}}` | string | Git repository URL from the scrape job |
| `{{.Alert.TargetFile}}` | string | File path parsed by the scrape job |

---

## New alert templates

Use the `new_alert` template category for `alert.created` and `alert.escalated` events. These templates fire when a new violation is detected or an existing alert increases in severity.

### Additional variables

| Variable | Type | Description |
|----------|------|-------------|
| `{{.AcknowledgeURL}}` | string | One-click acknowledgment URL for external systems |
| `{{.PreviousSeverity}}` | string | Previous severity level (only present on escalation events) |

### Example: simple text

```json title="new_alert template"
{
  "text": "ALERT: {{.Alert.ConfigName}} - {{.Alert.DiscoveredVersion}} is {{.Alert.BehindBy}} {{.Alert.RuleType}} behind latest ({{.Alert.LatestVersion}}). Severity: {{.Alert.Severity | upper}}"
}
```

### Example: with acknowledge link

```json title="new_alert template with ack URL"
{
  "text": "{{.Alert.Severity | upper}}: {{.Alert.ConfigName}}\nCurrent: {{.Alert.DiscoveredVersion}} | Latest: {{.Alert.LatestVersion}}\nBehind by: {{.Alert.BehindBy}}\nAcknowledge: {{.AcknowledgeURL}}"
}
```

---

## Acknowledged templates

Use the `acknowledged` template category for `alert.acknowledged` and `alert.unacknowledged` events. These templates fire when a user acknowledges an alert or when an acknowledgment is reset due to a version change.

### Additional variables

| Variable | Type | Description |
|----------|------|-------------|
| `{{.IsAcknowledged}}` | boolean | `true` for acknowledged, `false` for unacknowledged |
| `{{.AcknowledgedBy}}` | string | Email or identifier of the user who acknowledged |
| `{{.AcknowledgedAt}}` | string | ISO 8601 timestamp of when the acknowledgment occurred |

### Example: conditional text

```json title="acknowledged template"
{
  "text": "{{if .IsAcknowledged}}Acknowledged{{else}}Unacknowledged{{end}}: {{.Alert.ConfigName}} ({{.Alert.ArtifactName}}){{if .IsAcknowledged}} by {{.AcknowledgedBy}}{{end}}"
}
```

---

## Resolved templates

Use the `resolved` template category for `alert.resolved` events. These templates fire when a version update causes the alert to no longer violate its rule.

### Additional variables

| Variable | Type | Description |
|----------|------|-------------|
| `{{.ResolvedAt}}` | string | ISO 8601 timestamp of when the alert was resolved |

### Example

```json title="resolved template"
{
  "text": "Resolved: {{.Alert.ConfigName}} - {{.Alert.ArtifactName}} is no longer behind. Resolved at {{.ResolvedAt}}"
}
```

---

## Template functions

Three built-in functions transform values inline.

| Function | Syntax | Input | Output |
|----------|--------|-------|--------|
| `upper` | `{{.Alert.Severity \| upper}}` | `critical` | `CRITICAL` |
| `lower` | `{{.Event \| lower}}` | `Alert.Created` | `alert.created` |
| `json` | `{{.Alert \| json}}` | (object) | `{"id":1,"severity":"critical",...}` |

### Using functions in templates

Pipe a variable to a function with the `|` operator:

```json title="Using upper for emphasis"
{"text": "{{.Alert.Severity | upper}} ALERT: {{.Alert.ConfigName}}"}
```

This produces: `CRITICAL ALERT: My Alert Config`

---

## Template resolution priority

When Planekeeper sends a notification, it looks for a template in this order:

1. **Channel-specific template** -- set in the notification channel's event_templates configuration
2. **Organization-level template** -- set via the Settings page
3. **Global default template** -- set at the system level
4. **Standard JSON payload** -- the built-in default format with no template applied

The first non-empty template found is used. Leave a template blank at any level to fall back to the next level.

---

## Event-to-category mapping

| Event type | Template category |
|-----------|-------------------|
| `alert.created` | `new_alert` |
| `alert.escalated` | `new_alert` |
| `test` | `new_alert` |
| `alert.acknowledged` | `acknowledged` |
| `alert.unacknowledged` | `acknowledged` |
| `alert.resolved` | `resolved` |

---

## Escaping special characters

Templates are embedded inside JSON strings. Escape these characters:

| Character | Escape sequence |
|-----------|----------------|
| Double quote | `\"` |
| Newline | `\n` |
| Backslash | `\\` |
| Tab | `\t` |

```json title="Escaped newlines for multi-line output"
{"text": "Alert: {{.Alert.ConfigName}}\nSeverity: {{.Alert.Severity | upper}}\nVersion: {{.Alert.DiscoveredVersion}}"}
```

> **success:** 
**Test before enabling**

Use the channel test button to verify your template produces valid output for the target platform. Template syntax errors are caught during the test and reported in the results.



---

## Related

- Next: [Version Transforms](https://docs.planekeeper.com/reference/version-transforms/page.md) — Reference for version transform options that normalize version strings extracted by scrape jobs.
- Section: [Reference](https://docs.planekeeper.com/reference/index.md)
