Workspaces
Sautikit's multi-tenant model: workspaces, members, roles, and invitations.
A workspace is the billing and access boundary in Sautikit. Numbers, the KES wallet, API keys, and call records all belong to a single workspace. One user may belong to multiple workspaces with independent roles. Members are invited by email and assigned a role of owner or member.
All API requests are scoped to a single workspace, determined by the API key or session used.
A workspace is created automatically when a new user completes onboarding. The workspace:
wallet_currency (KES for Kenya) at creation; this cannot be changed.country code (KE) that determines which numbers are available to claim.slug from the workspace name (used in invitation links).mpesa_account_ref (TS-XXXXXXXX) for M-Pesa Paybill payments.Users may create additional workspaces for separate projects or environments (e.g. staging vs production). Each workspace has its own wallet and number pool.
| Role | Permissions |
|---|---|
owner | Full access: manage members, billing, API keys, numbers, calls |
member | Access to numbers, calls, and API keys; cannot manage billing or remove other members |
A workspace must always have at least one owner. Attempting to remove the last owner or demote them returns 409 accounts.last_owner.
Owners invite collaborators by email. The invite flow:
Pending invitations can be listed, revoked, or re-sent via the API. An invitation that has not been accepted after 7 days expires automatically.
# List pending invitations
curl "https://api.sautikit.com/v1/invitations" \
-H "Authorization: Bearer $SAUTIKIT_API_KEY"
# Revoke an invitation
curl -X DELETE "https://api.sautikit.com/v1/invitations/{id}" \
-H "Authorization: Bearer $SAUTIKIT_API_KEY"Authentication is passwordless (magic link via email). After sign-in a session token is set. API access uses long-lived API keys scoped to a workspace; see the API keys concept for key creation and rotation.
Sessions are workspace-aware: the session middleware resolves the active workspace from the session cookie and makes it available to all API handlers. When a user switches workspace in the console, the active workspace context changes without signing out.
A single user can belong to multiple workspaces. The GET /v1/me endpoint returns the user's full membership list:
{
"user": { "id": "...", "email": "dev@example.com" },
"memberships": [
{
"workspace_id": "01900000-0000-7000-8000-000000000001",
"name": "Acme Production",
"slug": "acme-production",
"currency": "KES",
"country": "KE",
"role": "owner"
},
{
"workspace_id": "01900000-0000-7000-8000-000000000002",
"name": "Acme Staging",
"slug": "acme-staging",
"currency": "KES",
"country": "KE",
"role": "member"
}
]
}API keys are workspace-scoped: a key created in Acme Production cannot access Acme Staging resources.
Sautikit support may suspend a workspace for policy violations or payment issues. While suspended:
403 workspace.suspended.skipped_suspended; not retried).The workspace.suspended and workspace.unsuspended events are emitted to the outbox for internal use; they are not subscribable as customer-facing webhook events.