Tags and labels configuration
Tags and labels are short string values attached to alerts and configuration. Unit Oncall maintains them as a per-Organization master so they auto-complete in the UI and stay consistent across resources. You normally do not create tag or label master entries by hand — they are populated automatically as alerts arrive and as configuration is saved.
This page explains how the master is populated, what status and source mean, and which Unit Oncall feature uses tags versus labels.
Tags vs labels
| Tags | Labels | |
|---|---|---|
| Where they appear | Bundle Settings, routing, alert grouping | Schedules, organizational metadata, search filters |
| Typical values | db, region:us-east, service:checkout | team:platform, env:prod, priority:high |
| Reserved prefix | _ (e.g. _notify:critical) — reserved for Unit Oncall, not added to the master | _ (e.g. _team:platform) — reserved for Unit Oncall, not added to the master |
Reserved tags that start with _ (such as _notify:*) are interpreted by Unit Oncall itself (for example to override notification routing). They are never added to the tag master.
Keep tags to values that repeat
Tags are normalized keys for routing and bundling, not a place to record what happened. An alert is grouped by a Bundle Settings entry only when its tag set is exactly equal to that entry's tags (see Bundle Settings), so a tag that differs per alert — host:web-03, instance:i-0ab12, pod:api-7f9c-xk2, a request ID, a timestamp, a numeric measurement — stops the alert from matching the entry you wrote for it.
Such an alert does not get a Bundle of its own. It falls into the Schedule's shared Default Bundle along with every other unmatched alert, and while that Bundle is open the alerts joining it raise no new notification (only an escalation to critical still pages). The risk of a varying tag is therefore not extra noise — it is unrelated incidents merging and going unnoticed.
Nothing is lost by leaving those values out: the payload your monitoring tool sent is kept in full on the alert as raw_payload, and it is what you read while investigating. Tags should carry the stable dimensions you route and group on — env:prod, service:checkout, region:us-east, team:platform — and the per-alert detail should stay in the payload. Which tags an alert ends up with is decided by your Transformation Rule.
Master entry fields
Each entry in the tag or label master has the following fields. They are read-only from the API: you can list and suggest them, but you do not edit them directly.
| Field | Type | Notes |
|---|---|---|
id | number | Master entry ID. |
organization_id | number | The Organization the entry belongs to. |
name | string | The normalized tag or label value (lower-cased and trimmed). Up to 200 characters. |
status | string | confirmed or candidate. See below. |
source | string | webhook (added by an incoming alert) or manual (added when a user saved configuration). |
usage_count | number | How many times this value has been observed while in the candidate state. Once an entry becomes confirmed, this value is no longer incremented. |
last_seen_at | string | RFC3339 timestamp of the most recent observation while in the candidate state. Once an entry becomes confirmed, it is no longer updated. |
created_at | string | RFC3339 timestamp of when the entry first appeared. |
Status: confirmed vs candidate
confirmed— the value is stable enough to suggest in autocomplete. An entry becomesconfirmedvia one of three paths:- It is in
key:valueform with a stable value (for exampleservice:checkoutorregion:us-east) when first seen. - A user adds it manually through saved configuration.
- It was a
candidateand has been observed repeatedly: after 3 observations the background upsert promotes it toconfirmedautomatically.
- It is in
candidate— the value has been observed but is not yet trusted. Free-form tags from incoming webhooks (anything that is notkey:value, pluskey:valuepairs whose value looks like a timestamp, UUID, IP, or large number) start as candidates and remain so until the auto-promotion threshold described above is reached.
Only confirmed entries appear in the suggestion API. Candidate entries are tracked so you can review them but they are not auto-completed.
Source: webhook vs manual
webhook— Unit Oncall extracted the value from an incoming alert payload via its transformation rule.manual— A user added the value by saving configuration. Manual entries from Bundle Settings, Schedule labels, and routing rule conditions are immediatelyconfirmed.
Lifecycle
Candidate entries that go unused are pruned automatically. By default, candidates that have not been seen for 30 days are removed by a background job. Confirmed entries are never automatically removed.
If a tag name's usage_count rises while its last_seen_at keeps moving forward, that is a signal you may want to promote it to a confirmed name (typically by reshaping it into a key:value form in your transformation rule).
Allowed characters
Tags and labels must consist only of:
- letters
A-Zanda-z - digits
0-9 - the symbols
-_.:/
and must be between 1 and 200 characters long.
Everything else is outside the supported character set: Japanese and other non-ASCII text,
full-width alphanumerics, emoji, spaces, and symbols such as + @ * % &.
This is deliberate. Tags and labels are identifiers, and the values that reach Unit Oncall come
overwhelmingly from the key:value conventions of monitoring tools (env:prod,
api-server_v2.1/beta, github.com/org/repo), which use exactly this character set. Restricting
to it also removes a class of values that look identical in a list but are different strings —
zero-width spaces, right-to-left overrides, and look-alike letters from other alphabets — so the
tag and label lists you review stay trustworthy.
Where the rule is enforced, and what happens when it is not met
The rule is applied differently depending on whether you are writing configuration or receiving an alert. Both behaviours are intentional.
| Writing configuration | Tags and labels on incoming alerts | |
|---|---|---|
| What | Tag / label master entries you add by hand, Runbook and Postmortem tags / labels, Schedule labels, Bundle Settings tags, Transformation Rule mappings.tags / mappings.labels with type: static, and test alerts | Values a monitoring tool sends you, extracted by a Transformation Rule using type: jsonpath or type: format |
| Behaviour | Rejected. The request fails with HTTP 400 and the configuration is not saved | Not supported, but accepted. The alert is stored and displayed with the value exactly as sent |
Nothing breaks when a monitoring tool sends a Japanese (or otherwise unsupported) tag. The alert arrives, is stored, and shows the tag as sent. What that tag cannot do is take part in configuration:
- It is not added to the tag or label master, so it never appears in autocomplete.
- It cannot be used for routing or bundling, because you cannot write it into a Routing Rule
condition or a Bundle Settings
tagslist in the first place — those are configuration and are rejected by the rule above. - As a result an alert whose only tags are unsupported matches no rule and follows your
default routing (the Webhook's
default_schedule_id), and is not grouped into a configured Bundle.
If you want such alerts routed or bundled, map them to a supported value in your Transformation
Rule — for example use mapping to translate the incoming value, or emit a type: static tag
alongside the extracted one.
Other validation rules (for values that get added to the master)
- Values that start with
_are reserved for Unit Oncall and are never added to the master, for both tags and labels. - Values are normalized before storage: leading/trailing whitespace is trimmed and characters are lower-cased.
- Manual additions are always stored as
confirmed. Webhook-sourced values are stored asconfirmedonly when they arekey:valuewith a stable value; otherwise they are stored ascandidate.
Examples
A confirmed tag added by a transformation rule that emits service:<name>. usage_count is frozen at the value the entry had at the moment it became confirmed (typically 0 for tags confirmed on first observation):
{
"id": 101,
"organization_id": 42,
"name": "service:checkout",
"status": "confirmed",
"source": "webhook",
"usage_count": 0,
"last_seen_at": "2026-06-05T01:00:00Z",
"created_at": "2026-06-01T09:30:00Z"
}
A candidate tag automatically extracted from a free-form alert payload. The next observation will be the 3rd one and will promote the entry to confirmed, freezing usage_count at 3:
{
"id": 102,
"organization_id": 42,
"name": "host-12ab",
"status": "candidate",
"source": "webhook",
"usage_count": 2,
"last_seen_at": "2026-06-04T22:14:00Z",
"created_at": "2026-06-04T22:10:00Z"
}
A confirmed label added when a Schedule was saved with labels: ["env:prod"]. Manual entries are confirmed from the start and usage_count is not incremented afterwards:
{
"id": 201,
"organization_id": 42,
"name": "env:prod",
"status": "confirmed",
"source": "manual",
"usage_count": 0,
"last_seen_at": "2026-06-05T00:00:00Z",
"created_at": "2026-06-05T00:00:00Z"
}
Related
- Bundle Settings —
tagshere are matched against the tag master. - Schedule —
labelsare stored in the label master. - Transformation Rule — produces the tags and labels seen by the master.
- Routing Rule — conditions can reference tag and label values.
