Typed ids

Embed
Preview of the card
<a href="https://watchtowerops.net/docs/ids"><img src="https://watchtowerops.net/docs/_api/public/orgs/aa5959cb-1a0b-4a9a-bc9a-913e7ac31cd9/spaces/b7aac181-9916-4805-b253-becc5fd2ca62/pages/07d415ad-ce34-483b-b9b4-66ba2562a13c/social-card.svg?v=3e7ae33eec8b" alt="Typed ids" width="600" height="315"></a>

Every id on the wire is <prefix>_ followed by 26 characters of lowercase Crockford base32 (0-9a-z without i, l, o, u; the first character is 0 to 7), for example prj_01m6fnwtzve9jba4rbantnq0jd. Regular expression for one kind: ^env_[0-7][0-9a-hjkmnp-tv-z]{25}$. Internally an id is a UUID v7, so ids sort by creation time. The OpenAPI document types them as string with a pattern of the form ^prj_[0-9a-hjkmnp-tv-z]{26}$ on every field whose name says which kind it holds (project_id, env_id, issue_id, ...); this table is the authority for the prefixes (crates/wt-domain/src/ids.rs). Fields that can hold several kinds, or an id from an outside system (user_id on end-user telemetry, for example), carry no pattern.

A request with an id of the wrong kind or a malformed one gets 404 for a path parameter and 400 (naming the field) for a body or query field. Some inputs that accept several kinds also take a bare hyphenated UUID.

Client-chosen ids

Most ids are made by the server. Route ids in the alert routing tree (rte_…, PUT /v1/projects/{prj}/routing) are chosen by the client: every node of the tree you send needs an id, new nodes included, so a client generates one (a UUID v7 in the encoding above) and keeps it across edits so the node keeps its identity. Query ids (watchtower-query-id header) are client-chosen too.

Prefix

Kind

org_

OrgId

prj_

ProjectId

env_

EnvId

usr_

UserId

cred_

CredentialId

key_

ApiKeyId

pip_

PipelineId

sq_

SavedQueryId

sqs_

ScheduledQueryId

rel_

ReleaseId

dep_

DeploymentId

iss_

IssueId

rul_

RuleId

alr_

AlertId

slo_

SloId

rte_

RouteId

rcv_

ReceiverId

sil_

SilenceId

mtw_

WindowId

ntf_

NotificationId

mon_

MonitorId

htk_

HealthTokenId

sch_

ScheduleId

esc_

EscalationPolicyId

inc_

IncidentId

agt_

AgentId

ent_

EntityId

con_

ConnectorId

wfl_

WorkflowId

team_

TeamId

ktx_

KeyTransactionId

pge_

PageId

ctm_

ContactMethodId

acf_

AgentConfigId

xdst_

ExportDestinationId

tpl_

TemplateId

pkd_

PublishableKeyId

jny_

JourneyId

rcm_

ReplayCommentId

rsh_

ReplayShareId

ppl_

ProfilePolicyId

prm_

PromptId

dst_

DatasetId

evl_

EvaluatorId

exp_

ExperimentId

rvq_

ReviewQueueId

inv_

InvestigationId

prp_

ProposalId

rbk_

RunbookId

act_

ActionId

mcp_

McpServerId

skl_

SkillId

bdg_

BudgetId

del_

DeletionRequestId

hld_

LegalHoldId

aro_

ArchiveObjectId

rhy_

RehydrationId

exs_

ExportScheduleId

dpl_

DataplaneId

flc_

FleetConfigId

rol_

RolloutId

rly_

RelayId

loc_

LocationId

plg_

PluginId

trt_

TraceTestId

prb_

ProbeId

sst_

SecretStoreId

sct_

ScimTokenId

afw_

AuditForwarderId

alw_

AllowlistId

Updated