> ## Documentation Index
> Fetch the complete documentation index at: https://noradocs.solomontsao.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Workspaces

# Workspaces API: group and organize agents

> Create workspaces to group Nora agents by project or team, assign agent roles, list workspace members, and delete workspaces you own.

Workspaces let you organise agents into logical groups — for example by project, team, or environment. You create a workspace, invite teammates, add agents you own, and query which agents belong to a given workspace. Workspace roles control team access: viewers can read, editors can operate assigned agents, and admins or owners can manage assignments.

***

## List workspaces

Return all workspaces where the authenticated user is a member.

```
GET /workspaces
```

### Response

<ResponseField name="id" type="string">
  Workspace UUID.
</ResponseField>

<ResponseField name="name" type="string">
  Workspace display name.
</ResponseField>

<ResponseField name="user_id" type="string">
  UUID of the owning user.
</ResponseField>

<ResponseField name="created_at" type="string">
  ISO 8601 creation timestamp.
</ResponseField>

<ResponseField name="role" type="string">
  Caller role in the workspace.
</ResponseField>

<ResponseField name="agent_count" type="number">
  Number of assigned agents.
</ResponseField>

<ResponseField name="member_count" type="number">
  Number of workspace members.
</ResponseField>

<CodeGroup>
  ```bash curl theme={null} theme={null}
  curl http://localhost:8080/api/workspaces \
    -H "Authorization: Bearer $TOKEN"
  ```
</CodeGroup>

```json theme={null} theme={null}
[
  {
    "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
    "name": "Production",
    "user_id": "d4e5f6a7-b8c9-4d01-a234-56789bcdef01",
    "created_at": "2025-02-15T14:00:00.000Z",
    "role": "owner",
    "agent_count": 3,
    "member_count": 4
  }
]
```

***

## Create a workspace

Create a new workspace.

```
POST /workspaces
```

### Request body

<ParamField body="name" type="string" required>
  Workspace name, 1–100 characters.
</ParamField>

### Response

<ResponseField name="id" type="string">
  New workspace UUID.
</ResponseField>

<ResponseField name="name" type="string">
  Workspace name.
</ResponseField>

<ResponseField name="user_id" type="string">
  UUID of the owning user.
</ResponseField>

<ResponseField name="created_at" type="string">
  ISO 8601 creation timestamp.
</ResponseField>

<CodeGroup>
  ```bash curl theme={null} theme={null}
  curl -X POST http://localhost:8080/api/workspaces \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"name":"Production"}'
  ```
</CodeGroup>

```json theme={null} theme={null}
{
  "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "name": "Production",
  "user_id": "d4e5f6a7-b8c9-4d01-a234-56789bcdef01",
  "created_at": "2025-03-10T09:00:00.000Z"
}
```

| Status | Condition                                    |
| ------ | -------------------------------------------- |
| `400`  | Missing name, or name exceeds 100 characters |

***

## List agents in a workspace

Return all agents that have been added to a specific workspace. Requires `viewer` or higher.

```
GET /workspaces/:id/agents
```

### Path parameters

<ParamField path="id" type="string" required>
  Workspace UUID.
</ParamField>

### Response

Returns an array of agent records joined with their workspace assignment details.

<ResponseField name="agentId" type="string">
  Agent UUID.
</ResponseField>

<ResponseField name="agentName" type="string">
  Agent display name.
</ResponseField>

<ResponseField name="agentStatus" type="string">
  Current agent status.
</ResponseField>

<ResponseField name="role" type="string">
  Role assigned to this agent in the workspace, if any.
</ResponseField>

<ResponseField name="isDirectOwner" type="boolean">
  Whether the caller owns the agent directly.
</ResponseField>

<CodeGroup>
  ```bash curl theme={null} theme={null}
  curl http://localhost:8080/api/workspaces/b2c3d4e5-f6a7-8901-bcde-f12345678901/agents \
    -H "Authorization: Bearer $TOKEN"
  ```
</CodeGroup>

```json theme={null} theme={null}
[
  {
    "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "agentName": "My Research Agent",
    "agentStatus": "running",
    "role": "member",
    "isDirectOwner": true
  }
]
```

***

## Add an agent to a workspace

Associate one of your directly owned agents with a workspace. Requires `editor` or higher.

```
POST /workspaces/:id/agents
```

### Path parameters

<ParamField path="id" type="string" required>
  Workspace UUID.
</ParamField>

### Request body

<ParamField body="agentId" type="string" required>
  UUID of the agent to add. Must be directly owned by the caller.
</ParamField>

<ParamField body="role" type="string">
  Optional assignment label for this agent within the workspace. Defaults to `member`.
</ParamField>

### Response

Returns the workspace membership record.

<ResponseField name="workspace_id" type="string">
  Workspace UUID.
</ResponseField>

<ResponseField name="agent_id" type="string">
  Agent UUID.
</ResponseField>

<ResponseField name="role" type="string">
  Assigned role, or `null`.
</ResponseField>

<CodeGroup>
  ```bash curl theme={null} theme={null}
  curl -X POST http://localhost:8080/api/workspaces/b2c3d4e5-f6a7-8901-bcde-f12345678901/agents \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"agentId":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","role":"primary"}'
  ```
</CodeGroup>

```json theme={null} theme={null}
{
  "workspace_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "agent_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "role": "primary"
}
```

| Status | Condition                                 |
| ------ | ----------------------------------------- |
| `400`  | Missing `agentId`                         |
| `404`  | Agent not found or does not belong to you |

***

## List assignment candidates

Return directly owned agents with an `assigned` flag for the target workspace. Requires `editor` or higher.

```
GET /workspaces/:id/agent-candidates
```

```json theme={null} theme={null}
[
  {
    "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "name": "My Research Agent",
    "status": "running",
    "assigned": true
  }
]
```

***

## Remove an agent assignment

Remove an agent from a workspace without deleting the agent runtime or record. Requires `admin` or `owner`.

```
DELETE /workspaces/:id/agents/:agentId
```

```json theme={null} theme={null}
{ "success": true }
```

***

## Cost dashboard

Return workspace token-cost groups, per-agent token usage rows, unassigned owned agents, and a unique fleet total that avoids double-counting agents assigned to multiple workspaces. Cost rows include token usage grouped by model.

<Note>
  Session users receive every workspace they can access plus their unassigned owned agents. A
  workspace API key with `workspaces:read` receives the same response envelope, but it contains only
  the key's exact bound workspace and an empty `unassigned` group.
</Note>

```
GET /workspaces/cost?period_days=30
```

Use `period_start` and `period_end` for a custom UTC date window:

```
GET /workspaces/cost?period_start=2026-05-01&period_end=2026-05-21
```

```json theme={null} theme={null}
{
  "periodDays": 30,
  "workspaceTotalUsd": 42.1,
  "uniqueFleetTotalUsd": 31.55,
  "workspaces": [
    {
      "workspaceId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "workspaceName": "Production",
      "totalUsd": 31.55,
      "perAgent": [
        {
          "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
          "agentName": "My Research Agent",
          "token_cost": 7.64,
          "total_cost": 7.64,
          "input_tokens": 120000,
          "output_tokens": 42000,
          "total_tokens": 162000,
          "cost_details": {
            "tokens": {
              "models": [
                {
                  "model": "openai/gpt-5.5",
                  "provider": "openai",
                  "input_tokens": 120000,
                  "output_tokens": 42000,
                  "total_tokens": 162000,
                  "rate_source": "model",
                  "token_cost": 7.64
                }
              ]
            }
          }
        }
      ]
    }
  ],
  "unassigned": {
    "totalUsd": 0,
    "perAgent": []
  }
}
```

***

## Delete a workspace

Permanently delete a workspace. All agent memberships within the workspace are removed. The agents themselves are not affected.

```
DELETE /workspaces/:id
```

### Path parameters

<ParamField path="id" type="string" required>
  Workspace UUID.
</ParamField>

### Response

<ResponseField name="success" type="boolean">
  `true` when the workspace was deleted.
</ResponseField>

<CodeGroup>
  ```bash curl theme={null} theme={null}
  curl -X DELETE http://localhost:8080/api/workspaces/b2c3d4e5-f6a7-8901-bcde-f12345678901 \
    -H "Authorization: Bearer $TOKEN"
  ```
</CodeGroup>

```json theme={null} theme={null}
{ "success": true }
```

<Warning>
  Deleting a workspace is irreversible. All agent memberships are removed immediately. The agents
  themselves continue to run and remain accessible through the Agents API.
</Warning>
