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`).
const url = 'https://example.com/api/workspaces/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/settings';const options = { method: 'PATCH', headers: { cookie: 'supacloud_session=<supacloud_session>', 'Content-Type': 'application/json' }, body: '{"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"}}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}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" } }'Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Workspace ID whose settings to patch
Request Bodyrequired
Section titled “Request Bodyrequired”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
#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.
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.
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.
#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).
#519 #11 — the digest cadence (off | daily | weekly). Absent leaves it
unchanged. An invalid value is a 400.
#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).
#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.
ADR 0049 P3 / Tier-3 (#547/#548) — the per-scope memory GOVERNANCE policy (auto-publish / require-review / retention-days, keyed by workspace|project|personal). Absent leaves the stored policy unchanged; a value REPLACES it (the panel always sends the full three-scope policy). Validated (no contradictory auto-publish + require-review; bounded retention) before persist. Workspace admin.
object
The governance rule for ONE memory scope: whether new memories of that scope skip
the review queue (auto_publish), whether they must be human-reviewed
(require_review), and how long they are retained before the decay sweep may
archive them (retention_days, 0 = keep forever).
auto_publish and require_review are intentionally NOT collapsed into one flag:
the conservative default is “review required, not auto-published”, and a future
“auto-published BUT still logged for review” mode keeps both axes meaningful. The
validation below rejects the contradictory auto_publish && require_review combo.
object
New memories of this scope skip the review queue and land live immediately.
New memories of this scope must be human-reviewed before they go live.
Days a memory of this scope is retained before the decay sweep may archive it;
0 keeps it forever (the default).
The governance rule for ONE memory scope: whether new memories of that scope skip
the review queue (auto_publish), whether they must be human-reviewed
(require_review), and how long they are retained before the decay sweep may
archive them (retention_days, 0 = keep forever).
auto_publish and require_review are intentionally NOT collapsed into one flag:
the conservative default is “review required, not auto-published”, and a future
“auto-published BUT still logged for review” mode keeps both axes meaningful. The
validation below rejects the contradictory auto_publish && require_review combo.
object
New memories of this scope skip the review queue and land live immediately.
New memories of this scope must be human-reviewed before they go live.
Days a memory of this scope is retained before the decay sweep may archive it;
0 keeps it forever (the default).
The governance rule for ONE memory scope: whether new memories of that scope skip
the review queue (auto_publish), whether they must be human-reviewed
(require_review), and how long they are retained before the decay sweep may
archive them (retention_days, 0 = keep forever).
auto_publish and require_review are intentionally NOT collapsed into one flag:
the conservative default is “review required, not auto-published”, and a future
“auto-published BUT still logged for review” mode keeps both axes meaningful. The
validation below rejects the contradictory auto_publish && require_review combo.
object
New memories of this scope skip the review queue and land live immediately.
New memories of this scope must be human-reviewed before they go live.
Days a memory of this scope is retained before the decay sweep may archive it;
0 keeps it forever (the default).
Onboarding-safe flag. false graduates the workspace (autonomous backlog
dispatch + uncapped autonomy); absent leaves it unchanged.
Quiet-window end (HH:MM, UTC). Absent = no change; null = clear.
Quiet-window start (HH:MM, UTC). Absent = no change; null = clear.
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.
#532 (A5) — the OWNER-pinned credential that backs INTERNAL system-prompt LLM
calls (backlog classify / judge / recommendations / debate / vision). DOUBLE-
Option: absent = no change; null = clear the pin (back to the default
most-specific precedence); a value PINS the credential by id + kind. Validated
to be visible to the workspace before persist (never trust the id for
cross-workspace access).
object
The credential’s primary key (an api_key_refs.id or agent_oauth_tokens.id).
The credential kind: api_key or oauth_token.
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" }}Responses
Section titled “Responses”Settings patched; the echo round-trips the persisted values
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
#583 Item 2 / #582 — echoed Debug-light CEILING — present ONLY when the patch touched it.
Persisted autonomy level (0..=100, clamped to the plan ceiling) — present
ONLY when the patch touched the autonomy fields.
Persisted per-axis override vector — present ONLY when the patch touched the autonomy fields.
#712 — echoed workspace-tier standard-closeout config — present ONLY when the patch touched it (round-trips the persisted/validated config).
Persisted digest cadence (off | daily | weekly) — present ONLY when the
patch touched the digest config.
Persisted digest-enabled flag — present ONLY when the patch touched the digest config.
#708 W8 — echoed environment-scope FLOOR — present ONLY when the patch touched it.
Some(Some(scope)) = the mandated floor; Some(None) = cleared (no floor).
ADR 0049 P3 / Tier-3 — echoed per-scope memory governance policy — present ONLY when the patch touched it (the panel always sends the full three-scope policy, so the echo round-trips the persisted/validated policy).
object
The governance rule for ONE memory scope: whether new memories of that scope skip
the review queue (auto_publish), whether they must be human-reviewed
(require_review), and how long they are retained before the decay sweep may
archive them (retention_days, 0 = keep forever).
auto_publish and require_review are intentionally NOT collapsed into one flag:
the conservative default is “review required, not auto-published”, and a future
“auto-published BUT still logged for review” mode keeps both axes meaningful. The
validation below rejects the contradictory auto_publish && require_review combo.
object
New memories of this scope skip the review queue and land live immediately.
New memories of this scope must be human-reviewed before they go live.
Days a memory of this scope is retained before the decay sweep may archive it;
0 keeps it forever (the default).
The governance rule for ONE memory scope: whether new memories of that scope skip
the review queue (auto_publish), whether they must be human-reviewed
(require_review), and how long they are retained before the decay sweep may
archive them (retention_days, 0 = keep forever).
auto_publish and require_review are intentionally NOT collapsed into one flag:
the conservative default is “review required, not auto-published”, and a future
“auto-published BUT still logged for review” mode keeps both axes meaningful. The
validation below rejects the contradictory auto_publish && require_review combo.
object
New memories of this scope skip the review queue and land live immediately.
New memories of this scope must be human-reviewed before they go live.
Days a memory of this scope is retained before the decay sweep may archive it;
0 keeps it forever (the default).
The governance rule for ONE memory scope: whether new memories of that scope skip
the review queue (auto_publish), whether they must be human-reviewed
(require_review), and how long they are retained before the decay sweep may
archive them (retention_days, 0 = keep forever).
auto_publish and require_review are intentionally NOT collapsed into one flag:
the conservative default is “review required, not auto-published”, and a future
“auto-published BUT still logged for review” mode keeps both axes meaningful. The
validation below rejects the contradictory auto_publish && require_review combo.
object
New memories of this scope skip the review queue and land live immediately.
New memories of this scope must be human-reviewed before they go live.
Days a memory of this scope is retained before the decay sweep may archive it;
0 keeps it forever (the default).
Always true on a successful patch.
Echoed onboarding-safe flag (the request value; null when the field was
absent from the request).
Echoed quiet-window end (HH:MM, UTC); null when absent/cleared.
Echoed quiet-window start (HH:MM, UTC); null when absent/cleared.
Echoed system-LLM credential pin ({id,kind}) or null when cleared —
present ONLY when the patch touched the pin. DOUBLE-Option: the OUTER layer
gates presence (absent ⇒ key omitted), the INNER carries Some(pin) (echoes
{id,kind}) vs None (echoes null, i.e. the pin was cleared back to the
default precedence). Mirrors the apply path’s three-state echo; utoipa flattens
the nested Option into a single nullable SystemLlmCredentialPinEcho.
object
The pinned credential’s primary key.
The credential kind: api_key or oauth_token.
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
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
Machine-readable, stable error code.
Present only on a quota-exceeded 403 — the inline upgrade-CTA payload.
object
The entitlement feature key that was hit, e.g. apps.max_count.
The plan’s limit for this key.
Where to send the user to upgrade.
Current usage (count or bytes, per the key).
Human-readable message (the server’s English text; the client may localize
by code).
Example
{ "code": "not_found"}Authentication required
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
Machine-readable, stable error code.
Present only on a quota-exceeded 403 — the inline upgrade-CTA payload.
object
The entitlement feature key that was hit, e.g. apps.max_count.
The plan’s limit for this key.
Where to send the user to upgrade.
Current usage (count or bytes, per the key).
Human-readable message (the server’s English text; the client may localize
by code).
Example
{ "code": "not_found"}Permission denied
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
Machine-readable, stable error code.
Present only on a quota-exceeded 403 — the inline upgrade-CTA payload.
object
The entitlement feature key that was hit, e.g. apps.max_count.
The plan’s limit for this key.
Where to send the user to upgrade.
Current usage (count or bytes, per the key).
Human-readable message (the server’s English text; the client may localize
by code).
Example
{ "code": "not_found"}Structured server error
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
Machine-readable, stable error code.
Present only on a quota-exceeded 403 — the inline upgrade-CTA payload.
object
The entitlement feature key that was hit, e.g. apps.max_count.
The plan’s limit for this key.
Where to send the user to upgrade.
Current usage (count or bytes, per the key).
Human-readable message (the server’s English text; the client may localize
by code).
Example
{ "code": "not_found"}