put_api_projects_id_
const url = 'https://example.com/api/projects/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0';const options = { method: 'PUT', headers: { cookie: 'supacloud_session=<supacloud_session>', 'Content-Type': 'application/json' }, body: '{"automations":[{"agent_profile_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","autonomy_override":1,"candidate_profile_ids":["2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"],"close_source_issue":true,"completion_action":"example","denied_tools":["example"],"enabled":true,"environment_scope":"example","kind":"example","pipeline_config":"example","post_completion_comment":true,"review_enabled":true,"severity_min":"example","source_filter":"example","trigger":"example","webhook_secret":"example"}],"autonomy_level":1,"autonomy_overrides":"example","backlog_classifier":"example","backlog_daily_budget_usd":1,"backlog_max_concurrent":1,"backlog_merge_policy":"example","backlog_mode_enabled":true,"backlog_required_reviewers":1,"closeout_config":"example","daily_budget_usd":1,"denied_tools":["example"],"git_credential_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","git_default_branch":"example","git_provider":"example","git_repo_url":"example","issue_tracker":"example","issue_tracker_autodev_enabled":true,"issue_tracker_credential_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","issue_tracker_key":"example","issue_tracker_state_map":"example","issue_tracker_webhook_secret":"example","memory_governance_policy":"example","monthly_budget_usd":1,"name":"example","required_worker_group_ids":["2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PUT \ --url https://example.com/api/projects/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0 \ --header 'Content-Type: application/json' \ --cookie supacloud_session=<supacloud_session> \ --data '{ "automations": [ { "agent_profile_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "autonomy_override": 1, "candidate_profile_ids": [ "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" ], "close_source_issue": true, "completion_action": "example", "denied_tools": [ "example" ], "enabled": true, "environment_scope": "example", "kind": "example", "pipeline_config": "example", "post_completion_comment": true, "review_enabled": true, "severity_min": "example", "source_filter": "example", "trigger": "example", "webhook_secret": "example" } ], "autonomy_level": 1, "autonomy_overrides": "example", "backlog_classifier": "example", "backlog_daily_budget_usd": 1, "backlog_max_concurrent": 1, "backlog_merge_policy": "example", "backlog_mode_enabled": true, "backlog_required_reviewers": 1, "closeout_config": "example", "daily_budget_usd": 1, "denied_tools": [ "example" ], "git_credential_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "git_default_branch": "example", "git_provider": "example", "git_repo_url": "example", "issue_tracker": "example", "issue_tracker_autodev_enabled": true, "issue_tracker_credential_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "issue_tracker_key": "example", "issue_tracker_state_map": "example", "issue_tracker_webhook_secret": "example", "memory_governance_policy": "example", "monthly_budget_usd": 1, "name": "example", "required_worker_group_ids": [ "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" ] }'Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Project id
Request Bodyrequired
Section titled “Request Bodyrequired”object
ADR 0045 Stage 1b — the consolidated Automation section’s per-kind rows,
dual-written into project_automations alongside the legacy flag columns.
What a save supplies for one automation. webhook_secret = None keeps any
stored secret on update (the persistence COALESCE) — a config edit need not
re-type it. autonomy_override is the REQUESTED level; the service clamps it
to the workspace ceiling before persist.
object
#534 WS-2 — the multi-agent work-lane candidate pool (backlog/simple lane).
Some(None) clears; Some(Some([])) = the All wildcard (every keyed
workspace profile, dynamic); Some(Some([ids])) = an explicit set; an omitted
key (outer None) keeps the stored pool.
#538 L12 — the post-completion issue action (close | comment | nothing). Legacy: the
FE now sends the two booleans below; kept for back-compat + dual-write.
#538 feinschliff — the dev-pipeline knobs JSONB (return_to_sender, convergence_level, max_rounds, max_cost_usd, per-stage overrides; mig 231).
#708 C1 — the two ADDITIVE completion booleans (post the closing comment × close/
transition the source issue). An omitted key keeps the stored value; when set, the write
derives + dual-writes completion_action (lossy for “silent close”).
#538 feinschliff — the Review toggle (the gated audit tail).
Write-only HMAC secret; an omitted/empty value keeps the stored secret (the persistence COALESCE), a non-empty value overwrites it.
ADR 0045 Stage 4 — per-project autonomy override base level. DOUBLE-Option:
absent leaves it untouched; null clears it (inherit the workspace); a
value sets it (clamped to the plan ceiling). The DB CHECK bounds 0..=100.
ADR 0045 Stage 4 — the project’s Advanced override vector. None leaves it
untouched; a value replaces it. Applied only when autonomy_level is present.
#626 G1 — backlog classifier variant ('llm' | 'rules', mig 167 CHECK).
None leaves the column untouched.
#708 B4 — per-project daily backlog $-budget. DOUBLE-Option: absent untouched;
null clears to no-cap; a value sets it. Owner/admin.
#708 B4 — per-project backlog concurrency cap. DOUBLE-Option: absent untouched;
null clears (inherit the workspace ceiling); a value sets it. Owner/admin.
ADR 0045 Stage 1b — backlog merge policy ('pr_only' default). None
leaves it untouched.
ADR 0045 Stage 1b — autonomous backlog-dispatch mode (XOR PR-flow
auto-developer; the UI enforces the exclusivity, the server does not).
None leaves the column untouched.
#708 B4 — required distinct-human reviewer bar (mig 167). None untouched. Owner/admin.
#712 — the project-tier SPARSE standard-closeout override (mig 283). DOUBLE-Option:
absent leaves it untouched; null RESETS it to inherit the workspace default (SQL
NULL); a value stores the sparse override (shape-validated on write). Owner/admin
safety rail.
#708 M5 — the per-project TOTAL daily $-budget (mig 296): an AND-gate UNDER the
workspace cap that binds EVERY lane (manual, backlog AND pr_review). Double-Option:
absent = untouched; null = clear; a value = set. Owner/admin safety rail.
ADR 0045 Stage 1b — per-project blast-radius tool denylist (mig 210).
None leaves it untouched.
#708 W13 — the project-tier SPARSE memory-governance override (mig 289). DOUBLE-Option:
absent leaves it untouched; null RESETS it to inherit the workspace policy (SQL
NULL); a value stores the sparse override (shape-validated on write). Owner/admin
safety rail.
#708 M5 — the per-project TOTAL monthly $-budget (mig 296). Same double-Option
semantics; AND-gates under the workspace cap alongside daily_budget_usd.
ADR 0046 RUNG 1b — the project’s worker-group OVERRIDE binding. DOUBLE-Option:
absent leaves it untouched; null clears it to inherit (column NULL); a value
(incl. []) sets the override. Workspace admin (a routing/safety rail).
Examplegenerated
{ "automations": [ { "agent_profile_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "autonomy_override": 1, "candidate_profile_ids": [ "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" ], "close_source_issue": true, "completion_action": "example", "denied_tools": [ "example" ], "enabled": true, "environment_scope": "example", "kind": "example", "pipeline_config": "example", "post_completion_comment": true, "review_enabled": true, "severity_min": "example", "source_filter": "example", "trigger": "example", "webhook_secret": "example" } ], "autonomy_level": 1, "autonomy_overrides": "example", "backlog_classifier": "example", "backlog_daily_budget_usd": 1, "backlog_max_concurrent": 1, "backlog_merge_policy": "example", "backlog_mode_enabled": true, "backlog_required_reviewers": 1, "closeout_config": "example", "daily_budget_usd": 1, "denied_tools": [ "example" ], "git_credential_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "git_default_branch": "example", "git_provider": "example", "git_repo_url": "example", "issue_tracker": "example", "issue_tracker_autodev_enabled": true, "issue_tracker_credential_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "issue_tracker_key": "example", "issue_tracker_state_map": "example", "issue_tracker_webhook_secret": "example", "memory_governance_policy": "example", "monthly_budget_usd": 1, "name": "example", "required_worker_group_ids": [ "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" ]}Responses
Section titled “Responses”Updated project
object
D1 — the materialized Auto Developer workflow’s id, surfaced so the
project-edit UI can render an “Edit workflow” link. None until the arm’s
workflow is materialized.
ADR 0045 Stage 4 — the project-scope autonomy level (0..=100), or null
to inherit from the workspace. The project-edit form seeds the autonomy
slider from it.
ADR 0045 Stage 4 — the Advanced per-axis autonomy override vector
(free-form string-keyed bag, e.g. {"level": N}). Defaults to {}. The
project-edit form seeds the Advanced overrides from it.
object
Issue #532 — how items are classified: 'llm' (default — one LLM call per
item, tuned by the backlog automation’s source_filter classifier config)
or 'rules' (the deterministic mapping). Surfaced so the Automation
section shows the editable Classifier tuning for llm and the read-only
rules mapping for rules.
#708 B4 — per-project daily backlog $-budget (null = no cap). Surfaced so the
backlog-limits field can seed + round-trip its current value.
#708 B4 — per-project backlog concurrency cap (null = inherit the workspace
ceiling). Surfaced so the backlog-limits field can seed + round-trip.
ADR 0045 Stage 1b — backlog merge policy: 'pr_only' (default) |
'auto_on_green' | 'full_auto'. Surfaced so the consolidated
Automation section can round-trip the selected Approval-mode.
#364 / #388 — whether the project runs in autonomous backlog-dispatch mode (mutually exclusive with PR-flow auto-developer). Surfaced so the #358 board + project detail can render the “Backlog” chip.
ADR 0045 Stage 1b — N human approvals required on the backlog
in_review → done/merge step. Surfaced read-only on the project detail.
#712 — the project-tier SPARSE standard-closeout override (mig 283), or null
to inherit the workspace default entirely. A sparse per-step bag
({memory, project_docs, user_docs, wiki}); #708 S4 types its interior via the
CloseoutConfigPatch schema (was an opaque unknown).
object
Gates the Tier-0 closeout MEMORY proposal. None inherits the next tier.
#708 M5 — the project-TOTAL daily/monthly $-budget caps (mig 296; every launch, not
just backlog). Surfaced so the Guardrails budget inputs seed + round-trip their
current value. null = no project cap.
ADR 0045 Stage 1b — per-project blast-radius tool denylist (mig 210). Surfaced so the Automation section can render + round-trip the chosen Blast-radius denied tools.
ADR 0029 Slice 5 — Linear/Notion issue tracker config.
ADR 0029 Slice 7 — tracker auto-developer toggle. The webhook secret
itself (the HMAC signing secret the Linear/Notion receiver verifies
against) is NEVER returned outward: a member who could read it could
forge validly-signed webhooks that launch agents (H1 audit). Mirroring
the auto_developer_webhook_secret posture, we expose only whether one
is configured. The user supplies the secret on create/update, so they
already know its value and never need it read back.
ADR 0029 Slice 6 (D7) — per-provider state-name overrides. The runtime
type stays serde_json::Value (a free-form JSONB column); the spec is
narrowed to the real serialized shape — a map keyed by tracker provider
name (linear / notion) to a [TrackerStateNames] override bag.
Issue #110: per-project concurrency cap; None = unlimited.
#708 W13 — the project-tier SPARSE memory-governance override (mig 289), or null
to inherit the workspace policy entirely. A sparse per-scope JSONB bag
({workspace, project, personal}) the project-edit settings seed from.
Examplegenerated
{ "auto_developer_workflow_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "autonomy_level": 1, "autonomy_overrides": { "additionalProperty": "example" }, "backlog_classifier": "example", "backlog_daily_budget_usd": 1, "backlog_max_concurrent": 1, "backlog_merge_policy": "example", "backlog_mode_enabled": true, "backlog_required_reviewers": 1, "closeout_config": { "memory": true, "project_docs": { "condition": "example", "enabled": true, "globs": [ "example" ] }, "user_docs": { "condition": "example", "enabled": true, "globs": [ "example" ], "langs": [ "example" ] }, "wiki": { "condition": "example", "enabled": true } }, "created_at": "2026-04-15T12:00:00Z", "daily_budget_usd": 1, "denied_tools": [ "example" ], "detected_stack": "example", "git_credential_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "git_default_branch": "example", "git_provider": "example", "git_repo_url": "example", "id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "image_built_at": "2026-04-15T12:00:00Z", "image_config": "example", "image_error": "example", "image_size": 1, "image_status": "example", "image_tag": "example", "issue_tracker": "example", "issue_tracker_autodev_enabled": true, "issue_tracker_credential_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "issue_tracker_key": "example", "issue_tracker_state_map": "example", "issue_tracker_webhook_secret_set": true, "max_concurrent_runs": 1, "memory_governance_policy": "example", "monthly_budget_usd": 1, "name": "example", "user_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "workspace_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"}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"}