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

# Workspaces

> Create and manage workspaces, their members, and their budget

A workspace groups providers, models, prompts, mappings, configs, and indexes. Reads need
`workspaces:read` and writes need `workspaces:write`. Member and budget actions have their
own scopes and roles, noted below.

## List workspaces

```
GET /api/v1/workspaces
```

Each row carries `my_role` and a `stats` summary.

<RequestExample>
  ```bash cURL theme={null}
  curl 'https://platform.nemu.cc/api/v1/workspaces' \
    -H 'Authorization: Bearer <access_token>'
  ```

  ```ts SDK theme={null}
  const workspaces = await nemu.workspaces.list();
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "data": [
      {
        "id": "ws_1",
        "name": "prod",
        "owner_id": "3f0e...",
        "my_role": "OWNER",
        "stats": {
          "member_count": 3,
          "prompt_count": 12,
          "config_count": 2,
          "mapping_count": 4,
          "provider_count": 2
        },
        "created_at": "2026-01-04T10:22:00.000Z",
        "updated_at": "2026-02-01T09:00:00.000Z"
      }
    ],
    "total": 1
  }
  ```
</ResponseExample>

## Get a workspace

```
GET /api/v1/workspaces/{id}
```

## Create a workspace

```
POST /api/v1/workspaces
```

<ParamField body="name" type="string" required>
  A name for the workspace, from 1 to 128 characters.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST 'https://platform.nemu.cc/api/v1/workspaces' \
    -H 'Authorization: Bearer <access_token>' \
    -H 'Content-Type: application/json' \
    -d '{"name": "prod"}'
  ```

  ```ts SDK theme={null}
  const workspace = await nemu.workspaces.create({ name: "prod" });
  ```
</RequestExample>

## Update a workspace

```
PATCH /api/v1/workspaces/{id}
```

<ParamField body="name" type="string">
  A new name for the workspace.
</ParamField>

```ts SDK theme={null}
await workspace.update({ name: "production" });
```

## Delete a workspace

```
DELETE /api/v1/workspaces/{id}
```

Only the owner can delete a workspace.

```ts SDK theme={null}
await workspace.delete();
```

## Members

Reads need `members:read` and writes need `members:write`.

### List members

```
GET /api/v1/workspaces/{id}/members
```

<ResponseExample>
  ```json 200 theme={null}
  {
    "data": [
      {
        "id": "mem_1",
        "workspace_id": "ws_1",
        "user_id": "3f0e...",
        "role": "OWNER",
        "created_at": "2026-01-04T10:22:00.000Z",
        "user": {
          "id": "3f0e...",
          "username": "user",
          "email": "user@example.com"
        }
      }
    ]
  }
  ```
</ResponseExample>

### Invite a member

```
POST /api/v1/workspaces/{id}/members
```

Creates an invitation and returns a shareable link.

<ParamField body="restricted_to" type="string[]">
  Limit the invite to specific email addresses.
</ParamField>

<ParamField body="max_uses" type="integer">
  How many times the invite can be redeemed.
</ParamField>

<ParamField body="expires_in_days" type="integer">
  How many days the invite stays valid.
</ParamField>

<ResponseExample>
  ```json 200 theme={null}
  {
    "data": {
      "id": "inv_1",
      "code": "abc123",
      "link": "https://platform.nemu.cc/invite/abc123",
      "expires_at": "2026-02-10T00:00:00.000Z",
      "max_uses": 5
    }
  }
  ```
</ResponseExample>

### Update a member role

```
PATCH /api/v1/workspaces/{id}/members/{member_id}
```

<ParamField body="role" type="string" required>
  `ADMIN` or `MEMBER`.
</ParamField>

### Remove a member

```
DELETE /api/v1/workspaces/{id}/members/{member_id}
```

## Budget

The monthly spend cap for a workspace. Reading needs workspace membership. Updating needs an
administrator role on the workspace.

### Get the budget

```
GET /api/v1/workspaces/{id}/budget
```

<ResponseExample>
  ```json 200 theme={null}
  {
    "budget": 100,
    "current_spend": 42.5,
    "remaining": 57.5
  }
  ```
</ResponseExample>

### Update the budget

```
PATCH /api/v1/workspaces/{id}/budget
```

<ParamField body="budget" type="number" required>
  The monthly cap, from 0 to 1000000.
</ParamField>

<ResponseExample>
  ```json 200 theme={null}
  {
    "success": true,
    "budget": 250
  }
  ```
</ResponseExample>

## Gateway token

Mints a short lived gateway key so a workspace can send inference through the gateway. This
endpoint authenticates with your app credentials rather than a bearer token, so reach for
the SDK, which handles it for you.

```
POST /api/v1/workspaces/{id}/gate-token
```

```ts SDK theme={null}
const key = await workspace.gateway_key();
```

<ResponseExample>
  ```json 200 theme={null}
  {
    "gate_key": "eyJhbGciOi..."
  }
  ```
</ResponseExample>
