Back to Home

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

TagsLabels
Where they appearBundle Settings, routing, alert groupingSchedules, organizational metadata, search filters
Typical valuesdb, region:us-east, service:checkoutteam: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.

FieldTypeNotes
idnumberMaster entry ID.
organization_idnumberThe Organization the entry belongs to.
namestringThe normalized tag or label value (lower-cased and trimmed). Up to 200 characters.
statusstringconfirmed or candidate. See below.
sourcestringwebhook (added by an incoming alert) or manual (added when a user saved configuration).
usage_countnumberHow 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_atstringRFC3339 timestamp of the most recent observation while in the candidate state. Once an entry becomes confirmed, it is no longer updated.
created_atstringRFC3339 timestamp of when the entry first appeared.

Status: confirmed vs candidate

  • confirmed — the value is stable enough to suggest in autocomplete. An entry becomes confirmed via one of three paths:
    1. It is in key:value form with a stable value (for example service:checkout or region:us-east) when first seen.
    2. A user adds it manually through saved configuration.
    3. It was a candidate and has been observed repeatedly: after 3 observations the background upsert promotes it to confirmed automatically.
  • candidate — the value has been observed but is not yet trusted. Free-form tags from incoming webhooks (anything that is not key:value, plus key:value pairs 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 immediately confirmed.

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-Z and a-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 configurationTags and labels on incoming alerts
WhatTag / 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 alertsValues a monitoring tool sends you, extracted by a Transformation Rule using type: jsonpath or type: format
BehaviourRejected. The request fails with HTTP 400 and the configuration is not savedNot 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 tags list 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 as confirmed only when they are key:value with a stable value; otherwise they are stored as candidate.

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"
}