You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Bootstrap API returns everything a client needs to initialize: the authenticated user's identity, their workspaces, and the active workspace's shell configuration. The web UI calls this on page load.
9
9
10
+
Bootstrap is the discovery endpoint — the one place the server picks a default workspace for the caller. Data endpoints (`/mcp`, `/v1/chat`, `/v1/tools/call`, `/v1/shell`, `/v1/events`) treat `X-Workspace-Id` as authoritative and reject requests that omit it. Same header name, different strictness by endpoint class.
11
+
10
12
## GET /v1/bootstrap
11
13
12
14
Returns the current user, their workspaces with roles, and the shell configuration for the active workspace.
13
15
16
+
**Request headers:**
17
+
18
+
| Header | Required | Description |
19
+
|---|---|---|
20
+
|`Authorization`| Yes |`Bearer <token>` — see [Authentication](/api/authentication)|
21
+
|`X-Workspace-Id`| No |**Soft hint.** If present and the user is a member of this workspace, it becomes `activeWorkspace` in the response. Otherwise ignored and the first membership is returned. Clients use this to restore a user's last-selected workspace from local storage. |
22
+
14
23
**Response:**
15
24
16
25
```json
@@ -50,15 +59,16 @@ Returns the current user, their workspaces with roles, and the shell configurati
50
59
|-------|------|-------------|
51
60
|`user`|`object`| Authenticated user identity (id, name, email, role) |
52
61
|`workspaces`|`array`| Workspaces the user belongs to, with their role in each |
53
-
|`activeWorkspace`|`string`| ID of the currently active workspace |
62
+
|`activeWorkspace`|`string`| ID of the currently active workspace. Always populated — the server enforces the invariant that every authenticated user has at least one workspace (provisioned at login, re-created on next login if externally deleted).|
| 500 |`workspace_invariant_violation`| Authenticated user reached bootstrap with zero workspaces. Provisioning should have run at login; this indicates a broken identity-layer path rather than client misuse. |
Copy file name to clipboardExpand all lines: src/content/docs/api/mcp-endpoint.mdx
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -76,7 +76,7 @@ Every MCP request is scoped to a workspace. External clients identify the worksp
76
76
77
77
Workspace IDs have the form `ws_<alphanumeric>` and can be copied from **Settings → Profile → MCP Connection** in the web UI.
78
78
79
-
If the user belongs to multiple workspaces and no header is set, the server returns `400` with the message "Multiple workspaces available. Set X-Workspace-Id header to specify which workspace to use." Set the header on every client config — it removes ambiguity if the user is later added to more workspaces.
79
+
If the header is missing, the server returns `400` with the message "Workspace required. Set the X-Workspace-Id header. The workspace ID is available from GET /v1/bootstrap or Settings → Profile → MCP Connection." — regardless of how many workspaces the user belongs to. The server does not pick a default on data endpoints.
Copy file name to clipboardExpand all lines: src/content/docs/apps/placements.mdx
+18-12Lines changed: 18 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -135,22 +135,28 @@ The `size` field provides a hint to the slot renderer:
135
135
136
136
The `PlacementRegistry` is an in-memory store that tracks all active placements. It is updated when bundles are installed or uninstalled.
137
137
138
-
**Registration**— When a bundle starts, its placements are registered. If the bundle has explicit `placements`, they are used directly. If it only has `primaryView`, `registerLegacy()` converts it to a single `"main"` placement.
138
+
Every entry is either **ambient**(no `wsId` — platform-provided views like Home, Conversations, Files, Settings; always present inside any workspace) or **workspace-scoped** (installed bundles, visible only to members of that workspace). The registry exposes a single read method, `forWorkspace(wsId)`, which returns ambient + scoped entries merged and sorted. There is deliberately no "return everything" accessor — in a multi-tenant host, no legitimate caller wants placements unrelated to a workspace.
139
139
140
-
**Querying** — `forSlot(slot)` returns all entries matching the slot (including sub-slots), sorted by priority ascending.
140
+
**Registration** — When a bundle starts, its placements are registered against the installing workspace's `wsId`. If the bundle has explicit `placements`, they are used directly. If it only has `primaryView`, `registerLegacy()` converts it to a single `"main"` placement.
141
141
142
-
**Unregistration** — When a bundle is uninstalled, all its placements are removed.
142
+
**Querying** — `forWorkspace(wsId)` returns ambient entries plus entries scoped to `wsId`, sorted by slot then priority (lower first).
143
+
144
+
**Unregistration** — When a bundle is uninstalled, its placements for that workspace are removed. Other workspaces' entries for the same bundle are untouched.
Copy file name to clipboardExpand all lines: src/content/docs/using/workspaces.mdx
+6-2Lines changed: 6 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -91,11 +91,15 @@ The agent installs the bundle and registers its tools in the workspace's tool re
91
91
92
92
## Switching workspaces
93
93
94
-
In the web UI, switch workspaces from the workspace selector in the sidebar. The API uses the `X-Workspace-Id` header or the `workspaceId` field in chat requests to target a specific workspace.
94
+
In the web UI, switch workspaces from the workspace selector in the sidebar. Every API request to a workspace-scoped endpoint (`/mcp`, `/v1/chat`, `/v1/tools/call`, `/v1/shell`, `/v1/events`) must include an `X-Workspace-Id` header. Chat requests continuing an existing conversation inherit the workspace from `conversationId` — no alternative addressing scheme.
95
+
96
+
<Asidetype="note">
97
+
NimbleBrain guarantees every authenticated user has at least one workspace. One is provisioned on first login and re-created on the next login if manually deleted. Client code can rely on this invariant — `activeWorkspace` from `/v1/bootstrap` is always a valid workspace ID.
98
+
</Aside>
95
99
96
100
## Bootstrap
97
101
98
-
When the web UI loads, it calls `GET /v1/bootstrap`to get the current user's identity, workspace list with roles, and the active workspace's configuration. This single call provides everything needed to render the shell.
102
+
Clients that don't yet know a workspace ID call `GET /v1/bootstrap`— the one endpoint where the server picks a default. It returns the authenticated user's identity, the full workspace list with roles, and the active workspace's shell configuration. Clients may send `X-Workspace-Id` on bootstrap as a soft hint (e.g., restoring a user's last selection from local storage); the server honors it when it matches a membership and falls back to the first workspace otherwise.
0 commit comments