OXYGENOxygen/ Docs
Workspace

Tags

One label vocabulary across every primitive: declare and annotate tags, attach them on each owning surface, filter by them, and rename, merge, or delete them everywhere at once.

Tags are the campaign handle — there is no separate campaign object. Put the same label on a sequence, its lead table, the workflow feeding it, the conversations it produces, and its learnings wiki page, and tags get returns the whole footprint in one read.

A tag exists once it is declared (a registry row carrying a description, colour, and pinned flag) or carried (some item's tags array holds it). Either alone is enough, and drift is permanent in both directions: a declared tag nobody uses stays declared with a count of 0, and a carried tag nobody declared is fully real — it indexes, renames, merges, and deletes like any other.

Labels are lowercased, trimmed, and deduplicated, up to 50 per item. They are not slugified: "Q3 Outbound" becomes q3 outbound, spaces intact. Chip colour derives from the label unless someone sets an override, so the same tag looks the same everywhere by default.

Browse

oxygen tags list             # every tag with per-primitive counts, most-used first
oxygen tags get q3-outbound  # everything carrying the tag, deep-linked

/tags is the same read plus editing: search across labels and descriptions, All / Pinned / Unused facets, New tag, per-row Edit… / Rename… / Pin / Delete…, and a selection bar with Merge into… / Pin / Unpin / Delete. Each tag's own page groups its items by kind. Tag chips filter the sequencer, publishing queue, and unibox lists; ?tag= deep-links into a pre-filtered view.

Declare and annotate

oxygen tags create q3-outbound --description "Q3 founder-led launch" --color blue --pinned
oxygen tags update q3-outbound --clear-color --unpinned

create is idempotent and never touches carriers — running it on a tag forty items already carry just annotates it. Colours are the named set (gray, red, orange, amber, yellow, green, teal, blue, indigo, purple, pink); omit --color to keep deriving it from the label. update changes only the flags you pass; --clear-description and --clear-color remove a value. To change the label itself use tags rename.

Attach

Tags are attached on each primitive's own surface:

oxygen sequences create ... --tags q3-outbound,saas-founders
oxygen sequences update <sequence> --tags q3-outbound   # replaces the set; "" clears
oxygen tables tag <table> --tags q3-outbound
oxygen workflows tag <workflow> --tags q3-outbound      # org metadata; no new revision
oxygen knowledge page upsert --slug <slug> --tags q3-outbound ...
oxygen publishing tags set <post> --add q3-outbound     # add/remove deltas
oxygen inbox tag <conversation> --add q3-outbound       # add/remove deltas; --channel linkedin/whatsapp for DMs
oxygen crm tag companies <record> --add tier-1          # add/remove deltas (run `oxygen crm setup` once to add the attribute)
oxygen mailboxes tag <mailbox> --tags q3-pool           # pool sending identities under a campaign
oxygen senders tag <sender> --tags q3-pool
oxygen blueprints tag <blueprint> --tags q3-outbound    # a saved blueprint; no re-export needed
oxygen domains tag acme.com --tags q3-pool             # sending domains (survives `domains sync`)
oxygen projects tag outbound --tags q3-outbound        # table projects
oxygen senders profiles tag <id> --tags q3-pool        # a whole sending identity in one edit
oxygen voice numbers tag +14155550142 --tags q3-pool   # dialing numbers

Feeds carry no tags of their own: a live table's capture is part of the table, so oxygen tables tag is where a feed joins a campaign.

Most list commands accept --tag to filter — sequences list, publishing posts list, tables list, workflows list, messages query, blueprints list — each taking one tag.

Every sending-identity list — mailboxes, domains, senders, senders profiles, voice numbers — takes --tag as a comma-separated set instead, matching any of them:

oxygen mailboxes list --tag q3-pool,q4-pool

oxygen inbox list --tag is the exception: it filters on the tags of the conversation's campaign (its sequence), not the conversation's own tags. DMs have no campaign link, so a tag filter there returns email only.

An archived sequence is otherwise immutable but still accepts a tags-only update, so finished campaigns can still be filed into a learnings tag.

In the web app

Anywhere tags appear there is an editing affordance: Add tags beside a tag glyph on an item with none yet, collapsing to a + once it has some (tight call sites show the + in both states). It opens a picker listing the tags your workspace already uses, pinned first, each with its carrier count; type to filter. Pick any number of them; if what you type doesn't exist yet, choose Create "…" and it's added on save. On list rows, clicking an existing tag chip filters the list instead; the add affordance is what edits.

Your changes save when you close the picker. If someone (or the AI Inbox Tagger) adds a tag while you have it open, that tag is kept — the picker only applies what you actually changed.

Filtering the sending pool

On Sequencer → Accounts, every tab (Senders, LinkedIn, Email, WhatsApp, Phone numbers) has a Tags dropdown next to its search box. Pick one or more tags to narrow the list to anything carrying any of them; clicking a tag chip on a row does the same thing, and clicking it again removes it.

The Email tab lists inboxes under their domains, and both can be tagged. Tagging the domain is the shortcut: filter to that tag and the domain shows up with all of its inboxes, so you don't have to tag twenty inboxes one at a time. Combine the tag filter with another filter (say Provider) and it narrows to inboxes proper — a tagged domain with no matching inbox drops out.

Auto-tagging inbound conversations

The AI Inbox Tagger (a workspace agent at /agents/inbox-auto-tagger; the /agents nav entry is beta-gated) classifies every new inbound conversation against a tag allowlist you configure and applies the matches automatically — riding the same analysis call that already categorizes replies, so it adds no model cost. It only ever adds tags, and it never re-adds a tag you removed from a conversation.

oxygen inbox auto-tagger get
oxygen inbox auto-tagger set --enabled --tags "pricing-question,partnership,support-request"
oxygen inbox auto-tagger set --channels email,linkedin   # default is all three
oxygen agent get inbox-auto-tagger    # state + recent tag applications

--tags replaces the whole allowlist (max 50). --tags "" clears it, which pauses tagging while leaving the agent enabled.

Reshape the vocabulary

oxygen tags rename q3-outbound q3-founder-launch          # preview: per-kind counts, no writes
oxygen tags rename q3-outbound q3-founder-launch --apply

oxygen tags merge q3-outbound q3-old --into q3-founder-launch --apply
oxygen tags delete q3-old q3-scratch --apply              # IRREVERSIBLE

All three are preview-first: without --apply they print per-kind (and per-tag) would-change counts and mutate nothing. All three are unfiltered by liveness — archived and finished items are rewritten too, so an un-archive never resurfaces the old name. That is why a preview count can legitimately exceed what tags list shows, which hides archived carriers. All three are safe to re-run after a partial failure.

Rename onto an existing tag behaves exactly like merging into it. When a tag absorbs another, the surviving tag wins per field, but a field it left empty is filled from the first source that has one; pinned ORs. delete strips the tag from every carrier and removes its declaration.

Semantics worth knowing

  • Whole-set vs delta is per-surface, and the flag names it: --tags replaces every tag on the item (--tags "" clears them) with no preview step, so read the current tags first when you mean to edit rather than overwrite. Exactly three surfaces take --add/--remove deltas instead — publishing posts, inbox conversations, and CRM records — so the auto-tagger and your edits merge instead of clobbering each other. Every other surface is whole-set, projects, sending domains, sender profiles and phone numbers included.
  • The tag index hides finished work: archived tables, wiki pages, blueprints, domains, projects, sender profiles and conversations drop out, as do canceled posts, disabled mailboxes, disconnected senders, and released phone numbers. Archived sequences stay in.
  • The unibox's warmup/DMARC/bounced markers are system badges — derived state, not tags.
  • Tags carry no approvals and spend no credits — they are workspace metadata.

On this page