---
title: "Workspace preferences API"
description: "Read and update Alpacon workspace preferences through the API. Learn the agent rollout policy, its maintenance window, and the deprecated auto upgrade flag."
---

> Full documentation index: https://docs.alpacax.com/llms.txt

# Workspace preferences

**Endpoint**: `/api/workspaces/preferences/`

Read and update the workspace-wide preferences shown under **Workspace settings** → **General**, including the [agent update policy](/use/workspace/settings/agent-updates/). There is one preferences object per workspace.

  On Alpacon Cloud, this endpoint takes a signed-in session: the web console, or an OAuth client such as the [Alpacon MCP server](/reference/mcp/tools/workspace-settings/#preferences). An API token is refused with `401`. On a self-hosted deployment, an API token with the [`preferences`](/reference/scopes/#preferences) scope works.

  
    ## Get preferences

    Any member of the workspace can read the preferences.

    ### Request

    ```http
    GET /api/workspaces/preferences/-/
    ```

    ### Response

    ```json
    {
      "front_url": "https://your-workspace.us1.alpacon.io",
      "country": "US",
      "language": "en",
      "timezone": "America/New_York",
      "invite_ttl": 172800,
      "enabled_extensions": ["metrics"],
      "websh_session_timeout": 86400,
      "agent_rollout_policy": {
        "mode": "latest",
        "window": {
          "days": [0, 1, 2, 3, 4],
          "start_hour": 2,
          "length_hours": 4,
          "timezone": "America/New_York"
        }
      },
      "auto_agent_upgrade": true,
      "package_proxy": null,
      "billing_email": "billing@example.com"
    }
    ```

    | Field | Type | Description |
    |-------|------|-------------|
    | `front_url` | string | The workspace's console URL |
    | `country`, `language` | string | Workspace country and default display language |
    | `timezone` | string | Workspace default timezone |
    | `invite_ttl` | integer | How long invitation links stay valid, in seconds |
    | `enabled_extensions` | array | Enabled [extensions](/use/workspace/settings/extensions/) |
    | `websh_session_timeout` | integer | Websh session time limit, in seconds |
    | `agent_rollout_policy` | object | The [agent rollout policy](#agent-rollout-policy) |
    | `auto_agent_upgrade` | boolean | **Deprecated.** See [`auto_agent_upgrade`](#auto_agent_upgrade-deprecated) |
    | `package_proxy` | string or `null` | Proxy server URL for package installation |
    | `billing_email` | string | Billing contact email. Alpacon Cloud only |
  </Tabs.Tab>

  <Tabs.Tab>
    ## Update preferences

    Update one or more preferences. Only Staff and Superuser members can update them, and only the fields you send change.

    ### Request

    ```http
    PATCH /api/workspaces/preferences/-/
    ```

    ### Request body

    ```json
    {
      "agent_rollout_policy": {
        "window": {
          "days": [5, 6],
          "start_hour": 22,
          "length_hours": 6,
          "timezone": "Asia/Seoul"
        }
      }
    }
    ```

    ### Response

    Returns the full preferences object (same schema as [Get preferences](#get-preferences)).
  </Tabs.Tab>
</Tabs>

## Agent rollout policy

`agent_rollout_policy` decides whether Alpacon upgrades agents in this workspace automatically, and in which hours:

```json
{
  "mode": "latest",
  "window": {
    "days": [0, 1, 2, 3, 4, 5, 6],
    "start_hour": 0,
    "length_hours": 24,
    "timezone": "UTC"
  }
}
```

| Field | Type | Description |
|-------|------|-------------|
| `mode` | string | `latest` upgrades agents to new releases inside the window. `n_minus_1` stays one release behind the newest; until verified upgrades are enabled, choosing it is refused with `preferences_agent_rollout_mode_unavailable`. `manual` runs no automatic upgrade: each server is upgraded with the [`upgrade_agent` action](/reference/api/servers/servers/#agent-actions) |
| `window.days` | array of integers | Days the window opens, `0` (Monday) to `6` (Sunday). At least one, no repeats |
| `window.start_hour` | integer | Hour the window opens, `0` to `23`, in `window.timezone` |
| `window.length_hours` | integer | How long the window stays open, `1` to `24`. It can run past midnight, and it's elapsed time, so a daylight-saving change inside the window doesn't stretch or shorten it |
| `window.timezone` | string | An IANA timezone name, such as `Asia/Seoul` or `America/New_York` |

The example above is the default: `latest`, with a window open every day for 24 hours, so upgrades can start at any time.

A write may name only part of the object—just `mode`, or just one `window` field—and whatever it leaves out keeps its current value. A read always returns the whole object.

Alpacon plans each week's automatic upgrades on Monday, inside the window. A change to the window takes effect from the next Monday's plan; upgrades already planned for hours that now fall outside it wait for the next open hour.

Every server's `agent_upgrade_policy` field in the [Servers API](/reference/api/servers/servers/#get-server) carries the current `mode`.

## `auto_agent_upgrade` (deprecated)

`auto_agent_upgrade` is the boolean that `agent_rollout_policy` replaced. It stays readable and writable for one more release, then it's removed. Use `agent_rollout_policy` instead.

- **Read**: `true` unless `mode` is `manual`.
- **Write `true`**: sets `mode` to `latest`, unless the mode is already automatic (`latest` or `n_minus_1`), in which case nothing changes.
- **Write `false`**: sets `mode` to `manual`.
- Neither write changes the window.
- When a request names both fields, `agent_rollout_policy` wins and `auto_agent_upgrade` is ignored.
- It accepts a JSON boolean only; any other value is refused with `invalid_input`.

These rules describe the REST API. For the MCP `update_workspace_preferences` tool, pass `agent_rollout_policy` directly; see [the MCP agent rollout policy reference](/reference/mcp/tools/workspace-settings/#agent-rollout-policy).

## Error responses

| Status | Error code | Description |
|--------|------------|-------------|
| 400 | `preferences_agent_rollout_policy_invalid` | `agent_rollout_policy` or its `window` isn't an object, or names a field that doesn't exist |
| 400 | `preferences_agent_rollout_mode_invalid` | `mode` isn't `latest`, `n_minus_1`, or `manual` |
| 400 | `preferences_agent_rollout_mode_unavailable` | `n_minus_1` can't be chosen until verified upgrades are enabled; choose `latest` or `manual` |
| 400 | `preferences_agent_rollout_window_days_invalid` | `days` is empty, repeats a day, or has a value outside `0`–`6` |
| 400 | `preferences_agent_rollout_window_start_hour_invalid` | `start_hour` isn't an integer from `0` to `23` |
| 400 | `preferences_agent_rollout_window_length_invalid` | `length_hours` isn't an integer from `1` to `24` |
| 400 | `preferences_agent_rollout_window_timezone_invalid` | `timezone` isn't an IANA timezone name |
| 400 | `preferences_timezone_invalid` | `timezone` isn't a valid IANA timezone name (for example `Asia/Seoul`) |
| 400 | `workspace_extension_requires_extension` | `enabled_extensions` turns on DNS or Proxy without IP, or turns IP off while DNS or Proxy stays on. Include `ip` in the same list |
| 401 | — | Invalid or missing authentication, including an API token on Alpacon Cloud. Uncoded `{"detail": "..."}` response |
| 403 | — | Only Staff and Superuser members can update preferences. Uncoded `{"detail": "..."}` response |

Source: https://docs.alpacax.com/reference/api/preferences/
