Collaboration
Comment threads, approval requests assigned to a named person, the opt-in gate that blocks a live launch, and workspace roles.
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
/collab, titled "Waiting on you", lists the approvals assigned to your login, plus comment threads that named you. It has no sidebar entry: open it from a notification email, by URL, or as Approvals in ⌘K. 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 Withdraw button on the pending request's card. Members and roles in the header goes to /collab/members.
/collab, /collab/approvals/<requestId>, and /collab/threads/<threadId> open by direct URL in every workspace, whatever its Beta features setting, so an emailed "you have been asked to approve" link always works. 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 record pages no longer show comment threads either. In the web app, threads and requests open only on their own /collab pages. Only sequences and tables take a gate, so approvals request on any other kind, such as a Knowledge page or a CRM record, 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, oxygen sequences create --from-table --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.
Workspace roles
Every member has one role. A refused request answers insufficient_role and names the permission the role lacks.
| Role | Can |
|---|---|
| Admin | Everything, including members and roles, billing, budgets and approval gates. |
| Member | Builds, sets up and runs the workspace, without member, billing, budget or approval-gate settings. |
Sales rep (rep) | Works their pipeline: finds and enriches leads, edits rows and runs enrichments in existing tables, works the CRM and Unibox, adds leads to existing sequences, uses Copilot and Oxygents and connects their own mailbox or LinkedIn account. Builds and sets up nothing else. |
| Viewer | Sees everything, comments, decides the approvals assigned to them and builds dashboards. Spends no credits. |
| Client | An agency's client: sees everything, comments and decides the approvals assigned to them. Nothing else. |
oxygen members role client@acme.com --role client # admin only
oxygen members list # everyone, and what their role allows
oxygen members role client@acme.com --role member # back to full member accessAPI keys and connected apps act with their person's role. Invite the person in Settings → Members first; a role set on an invited-but-not-joined address applies the moment they accept. On /collab/members, the Role column shows each member's role, and an admin's Change role column picks Admin, Member, Sales rep, Viewer or Client. Roles are held in Clerk, so the same role shows in Settings → Members, where an admin can change it too. oxygen approvals client grant|revoke still set and clear the client role.
From MCP
The collaboration tools are not in the default MCP tool set. Find them with oxygen_capabilities_search and run them through oxygen_capabilities_read or oxygen_capabilities_call, or connect with ?toolset=collaboration to list them directly. They follow the same rules as the commands above and are all free.
| Job | Tools |
|---|---|
| Ask, answer, and withdraw | oxygen_approvals_request, oxygen_approvals_inbox, oxygen_approvals_list, oxygen_approvals_decide, oxygen_approvals_cancel |
| Gates | oxygen_approval_gates_list, oxygen_approvals_gate_set |
| Comment threads | oxygen_comments_add, oxygen_comments_list, oxygen_comments_resolve, oxygen_comments_edit, oxygen_comments_delete |
| Members and roles | oxygen_workspace_members_list, oxygen_members_role_set, oxygen_members_workspace_role_set |
When all you have is an id from a notification email or a /collab link, pass it as request_id to oxygen_approvals_list or as thread_id to oxygen_comments_list.