Typed ids
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 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|