Workspaces
A workspace (called an account in the data model — the two terms are interchangeable for historical reasons) is the configuration boundary inside Huudis. OIDC clients, identity providers, IAM policies, members, webhook subscriptions, and audit logs all hang off one workspace. See Concepts → Workspace for the model.
A single human can belong to many workspaces — one personal, one for the company, one for each client they consult for — and switches between them. The active workspace is a property of the calling session, not the URL.
All requests on this page require a bearer admin JWT — see Authentication.
Endpoints
| Method | Path | Purpose |
|---|---|---|
GET |
/v1/account/workspaces |
List workspaces the calling user belongs to |
POST |
/v1/account/workspaces |
Create a new workspace |
PATCH |
/v1/account/workspaces/:id |
Rename |
POST |
/v1/account/workspaces/:id/switch |
Set the active workspace on the calling session |
Delete is not currently exposed via the API. Workspaces accumulate data (audit logs, billing rows) we don't safely cascade. To wind one down, remove every member and cancel the subscription — the row stays as a tombstone.
List workspaces
GET /v1/account/workspaces
Returns every workspace the calling user is a member of, oldest-joined first. The currently active one is flagged via isActive: true.
Response — 200 OK
{
"data": [
{
"id": "acc_01KPG30SQTDDZ469FGR7DBE0DC",
"name": "Forjio Headquarters",
"slug": "forjio-headquarters",
"createdAt": "2025-12-04T10:42:00.000Z",
"role": "owner",
"joinedAt": "2025-12-04T10:42:00.000Z",
"isActive": true,
"isForjioInternal": false
},
{
"id": "acc_01KPG31…",
"name": "Cafe Sumur",
"slug": "cafe-sumur",
"createdAt": "2026-02-11T14:00:00.000Z",
"role": "member",
"joinedAt": "2026-02-11T14:00:00.000Z",
"isActive": false,
"isForjioInternal": false
}
]
}
isForjioInternal: true flags Huudis's own operational workspaces (e.g., the one that contains the huudis-dashboard first-party client). Most callers can ignore the flag; it exists so the dashboard can mark those rows.
Create a workspace
POST /v1/account/workspaces
Creates a new workspace owned by the calling user. The user is added as owner, the session's active workspace switches to the new one in the same transaction, and an audit-log entry is written.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name |
string (1–120) | yes | Display name. Used to derive slug — you don't pick that explicitly. |
Response — 201 Created. The new workspace, with role: "owner", isActive: true.
{
"data": {
"id": "acc_01KPG40…",
"name": "Cafe Sumur",
"slug": "cafe-sumur",
"createdAt": "2026-05-12T22:55:00.000Z",
"role": "owner",
"joinedAt": "2026-05-12T22:55:00.000Z",
"isActive": true,
"isForjioInternal": false
}
}
There is no API path to delete the workspace you just created. If you don't want it, the typical flow is to leave it sitting empty — or migrate ownership to another user and have them leave it as well.
Rename a workspace
PATCH /v1/account/workspaces/:id
Changes the display name. The slug is not regenerated — it stays the original auto-derived value so that URLs and references don't break.
Request body
| Field | Type | Description |
|---|---|---|
name |
string (1–120) | New display name. |
Only owner and admin can rename. member returns 403 FORBIDDEN.
Switch the active workspace
POST /v1/account/workspaces/:id/switch
Sets the calling session's activeAccountId. Subsequent requests scoped to "the active workspace" (OIDC clients, identity providers, IAM, audit, etc.) will resolve to this workspace.
Response — 200 OK
{ "data": { "activeAccountId": "acc_01KPG31…" } }
404 NOT_A_MEMBER if the calling user isn't a member of the requested workspace — Huudis does not surface the existence of workspaces you don't belong to.
The workspace object
| Field | Type | Description |
|---|---|---|
id |
string (acc_…) |
Stable workspace ID. Used everywhere as accountId. |
name |
string | Display name. |
slug |
string | URL-safe variant of name at creation time. Stable thereafter. |
createdAt |
ISO 8601 | Creation timestamp. |
role |
owner | admin | member |
The calling user's role in this workspace. |
joinedAt |
ISO 8601 | When the calling user joined. |
isActive |
boolean | Whether the calling session currently has this workspace selected. |
isForjioInternal |
boolean | Huudis-operational workspace (only relevant to Forjio staff). |
Why "account" and "workspace" are the same thing
When Huudis was extracted from Storlaunch, the database model used Account. Product copy at the time used "workspace" because that was the metaphor users understood. The API and database kept account (and the acc_… prefix on every ID); the UI, docs, and SDKs use workspace. The fields on the wire say accountId because changing it would break every existing integration — treat the two terms as identical in your head.
The CLI mirrors this: huudis workspaces list and huudis account workspaces list are aliases of the same command.
Multi-workspace patterns
A single human typically wants one personal workspace and one per company they administrate. Three patterns come up:
- One workspace, many members. The simplest setup. All admins of a team share one workspace and one billing line.
- Workspace per environment. Some teams keep staging and production fully separate to avoid accidentally administering the wrong environment. Two workspaces; the same admin user is a member of both and switches.
- Workspace per client (for agencies). Each client is a workspace; the agency admin is added as
admin(notowner) so the client retains ultimate control.
Switching between them at runtime is the POST .../switch endpoint above. The CLI's huudis workspaces switch and the dashboard's workspace-picker dropdown both call the same endpoint.
Service opt-in
Each workspace carries an enabledServices array that gates which first-party Forjio products (Plugipay, Storlaunch, Fulkruma, etc.) the workspace appears in. Manage via Services. Huudis itself is always enabled and can't be removed.
Events
| Event type | Fires on |
|---|---|
huudis.account.created.v1 |
POST /v1/account/workspaces succeeds. |
huudis.account.member_added.v1 |
A user joins (covered on Users). |
huudis.account.service_enabled.v1 |
A workspace opts into a new Forjio service. |
Workspace rename and switch do not emit events — they're considered config noise. The audit log carries them under account.profile_updated and account.workspace_switched.
Next
- Users — members of a workspace.
- Services — the per-workspace product opt-in list.
- OIDC clients — what gets registered inside a workspace.
- Billing — per-workspace plan and usage.