Workspaces
Organize API keys and usage into named containers within one account.
A workspace is a named container that groups API keys and usage inside a single account, similar to a project or an environment. Every account starts with a Default Workspace, and keyless activity rolls up to it. An account can hold up to 10 workspaces.
Workspaces are managed with a session from the dashboard.
Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET | /v1/workspaces | List workspaces |
POST | /v1/workspaces | Create a workspace |
PATCH | /v1/workspaces/:id | Rename or edit a workspace |
DELETE | /v1/workspaces/:id | Delete a workspace and revoke its keys |
A workspace looks like:
{
"id": "ws_...",
"name": "Production",
"slug": "production",
"description": "Live traffic keys",
"is_default": false,
"created_at": "2026-07-30T12:00:00.000Z"
}Slugs are lowercase alphanumeric with hyphens and must be unique within the account. The Default Workspace cannot be deleted.
Scoping keys and usage
- Create an inference key inside a workspace by passing
workspace_idwhen you create it. See authentication. - Filter usage to one workspace with
GET /v1/usage?workspace_id=<id>.
Deleting a workspace revokes the API keys that belong to it, so move or recreate any keys you still need first.
Routing and privacy defaults
Privacy boundary
The privacy boundary is the weakest privacy tier any request made with the workspace's keys may use. Set it on the Privacy page:
| Boundary | privacy_boundary | Tiers a request may use |
|---|---|---|
| Standard (default) | null | Anonymous, Private, TEE, E2EE |
| Private | balanced | Private, TEE, E2EE |
| Maximum | maximum | TEE, E2EE |
The boundary applies to every request from every key in the workspace and to
the browser chat, which uses your Default Workspace. That covers chat with a
named model, /auto, embeddings, images, speech, and
compatibility mode. A request can ask for a stricter tier, but
it cannot go below the boundary: not with routing.privacy_classes, not with
provider.minimum_privacy, and not by naming a model. Failover never goes
below it either.
If no route of the requested model meets the boundary, the request is refused
with 403 privacy_boundary_not_met before any provider sees it. The message
names the boundary, never your prompt:
This workspace's privacy boundary (Private) does not allow this model's privacy tier. A workspace owner can change the boundary on the Privacy page.The boundary is separate from the /auto privacy level on the Routing
page, which only affects /auto and which a request can replace. When the
boundary is stricter, /auto uses the boundary.
GET /v1/routing/preferences returns the boundary as privacy_boundary
(null for Standard). PUT accepts it; leaving it out keeps the stored value.
Provider defaults
Each workspace has its own provider routing defaults, which apply to every request made with that workspace's API keys. In the dashboard:
- The Privacy page holds the privacy boundary and, under Provider fallback, whether fallback to another provider is allowed, how many times it may retry on another provider (up to 1 or up to 2), and how far a fallback may step down.
- The Routing page holds the Auto router (how
/autopicks a model, including its own privacy level), the default provider sort, and the providers that are disabled for the workspace.
With a session, read and replace them through
GET and PUT /v1/routing/preferences?workspace_id=<id>. Without
workspace_id the call applies to the Default Workspace.
Workspace defaults merge restrictively with each request's provider field: a
request can make routing stricter, for example by ignoring another provider or
turning fallback off, but it can never lower the workspace's privacy floor or
allow more providers than the workspace does. See
provider routing and failover.
Or hand the whole thing to your agent
One prompt carries the entire setup. Give it to your agent, review what it configures, and you are done.