API — Team access
Managing who has a login into a workspace, what they can see and edit, and from which devices — members, roles, and per-device approval.
The reference counterpart to Manage team access.
Mounted under /api/admin/team/* through the shared admin router
(app/api/admin/__init__.py → app.include_router(admin_router, prefix='/api/admin')),
authenticated with require_admin_principal. Only the workspace owner, or a
team member with manager rank, can call these — see
Manage team access for the rank model.
Password handling
A password is accepted only on create or an explicit reset. It is never returned by any endpoint, including the member you just created.
Members
| Endpoint | Purpose |
|---|---|
GET /team/members | List active grants in the workspace. A manager sees workers and themself, not other managers. |
GET /team/assignable-accounts | What can be scoped to a member — creators and their pages. Served from this router (not the Accounts tab) so a manager without Accounts access isn't blocked from granting scope. |
POST /team/members | Create a login: username, password, and either a role_id or an explicit set of tabs/edit-tabs/caps/money-mode. |
PATCH /team/members/{member_id} | Update label, permissions, shift settings, or account scope. |
DELETE /team/members/{member_id} | Revoke: grant status → revoked, username freed for reuse, and every active session for that member is killed immediately (a watermark, not a poll). |
A create/update body sets permissions either from a role_id or as its
own explicit tabs/edit_tabs/caps/money_mode — never both. Sending both when a
role_id is set fails 422 role_locked: detach the member from the role
first if you need to edit their permissions individually. A manager can never
grant a rank or a permission wider than their own.
Two independent axes live on the same row and are easy to conflate: money_mode
(hide/blur/show — how figures are displayed) and data_scope
(own/own_subs/all — whose data the member can see at all).
Roles
| Endpoint | Purpose |
|---|---|
GET /team/roles | List the workspace's role presets, optional q name filter. |
POST /team/roles | Create a named role: permission set + shift defaults. |
PATCH /team/roles/{role_id} | Update a role, or archive it (archived: true — existing holders keep it, it just can't be newly granted). |
DELETE /team/roles/{role_id} | Delete — 409 role_in_use if any member currently holds it. Archive it instead to stop offering it while keeping current holders. |
A role's shift_mode/shift_sources/shift_self_start fields validate
against the shift vocabulary owned by Club
(app.products.club.core.shift.{SHIFT_MODES,SHIFT_SOURCES,SELF_START_MODES})
— this router imports those constants directly rather than duplicating them.
Devices
| Endpoint | Purpose |
|---|---|
GET /team/devices | List devices seen for the workspace, optionally filtered to one member_id. A manager sees only their subordinates' devices. |
PATCH /team/devices/{device_id} | Approve, revoke, or rename one device. |
A member row can require device approval (device_gate on
the member record) — this endpoint is where that approval,
revocation, or rename actually happens, and where a stolen or lost device
gets cut off.
What's next
For the everyday walkthrough of inviting someone and setting their access, see Manage team access.
API — Account API keys
A creator mints their own Bearer API keys to drive the platform from their own Claude / MCP client — create, list, and revoke, scoped to that creator's tenant only.
Admin endpoints
Every internal endpoint the Account Platform panel calls under /api/admin/* — path, method, what it does, owner-only or not. Not the public API.