Skip to content

Workspaces & members

A workspace is the tenancy boundary: every product resource lives under one, and your membership (with role owner, admin, member, or guest) is checked before any workspace-scoped call runs. Non-members get 404 — see the overview on existence hiding.

Session JWTs and API keys both work on this page’s endpoints unless noted.

Endpoint Description
POST /v1/workspaces Create a workspace {name, subdomain, mailboxLocal?} — auto-provisions the <subdomain>.knobs.io mail domain and your owner membership (session-only)
GET /v1/workspaces List my workspaces
GET /v1/users/me/workspaces Same list, canonical path
GET /v1/workspaces/{wid} Workspace record: name, plan, default domain, addressFormat
PATCH /v1/workspaces/{wid} Rename / switch default domain / set addressFormat (admin) — {name?, defaultDomainId?, addressFormat?}
Terminal window
curl -X POST https://api.knobs.io/v1/workspaces \
-H "Authorization: Bearer <session-jwt>" \
-H "Content-Type: application/json" \
-d '{"name": "Acme", "subdomain": "acme", "mailboxLocal": "jane"}'

Returns 201 with the workspace record. The subdomain must be globally unique (409 subdomain_taken otherwise).

Terminal window
curl -H "Authorization: Bearer knak_..." https://api.knobs.io/v1/users/me/workspaces
{
"workspaces": [
{ "workspaceId": "w_31ab…", "name": "Acme", "role": "owner" }
]
}
Endpoint Description
GET /v1/workspaces/{wid}/members List active members with directory fields (any member)
POST /v1/workspaces/{wid}/members Add an existing user {uid, role} (admin) — for onboarding new people, prefer Invites
Terminal window
curl -H "Authorization: Bearer knak_..." \
https://api.knobs.io/v1/workspaces/{wid}/members
{ "members": [ { "uid": "u_9f2c…", "role": "owner", "email": "jane@acme.knobs.io", "name": "Jane" } ] }

Groups are named member rosters usable as sharing principals (grp_… ids in docs/sheets/calendar access grants) and, when given an address, as mail distribution lists. Reads are member-visible; mutations require a workspace admin or a group manager.

Endpoint Description
POST /v1/workspaces/{wid}/groups Create {name, description?, access: "internal"|"external"} (admin)
GET /v1/workspaces/{wid}/groups List groups with rosters
GET /v1/workspaces/{wid}/groups/{gid} One group
PATCH /v1/workspaces/{wid}/groups/{gid} Rename / description / access-mode switch
POST /v1/workspaces/{wid}/groups/{gid}/archive Archive (groups are never deleted)
POST /v1/workspaces/{wid}/groups/{gid}/members Add {uid, manager?} — active workspace members only
DELETE /v1/workspaces/{wid}/groups/{gid}/members/{uid} Remove from the roster

A group may claim one address on a verified workspace domain; inbound mail to it is delivered to every internal member’s inbox. Address management is admin-only.

Endpoint Description
POST /v1/workspaces/{wid}/groups/{gid}/address Claim {domainId, localPart} as the group’s address (admin)
DELETE /v1/workspaces/{wid}/groups/{gid}/address Remove the address — the mailbox is disabled, never deleted (admin)

External groups can carry outside email addresses that group mail is remailed to. Admins or group managers manage the list (cap 50). A member whose address hard-bounces is auto-disabled (status: "bounced"); recipients can also unsubscribe themselves via the list-unsubscribe link.

Endpoint Description
POST /v1/workspaces/{wid}/groups/{gid}/external-members Add {email} to the remail list
DELETE /v1/workspaces/{wid}/groups/{gid}/external-members/{email} Remove an external member
POST /v1/workspaces/{wid}/groups/{gid}/external-members/{email}/reactivate Re-enable a bounced or unsubscribed member
Terminal window
curl -X POST https://api.knobs.io/v1/workspaces/{wid}/groups \
-H "Authorization: Bearer knak_..." \
-H "Content-Type: application/json" \
-d '{"name": "Design", "access": "internal"}'

Switching an external group back to internal requires its external-member list to be empty (409 externals_present).