`GET /api/team-board` — the dense, server-paginated delivery board for the active workspace: one row per agent profile (or unassigned-agent fallback), each carrying aggregate queued / running / needs-input / done-PR / failed counts plus last activity and cost. Route name unchanged (ADR 0040).
const url = 'https://example.com/api/team-board';const options = {method: 'GET', headers: {cookie: 'supacloud_session=<supacloud_session>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url https://example.com/api/team-board \ --cookie supacloud_session=<supacloud_session>Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”Status tab: active / attention / failed (anything else = all).
Free-text search over the agent profile name + agent type.
Whitelisted sort column: last_activity | cost_usd | agent_type |
total_tasks | prs_merged | avg_duration_secs. Default last_activity.
asc | desc (default desc).
#626 — the reporting period the WHOLE board is scoped to: today | 7d |
30d | 90d | year (default 7d). Windows the rows, facets, KPIs and
trend on tasks.created_at >= since.
Recompute the NavTab count facets (default true). The board sends false
for a tab/page change (the counts don’t depend on either).
Compute the windowed KPI block (default true). The board sends false for a
tab/page change (the KPIs depend only on the period, not the tab/page).
Responses
Section titled “Responses”GET /team-board body — one page of dense per-profile delivery rows.
object
NavTab count facets — per-PROFILE-ROW counts over the workspace scope,
independent of the active tab. active = rows with any in-flight task,
attention = rows with any needs-input task, failed = rows with any
failed/cancelled task. The paused filter chip (a row with NO in-flight task)
is derived and carries no dedicated count — the FE renders the status chips
label-only, so only these four counts are surfaced.
object
One dense delivery-board row: an agent-profile bucket with aggregate task
counts (no per-task Vecs). profile is resolved for rows with a profile
id; fallback_agent_type is set for the unassigned-fallback bucket.
object
#626 — mean wall-clock seconds over the bucket’s completed tasks (“Ø Dauer”);
null when no task completed in the window.
#626 — the most recent model the bucket’s outcomes recorded; the FE prefers
the profile’s pinned fixed_model and falls back to this for a non-fixed
(auto-policy) profile. null when no outcome carried a model.
object
ADR 0045 §3.1 Stage 4 — OPTIONAL profile autonomy override (mig 214, nullable
SMALLINT). None = inherit the project/workspace level (sits between project
and workspace in the §3.1 precedence chain). #[serde(default)] keeps old
AgentProfileVersion JSON snapshots (pre-214) deserializable — they default to
None (a no-op).
ADR 0045 §3.1 — per-axis Advanced override vector (mig 214, JSONB NOT NULL DEFAULT '{}'). Empty {} = no per-axis override; the editor reads an
optional level key. #[serde(default)] keeps old snapshots deserializable.
Runtime stays serde_json::Value; the spec types it as an open map.
object
Avatar rendering kind (color | initial | icon | image). Runtime String;
the spec narrows it to the closed [AvatarKind] the editor offers.
ADR 0045 §3.6 — the profile’s default reasoning effort (migration
208, effort_default TEXT). Canonical lowercase string
(minimal | low | medium | high | max); None means “inherit the
runner default”. #[serde(default)] keeps old AgentProfileVersion
JSON snapshots (written before this column existed) deserializable —
they default to None (a no-op). Runtime stays String; the spec
narrows it to the closed canonical [sc_types::Effort]
(its lowercase wire form matches this column’s DB CHECK set).
Issue #364 / ADR 0039 (D7) — Claude execution mode lever (normal | workflow;
ultracode was RETIRED from this dimension by #708 who-3, migration 285 — it
survives only as the top EFFORT stage). #[serde(default = ...)] keeps old
AgentProfileVersion JSON snapshots (written before this column existed)
deserializable; they default to "normal" (a no-op). Runtime String; the
spec narrows it to the closed [ExecutionMode].
ADR 0045 §3.2 Stage 3 — when true, a task running under this profile arms
the interactive-approval gate (the runner’s canUseTool / pre-exec hook
pauses on a dangerous tool call, an open question, or a visual before/after
and waits for a human Approve/Reject; migration 213). false is today’s
behaviour (no gate). #[serde(default)] keeps old AgentProfileVersion
JSON snapshots (written before this column existed) deserializable — they
default to false (a no-op).
Issue #242 — when true, this profile’s capability_allowlist is the
workspace fallback MCP tool set for profile-less / empty-allowlist
tasks. At most one profile per team carries this flag (enforced by the
partial unique index uq_agent_profiles_workspace_default in
migration 119).
ADR 0049 (#547 / #548) — opt-in gate for the agent memory.create MCP tool
(migration 249, BOOLEAN NOT NULL DEFAULT false). When false (the default
for every profile) a task running under this profile CANNOT directly create a
memory — memory.create fails closed; only a workspace admin enabling this on
the profile editor opens the unreviewed direct-write path. Distinct from
memory_policy.allow_propose_create (the default-true review-first gate).
#[serde(default)] keeps old AgentProfileVersion JSON snapshots (written
before this column existed) deserializable — they default to false (a no-op).
The fixed memory-policy knobs the editor reads. Runtime stays
serde_json::Value; the spec types it as [AgentMemoryPolicy].
object
Model-selection policy (manual | fixed | auto). Runtime String; the spec
narrows it to the closed [ModelPolicy].
Forward-compatible list of post-flight check entries (e.g. the
kind:"visual_verify" gate). Runtime stays serde_json::Value; spec-typed
as an array of open maps.
object
Forward-compatible list of pre-flight check entries (each an open object,
e.g. a kind-discriminated gate). Runtime stays serde_json::Value; the
spec types it as an array of open maps so the value is not stripped.
object
ADR 0046 RUNG 1b — OPTIONAL profile worker-group affinity override (mig 227,
nullable UUID[]). None = inherit (the head of the first-non-null
profile->project->task chain — NULL contributes nothing); Some(vec![]) = an
explicit “no affinity from this source”. Resolved into the task’s
required_labels by services::runners::groups. #[serde(default)] keeps old
AgentProfileVersion JSON snapshots (pre-227) deserializable.
NB: this binding is intentionally EXCLUDED from agent-profile version snapshot/restore — it is dispatch-routing scope (a live operational binding), not part of the profile’s behavioural definition, so a version restore does not carry or revert it (ADR 0046 RUNG 1b review).
Open retry-policy bag. Runtime stays serde_json::Value; spec-typed as an
open map.
object
Issue #217 / ADR 0028 — optional slug whitelist for the script.run
MCP tool. NULL means any script in the workspace is callable; a
non-NULL array (including empty) is an explicit whitelist.
#626 — PRs merged by this bucket’s tasks (the “PRs” column).
#626 — a per-day task-count sparkline over the window (oldest → newest, gap-filled to a fixed length). Drives the “Trend” column.
#626 — the windowed KPI block (prior-window deltas included), present only
when include_kpis (default true).
object
Tasks created in the window (the period’s new-work volume).
In-flight tasks right now (window-independent — a long run counts whenever it started).
Mean wall-clock seconds (completion − start) over the window’s completed
tasks; null on an empty window.
The prior window’s mean cycle time (the delta baseline); null when the
prior window had no completed task.
Tasks needing input right now (window-independent).
Draft PRs (pr_is_draft IS TRUE); 0 until a PR-draft writer reports the flag.
PRs merged in the window.
PRs merged in the equal-length window immediately before (the delta baseline).
PRs opened and still open (not merged, not closed-unmerged).
Example
{ "items": [ { "profile": { "avatar_kind": "color", "effort_default": "minimal", "execution_mode": "normal", "model_policy": "manual" } } ]}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"}