Skip to content
Select themeSelect language

PATCH /workspaces/{id}/settings — update workspace settings (admin only). Carries the ADR 0045 onboarding-safe flag (graduating a workspace flips `onboarding_mode` to `false` and unlocks autonomous dispatch) and the backlog QUIET-HOURS window (Stage 1). All fields optional; see [`PatchWorkspaceSettingsRequest`]. Requires workspace admin (`ManageMembers`).

PATCH
/api/workspaces/{id}/settings
curl --request PATCH \
--url https://example.com/api/workspaces/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/settings \
--header 'Content-Type: application/json' \
--cookie supacloud_session=<supacloud_session> \
--data '{ "allow_debug": true, "autonomy_level": 1, "autonomy_overrides": "example", "closeout_config": "example", "digest_cadence": "example", "digest_enabled": true, "environment_scope_floor": "example", "memory_governance": { "personal": { "auto_publish": true, "require_review": true, "retention_days": 1 }, "project": { "auto_publish": true, "require_review": true, "retention_days": 1 }, "workspace": { "auto_publish": true, "require_review": true, "retention_days": 1 } }, "onboarding_mode": true, "quiet_hours_end": "example", "quiet_hours_start": "example", "required_worker_group_ids": [ "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" ], "system_llm_credential": { "id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "kind": "example" } }'
id
required
string format: uuid

Workspace ID whose settings to patch

Media typeapplication/json

PATCH body for workspace settings (ADR 0045 Stage 1). All fields optional: onboarding_mode graduates/re-arms the onboarding guard; the quiet-hours pair configures (both set), clears (both null) or leaves unchanged (absent) the backlog dispatch QUIET-HOURS window. Times are HH:MM, interpreted UTC.

object
allow_debug

#583 Item 2 / #582 — the Debug-light CEILING (allow_debug). Absent = no change; a value SETS the ceiling. Workspace-admin only (the handler already gates PATCH on WorkspaceAction::ManageMembers). true lets members opt their own live/follow session into debug; false (re-)closes the ceiling.

boolean | null
autonomy_level

ADR 0045 Stage 4 — the workspace base autonomy level (0..=100). Absent = no change; null = clear back to the DEFAULT level; a value SETS the level (clamped to the plan ceiling before persist). DOUBLE-Option so the slider patch is distinguishable from an unrelated (onboarding/quiet-hours) patch.

integer | null format: int32
autonomy_overrides

ADR 0045 Stage 4 — the Advanced per-axis override vector. Absent leaves the stored overrides unchanged; a value replaces them ({} clears them). Only applied when the autonomy fields are touched.

closeout_config

#712 — the workspace-tier standard-closeout config ({memory, project_docs, user_docs, wiki}, mig 283). Absent leaves the stored default unchanged; a value REPLACES the workspace default (shape-validated — a malformed bag is a 400). It is the DEFAULT every project inherits per step. Workspace-admin only (the handler gates PATCH on WorkspaceAction::ManageMembers).

digest_cadence

#519 #11 — the digest cadence (off | daily | weekly). Absent leaves it unchanged. An invalid value is a 400.

string | null
digest_enabled

#519 #11 — whether the autonomous-delivery notification digest is delivered. Absent leaves it unchanged. Applied together with digest_cadence (the pair is persisted whenever EITHER is present).

boolean | null
environment_scope_floor

#708 W8 — the workspace environment-scope FLOOR (all | production | staging | development, mig 290). Absent = no change; null = clear (no floor); a value MANDATES that no autonomous run acts outside that environment class (the blast radius is narrowed to it). An invalid value is a 400. Workspace-admin only.

string | null
memory_governance
One of:
null
onboarding_mode

Onboarding-safe flag. false graduates the workspace (autonomous backlog dispatch + uncapped autonomy); absent leaves it unchanged.

boolean | null
quiet_hours_end

Quiet-window end (HH:MM, UTC). Absent = no change; null = clear.

string | null
quiet_hours_start

Quiet-window start (HH:MM, UTC). Absent = no change; null = clear.

string | null
required_worker_group_ids

ADR 0046 RUNG 1b — the workspace worker-group FLOOR binding (the always-unioned isolation primitive). Absent = no change; a value (incl. []) REPLACES the floor. Persisted only when present, so an unrelated settings patch never clears it. Workspace admin.

Array<string> | null
system_llm_credential
One of:
null
Examplegenerated
{
"allow_debug": true,
"autonomy_level": 1,
"autonomy_overrides": "example",
"closeout_config": "example",
"digest_cadence": "example",
"digest_enabled": true,
"environment_scope_floor": "example",
"memory_governance": {
"personal": {
"auto_publish": true,
"require_review": true,
"retention_days": 1
},
"project": {
"auto_publish": true,
"require_review": true,
"retention_days": 1
},
"workspace": {
"auto_publish": true,
"require_review": true,
"retention_days": 1
}
},
"onboarding_mode": true,
"quiet_hours_end": "example",
"quiet_hours_start": "example",
"required_worker_group_ids": [
"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"
],
"system_llm_credential": {
"id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"kind": "example"
}
}

Settings patched; the echo round-trips the persisted values

Media typeapplication/json

The 200 body of PATCH /api/workspaces/{id}/settings — the typed echo apply_settings_patch builds and returns. ok plus the request-echoed onboarding / quiet-hours fields are ALWAYS present (the quiet-hours pair echoes the request, so it is null when absent/cleared); every remaining block is Some(..) ONLY when the patch touched it and skip_serializing_if omits the key otherwise — so the wire shape carries exactly the fields the patch changed.

object
allow_debug

#583 Item 2 / #582 — echoed Debug-light CEILING — present ONLY when the patch touched it.

boolean | null
autonomy_level

Persisted autonomy level (0..=100, clamped to the plan ceiling) — present ONLY when the patch touched the autonomy fields.

integer | null format: int32
autonomy_overrides

Persisted per-axis override vector — present ONLY when the patch touched the autonomy fields.

closeout_config

#712 — echoed workspace-tier standard-closeout config — present ONLY when the patch touched it (round-trips the persisted/validated config).

digest_cadence

Persisted digest cadence (off | daily | weekly) — present ONLY when the patch touched the digest config.

string | null
digest_enabled

Persisted digest-enabled flag — present ONLY when the patch touched the digest config.

boolean | null
environment_scope_floor

#708 W8 — echoed environment-scope FLOOR — present ONLY when the patch touched it. Some(Some(scope)) = the mandated floor; Some(None) = cleared (no floor).

string | null
memory_governance
One of:
null
ok
required

Always true on a successful patch.

boolean
onboarding_mode

Echoed onboarding-safe flag (the request value; null when the field was absent from the request).

boolean | null
quiet_hours_end

Echoed quiet-window end (HH:MM, UTC); null when absent/cleared.

string | null
quiet_hours_start

Echoed quiet-window start (HH:MM, UTC); null when absent/cleared.

string | null
system_llm_credential
One of:
null
Examplegenerated
{
"allow_debug": true,
"autonomy_level": 1,
"autonomy_overrides": "example",
"closeout_config": "example",
"digest_cadence": "example",
"digest_enabled": true,
"environment_scope_floor": "example",
"memory_governance": {
"personal": {
"auto_publish": true,
"require_review": true,
"retention_days": 1
},
"project": {
"auto_publish": true,
"require_review": true,
"retention_days": 1
},
"workspace": {
"auto_publish": true,
"require_review": true,
"retention_days": 1
}
},
"ok": true,
"onboarding_mode": true,
"quiet_hours_end": "example",
"quiet_hours_start": "example",
"system_llm_credential": {
"id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"kind": "example"
}
}

Structured client error

Media typeapplication/json

The canonical JSON body of every error response — the single source of truth the frontend binds to. Every AppError serializes as this exact shape, and the generated OpenAPI component ApiErrorBody (with its ErrorCode enum) is what the frontend error schema is generated from, so there is no hand-written error schema on either end.

object
code
required

Machine-readable, stable error code.

string
Allowed values: not_found unauthorized forbidden bad_request unprocessable precondition_failed conflict method_not_allowed rate_limited quota_exceeded database_error docker_error vault_error internal_error
details
One of:
null
error
required

Human-readable message (the server’s English text; the client may localize by code).

string
Example
{
"code": "not_found"
}

Authentication required

Media typeapplication/json

The canonical JSON body of every error response — the single source of truth the frontend binds to. Every AppError serializes as this exact shape, and the generated OpenAPI component ApiErrorBody (with its ErrorCode enum) is what the frontend error schema is generated from, so there is no hand-written error schema on either end.

object
code
required

Machine-readable, stable error code.

string
Allowed values: not_found unauthorized forbidden bad_request unprocessable precondition_failed conflict method_not_allowed rate_limited quota_exceeded database_error docker_error vault_error internal_error
details
One of:
null
error
required

Human-readable message (the server’s English text; the client may localize by code).

string
Example
{
"code": "not_found"
}

Permission denied

Media typeapplication/json

The canonical JSON body of every error response — the single source of truth the frontend binds to. Every AppError serializes as this exact shape, and the generated OpenAPI component ApiErrorBody (with its ErrorCode enum) is what the frontend error schema is generated from, so there is no hand-written error schema on either end.

object
code
required

Machine-readable, stable error code.

string
Allowed values: not_found unauthorized forbidden bad_request unprocessable precondition_failed conflict method_not_allowed rate_limited quota_exceeded database_error docker_error vault_error internal_error
details
One of:
null
error
required

Human-readable message (the server’s English text; the client may localize by code).

string
Example
{
"code": "not_found"
}

Structured server error

Media typeapplication/json

The canonical JSON body of every error response — the single source of truth the frontend binds to. Every AppError serializes as this exact shape, and the generated OpenAPI component ApiErrorBody (with its ErrorCode enum) is what the frontend error schema is generated from, so there is no hand-written error schema on either end.

object
code
required

Machine-readable, stable error code.

string
Allowed values: not_found unauthorized forbidden bad_request unprocessable precondition_failed conflict method_not_allowed rate_limited quota_exceeded database_error docker_error vault_error internal_error
details
One of:
null
error
required

Human-readable message (the server’s English text; the client may localize by code).

string
Example
{
"code": "not_found"
}