Collaboration
Comment threads, approval requests assigned to a named person, the opt-in gate that blocks a live launch, and the restricted client role.
Get a second person's documented go/no-go on the sequence about to launch or the list it sends to — and, when you want it, make that decision a precondition for the live launch. Comment threads hang off any workspace object, from a wiki page to a CRM record; approvals exist only where a gate does.
This is not the paid-action approval gate. That one asks you to authorize your own spend (--approved, --max-credits). This one asks somebody else to decide, stores their answer, and can hold the action until it arrives. Both can apply to the same launch.
Where it lives
Sidebar Data → Approvals opens /collab, titled "Waiting on you": approvals assigned to your login, plus comment threads that named you. Decide a card in place — Approve, Request changes, Reject, with an optional decision note. Withdrawing is the requester's move, not the assignee's: use approvals cancel, or the card's Withdraw button on the object's own panel. Members and roles in the header goes to /collab/members.
The sidebar entry is beta-gated — a workspace admin turns it on at /settings#/beta-features. The routes are not. /collab, /collab/approvals/<requestId>, and /collab/threads/<threadId> open by direct URL at either setting, deliberately: an emailed "you have been asked to approve" link must work for a client whose agency never flipped the toggle. Every approvals and comments command returns the matching URL as web_url.
Ask someone to decide
Sequence detail pages no longer show the comments or Approvals panels, and Knowledge files no longer show their comments panel. Use the commands below to request Sequence approval, and open an existing request or thread through its direct link. Existing requests, threads, and configured gates remain in place.
Table grids no longer show a Comments button or column and cell comment actions; table comments and sign-off requests remain available through the CLI and MCP. CRM records mount the thread half only. No gate covers Knowledge pages or CRM records, so approvals request on either is refused with gate_not_supported_for_subject. Table sign-off requests apply to the whole table.
oxygen approvals request --on sequence:9f1c2b7e --gate launch \
--assignee client@acme.com --title "Q3 outbound" --expires-hours 48
oxygen approvals inbox # what is waiting on you
oxygen approvals list --on sequence:9f1c2b7e # also --status, --mine, --limit
oxygen approvals show <requestId> # the id from an email or a /collab link
oxygen approvals decide <requestId> --approve --note "Copy is fine"
oxygen approvals cancel <requestId>You cannot assign yourself, and you cannot decide your own request — withdraw it with approvals cancel instead. Any one assignee can answer, and so can a workspace admin. Only --approve opens a gate: --changes-requested is a real answer that leaves it shut, and an expired request never opens one.
The gate
Asking blocks nothing on its own. A gate is workspace policy, and the owning primitive enforces it.
| Gate | Means | Set on | Refuses |
|---|---|---|---|
launch | approve before a sequence sends live | sequences | oxygen sequences start, oxygen sequences resume |
signoff | approve the table's rows before they are worked | tables | any enrollment from the bound source table — oxygen sequences enroll, a workflow's enroll step, the capture-feed sweep |
oxygen approvals gate set --default sequence --gate launch --required
oxygen approvals gate set --on sequence:9f1c2b7e --gate launch --not-required
oxygen approvals gate list --on sequence:9f1c2b7eEvery gate is off until an admin turns it on, and gate set is admin-only and CLI/MCP-only — the web app has no control for it. A gated sequence still previews, dry-runs, and shows its steps, copy, and cost to everyone; that is what the approver reads. Only the live start refuses, with approval_required naming the pending request and its assignees. The yes binds to what was approved: rewrite the sequence afterwards and the next live start refuses with approval_stale. Clearing the gate is not authorization to spend — the live start still needs its own --approved and caps, and a start that raises --max-credits or --max-live-sends above the approved ceiling is refused with approval_cap_exceeded.
Comments
Threads hang off the object, never inside it: resolving one changes no campaign.
oxygen comments add "Second step reads as a pitch" --on sequence:9f1c2b7e
oxygen comments add "Wrong domain" --on table:2b7e --path row:8f2c1a4d#email
oxygen comments list --on table:2b7e --status all
oxygen comments resolve <threadId> # --reopen flips it backAn @email in the body notifies that member. comments edit and comments delete are author-only and leave a trace.
The client role
The agency case: a login that can read the work, comment, and decide the approvals assigned to it — nothing else. Anything that runs, launches, spends, or reconfigures refuses with insufficient_role.
oxygen approvals client grant client@acme.com # admin only
oxygen approvals client list # everyone, and what they may do
oxygen approvals client revoke client@acme.comInvite the person in Settings → Members first; a grant on an invited-but-not-joined address applies the moment they accept. On /collab/members, the Access column shows who holds what, and an admin's Change access column switches a member between Full access and Client (restricted). An admin's role overrides the restriction, so the grant is refused until you demote them with oxygen orgs member-role <email> --role member.