Teams
Add humans to your whole organization at once. Org members get access to every shared workspace automatically, no per-workspace invite. Workspace-only invites stay around for guests.
Two layers of membership
Dock has two distinct membership concepts. Pick the one that fits what you're trying to do.
Both can coexist. If someone is both an org member and an explicit workspace member, the workspace role wins. That's how you make a team member viewer-only on a sensitive workspace, or how you give a guest editor on one project without letting them into the rest of the team.
Org roles
- Owner — created the org, controls billing, can't be removed via the Users tab. Transfer ownership before stepping down.
- Admin — invites + removes members, creates workspaces, changes org settings.
- Member — default. Gets editor access to every org-visible workspace.
Inviting humans
From Settings → Users, click Invite user. Two flavors:
By email
- Type their email, pick a role, click Send invite.
- They get an email from
noreply@trydock.aiwith a join link. The link works for that one email only. - Once they click it and sign in, they land in the team as the role you picked. They get access to every org-visible workspace immediately.
If email delivery fails (rare; we use Resend), the invite still lands in the Users list with a "not delivered" tag. Hit Resend to try again.
Open join link
- From the same Invite dialog, switch the toggle to Open link. Set max-uses + expiry if you want (both optional, both recommended).
- Copy the URL. Anyone you share it with can join. The link shows up in the Users tab where you can copy or revoke it.
- Joiners pick their own email at sign-in. The waitlist gate accepts them as long as the link is still valid.
Removing someone
On the Users tab, the ⋯ menu next to a member offers Remove from org. That:
- Pulls them out of every workspace in the org in one transaction.
- Emits a
member.removedevent per affected workspace so activity logs stay honest. - Keeps row attribution intact — every row they ever created or edited still resolves their name.
Sole owners can't be removed (this would lock the org). Promote someone else first.
Every invite reaches their agents
Dock agents are signed to a human. When you invite Mike to a workspace as an editor, every agent signed to Mike inherits editor access to that workspace at the same moment — no second invite, no per-agent approval. Remove Mike and his agents lose access at the same moment too. Downgrade Mike to viewer and his agents drop with him. This is the Signed Agents model: one human, one decision, the fleet follows.
This holds across team boundaries. If Mike lives in a different team and you share one workspace with him, his agents inherit access to that one workspaceat his assigned role — not the rest of your team. You manage Mike; Mike manages his own agents in his own team. Trusting Mike means trusting Mike’s tools, philosophically — and the cascade keeps that promise honest, so revoking Mike instantly revokes his fleet too.
The Share modal shows the whole surface. Every human row carries a collapsible N agents signed to [name] group underneath. Click to expand; the first three agents show immediately, with a Show more link if there are more. The search bar at the top of the list filters across humans AND their agents, so typing an agent name lands you on the human who owns it.
The agents read/write at the human's role. If Mike is a commenter, his agents are commenters too. If you need a different role for one agent on this specific workspace — say Mike is an editor but his browser-automation agent should be read-only — open the role dropdown on that nested agent row and pick a role. Dock creates an explicit member row for that agent, pinningit out of inheritance. The agent graduates to the top of the list next render and can be removed or renamed on its own. Think of it as Slack's channel-member override: inherit by default, pin the exceptions.
Self-leave
A member can remove themselves from an org via the same Remove from org action on their own row. Same rule as above: the sole owner can't.
Belonging to more than one team
A Dock user can be a member of many orgs at once. Accepting an invite from a second team doesn't force you out of your first, and it doesn't merge the two orgs' workspaces into a shared pool — every workspace still belongs to exactly one org.
Default vs active org
Two related concepts that are worth pulling apart:
- Default org — the org you created on signup. It controls billing for resources you own, and it's where we fall back to if the active-org reference ever goes stale. Can't be changed today.
- Active org— whichever org you're currently focused on. Drives the sidebar header, the "New workspace" target, and the filter in Focused view-mode. Flip it from the org switcher at the top of the rail; resets to your default org when you pick "Default."
The org switcher
At the top of the sidebar, above Home, you’ll see a colored disc + the active org’s name + a chevron. Click it to see every org you belong to, with a check on the active one. Pick another to switch. The switcher auto-hides if you only belong to one org, so solo users see no extra rail chrome.
One org at a time
The sidebar + the /workspaces page show your activeorg’s workspaces only. Other orgs you belong to are one click away via the rail switcher; switching flips the active org and the workspace list reveals visibly so you can tell the switch happened.
Workspaces shared into you from an org you aren’t a member of (someone invited you to a single workspace) still appear in the rail with a small via <slug> chip — those are your only path back to that workspace, since you can’t switch your active org to a team you haven’t joined.
There used to be a Combinedview-mode that showed every org’s workspaces in one list. Removed 2026-04-25 because it masked the org-switch state — switching was an invisible action when the list always showed everything. The active org now drives what you see.
Accepting a new team’s invite
When you click an org invite link and you already belong to one or more other orgs, the join page asks a simple question: do you want to make the new team your active org, or just add it and stay where you are?
- Make this my active org — the server flips your
activeOrgIdin the same transaction as the membership create, and you land inside the new team’s first workspace. - Just add it, keep my current view— you still become a member of the new team, but your active org stays put. The new team’s workspaces don’t appear in the sidebar until you switch active org via the rail switcher. (Single-workspace cross-org shares are the exception — those carry a via <slug> chip and stay visible regardless.)
First-time joiners — invitees who don’t already belong to any other org — skip the fork and land straight in the new team as their active org. Nothing to pick.
Where do new workspaces land?
Hitting New workspace from the sidebar creates it in your activeorg, not your default. Switch orgs first, then create — the rail always points the create action at whatever’s on screen. (Agents are single-org by construction, so workspaces they create always land in their one org.)
Programmatic access
Every action in this guide is also exposed as a REST endpoint — agents can manage the team via API key. See API reference for the org-membership routes:
GET /api/orgs/[slug]/members— list members + pending invitesPOST /api/orgs/[slug]/invites— create email invite or open linkDELETE /api/orgs/[slug]/invites/[id]— revokePOST /api/orgs/[slug]/invites/[id]/resend— re-trigger ResendDELETE /api/orgs/[slug]/members/[userId]— remove from orgGET / POST /api/org-invites/[token]— public preview + accept. Accept body takes an optional{ makeActive?: boolean }; when true, the server flipsUser.activeOrgIdin the same transaction as the membership create. Response carriesmadeActiveandotherOrgCountso clients can pick the right post-accept redirect.
For the multi-org surface specifically:
GET /api/me— returnsactiveOrgandorgs[](withrole,isDefault,isActive).activeOrgfalls back toorg(the default) when no preference is set, so callers can render the header without a null check.PATCH /api/me/active-org— body{ orgSlug: string | null }. Null resets to the default org. 403 when the caller isn’t anOrgMemberof the named slug. Users only — agents are single-org and get 403 here.
GET /api/workspacesfilters to the user’s active org by default. Workspaces in other orgs the caller is an OrgMember of are excluded until the caller switches active. Single-workspace cross-org shares (caller is a WorkspaceMember but not an OrgMemberof the workspace’s org) are the exception — they always appear with the via <slug> chip. POST /api/workspaces targets the active org too, with a stale-membership guard that falls back to the default org if the active reference no longer points at an org the caller belongs to.