Technical docs
Staff
Overview
Support reference for the Staff area:
- `/staff`
- `/staff/ai/[employee_id]`
- `/staff/user/[user_id]`
What users see
- Main tabs: `Staff` and `Invites`.
- Trash view is reached from `View Deleted` and is labeled `Pending Deletion`.
- The invite dialog also opens from `?invite=true`.
- Primary actions on the active Staff view:
- `Invite Member`
- `Add AI Teammate`
- Empty state buttons:
- `Invite Member`
- `Add AI`
Staff tab
- Header title: `Staff Directory`.
- Description: `Manage your team members and AI Teammates in one place`.
- Current table filters:
- `Type`: `Team Member`, `AI Teammate`
- `Status`: `Active`, `Pending`, `Inactive`
- `Added`
- `Updated` or `Deleted` in trash view
- `Role`
- `AI Skill`
- Current behavior:
- The staff API currently returns the full list without server pagination, server filtering, or server search.
- Search, pagination, date filters, role filters, and skill filters are handled in the frontend.
- Human rows come from accepted organization memberships, not from pending invites.
- Trash view is AI-teammates only.
- Per-user Ally rows show a `Personal` badge in the name cell.
- Row actions:
- AI teammates: `Chat`
- All rows: click-through to the detail page
- Human teammates: no inline action button in the list
- Bulk actions:
- Active view: `Delete`
- Trash view: `Restore`
- Selection rules:
- active-view human owners cannot be bulk-selected
- active-view system AI teammates cannot be bulk-selected
- trash-view selection is AI-only
Invites tab
- Header title: `Pending Invites`.
- Description: `Track and manage pending organization invitations`.
- The invite dialog supports two delivery methods:
- send by email
- generate a shareable invite link
- Both delivery methods create the same backend invite record through `POST /api/organizations/{orgId}/invites/`.
- The dialog's `Administrator` option maps to backend invite role `admin`.
- The free-text `Position` field is currently UI-only and is not persisted by the backend invite model.
- Current filters:
- `Status`: `Pending`, `Accepted`, `Cancelled`, `Expired`
- `Role`: `Admin`, `Member`
- `Added`
- `Updated`
- Row actions:
- pending email invites: `Resend`, `Cancel`, `Copy invite link`
- pending link invites: `Cancel`, `Copy invite link`
- accepted, cancelled, and expired rows are read-only
- Invites use server pagination, but filtering and status presentation are handled in the frontend.
- The frontend treats a pending invite whose `expires_at` is in the past as `Expired` for display.
AI teammate detail
- Create route: `/staff/ai/new`.
- Create mode initially exposes only the `Rules` tab; the full tab set appears after the teammate is created.
- Tabs:
- `Rules`
- `Skills`
- `Storage`
- `Connectors`
- `PATs`
- `Telegram`
- `Logs`
- `Reports`
- `Jobs`
- `Schedulers`
- `API` only when channel is `API`
- Ally is a special case:
- their detail page hides `Storage`
- their detail page hides `API`
- Channel choices in the header:
- `Not selected`
- `Web Chat`
- `API`
- `Web Chat` shows a copy action for the chat widget snippet in the header.
- `API` uses a dedicated tab with:
- `API Endpoint`
- request examples and built-in request tester
- API request log filtered from workflow runs
- Jobs and schedulers are documented in jobs-and-schedulers.md.
- Connectors tab lets users enable or disable org MCP servers for that teammate. The tab description is `Connected systems and services`.
- PATs tab lets users create tokens that let external AI agents act as that teammate.
- Telegram tab lets users:
- connect a Telegram bot by pasting a BotFather token
- disconnect the linked bot
- reconnect the webhook when the bot is linked but webhook delivery is not active
- Telegram tab states:
- unlinked: `No Telegram bot is linked to this AI Teammate yet. Connect a bot to receive messages from Telegram.`
- linked + active webhook: `Connected` badge plus webhook success notice
- linked + missing webhook: warning notice plus `Reconnect webhook`
- Storage tab shows only the folders explicitly shared with that teammate; it no longer expands every file inside those folders into the table.
- The Storage table is centered on access-management metadata: shared folder name, location, current teammate access, grantor, and grant date.
- Storage table filters include created, modified, granted, team, and grantor.
- Folder row actions are `Open`, `Share`, and `Delete`.
- The empty state for AI teammate Storage still links back to `/storage`.
- Employee-backed search/list endpoints filter per-user Ally records so a signed-in user only sees their own Ally.
- Updating a per-user Ally keeps the name fixed as `Ally`; editable fields are the assistant settings such as description, role, instructions, model, tools, and voice configuration.
- System AI teammates cannot be deleted from the active Staff list, bulk delete, or the AI teammate detail page.
Human teammate detail
- Back action: `Back`.
- The route reads accepted organization users via `GET /api/organizations/{orgId}/users/{user_id}`.
- Pending invitations stay in the `Invites` tab and do not become human Staff rows.
- Overflow menu includes:
- `Open in new tab`
- `Remove` for non-owner rows only
- The page shows email, phone, location, joined date, and invited date when available.
API and realtime
- Staff list:
- `GET /api/organizations/{orgId}/staff`
- `GET /api/organizations/{orgId}/staff/deleted`
- Humans:
- `GET /api/organizations/{orgId}/users`
- `GET /api/organizations/{orgId}/users/{user_id}`
- `PUT /api/organizations/{orgId}/users/{user_id}/role`
- `DELETE /api/organizations/{orgId}/users/{user_id}`
- `POST /api/organizations/{orgId}/users/bulk-delete`
- `POST /api/organizations/{orgId}/users/bulk-restore`
- Invites:
- `POST /api/organizations/{orgId}/invites/`
- `GET /api/organizations/{orgId}/invites/`
- `DELETE /api/organizations/{orgId}/invites/{invite_id}/`
- `POST /api/organizations/{orgId}/invites/{invite_id}/resend`
- public acceptance flow: `/api/invites/{code}` and `/api/invites/{code}/accept`
- AI teammates:
- `GET /api/organizations/{orgId}/employees/`
- `POST /api/organizations/{orgId}/employees/`
- `GET /api/organizations/{orgId}/employees/{employee_id}`
- `PUT /api/organizations/{orgId}/employees/{employee_id}`
- `DELETE /api/organizations/{orgId}/employees/{employee_id}`
- `POST /api/organizations/{orgId}/employees/bulk-delete`
- `POST /api/organizations/{orgId}/employees/bulk-restore`
- `GET /api/organizations/{orgId}/employees/{employee_id}/external-urls`
- `GET /api/organizations/{orgId}/employees/{employee_id}/telegram`
- `POST /api/organizations/{orgId}/employees/{employee_id}/telegram`
- `DELETE /api/organizations/{orgId}/employees/{employee_id}/telegram`
- `PUT /api/organizations/{orgId}/employees/{employee_id}/telegram/webhook`
- Logs and MCPs:
- `GET /api/organizations/{orgId}/workflows/runs/`
- `GET /api/organizations/{orgId}/mcps`
- `GET /api/organizations/{orgId}/mcps?employee_id={employee_id}`
- `POST /api/organizations/{orgId}/mcps/{mcp_id}/employee/{employee_id}`
- `DELETE /api/organizations/{orgId}/mcps/{mcp_id}/employee/{employee_id}`
- Jobs and schedulers APIs are documented in jobs-and-schedulers.md.
- WebSocket events used by Staff/Invites:
- `organization.staff_user_added`
- `organization.staff_user_removed`
- `ai_employee.created`
- `ai_employee.updated`
- `ai_employee.deleted`
- `staff_employee.created`
- `staff_employee.updated`
- `staff_employee.deleted`
- `organization_invite.created`
- `organization_invite.updated`
Permission notes
- Staff and invite actions are organization-scoped and authorized by backend checks.
- Human removal and human bulk delete/restore are admin-or-owner only on the backend.
- Human role changes are owner-only on the backend.
- The current trash UI only surfaces deleted AI teammates even though backend user restore endpoints exist.