Tagging
One tag library per project. Any umbrella?, comment, release, triage row, or follow-up can carry tags. Creating a new tag takes one keystroke.
One tag library
Tags live at the project level. Open Settings → Tags to see the library: each tag is a row with a name, a color swatch, and a count of everything it's currently attached to.
Tags are scoped per project — cross-project reuse isn't a thing. Each project's roadmap has its own vocabulary and keeping them separate avoids stale tags from one product bleeding into another.
Attaches to anything
The tag model is polymorphic — the same tag can sit on any of these surfaces without a schema per kind:
- Umbrellas — render as chips on board cards and the umbrella modal.
- Comments — mark inbound comments spam, support-request, feature-request during moderation.
- Releases — tag security, breaking, beta so readers can skim by kind.
- Feedback (triage) — tag dupe, needs-info before a row is promoted.
- Follow-ups — operational tags like urgent, sent-by-founder.
Deleting a tag removes it everywhere it was attached. Deleting an entity detaches its tags from the join but leaves the tags in the library.
Create on the fly
The tag picker is autocomplete-first. Start typing: existing tags filter as you go. Press Enter on a name that doesn't match anything yet and a will create chip gets staged. Hitting save attaches existing tags and creates the new ones in one round trip.
Cancelling the popover discards the staged creates — nothing hits the library until you save.
Name normalisation
"Frontend", "frontend", and " Frontend " all resolve to the same tag row. The picker won't offer "Create 'frontend'" when Frontend already exists.
The tag's display name is whatever the first caller typed — later lookups don't rewrite it. If you want to rename, do it explicitly in the tag library.
On the public roadmap API
Umbrella tags ship in the public roadmap API payload so integrators can render chips on their own roadmap pages —bug, enhancement, area/auth. Tag visibility follows the umbrella: if the umbrella is public, its tags are public.
Tags on comments, triage rows, and follow-ups are admin-only — they're not rendered on any public surface.
Tagging API
One generalised endpoint handles attach/replace across every entity kind:
PUT /api/v1/projects/{project_id}/{entity_kind}/{entity_id}/tags
{
"tag_ids": ["01HX...", "01HX..."],
"names": ["frontend", "needs-design"]
}entity_kind is one of umbrella, comment,release, feedback,follow_up. The body replaces the full tag set on the entity. names gets normalised, deduped, and resolved via ensure-or-create.
For typeahead, hit GET /api/v1/projects/{project_id}/tags?q=fro — prefix matches sort first, substring matches follow, capped at 50.