`GET /api/reports/overview` — windowed totals + per-dimension breakdown + gap-filled per-day series over `task_outcomes`.
const url = 'https://example.com/api/reports/overview';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/reports/overview \ --cookie supacloud_session=<supacloud_session>Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”today | 7d | 30d — the reporting window (default 7d).
agent | model | kind | project — the breakdown axis (default agent).
Responses
Section titled “Responses”object
object
The dimension value: agent_type | model | run kind | project UUID string.
A NULL/empty model or unmatched project folds to "unknown".
Human label: the project name for the project axis, else == key.
LOC produced for this dimension value (mig 252), COALESCE 0 — see
[ReportsTotals::loc_added].
#547/ADR-0049 delivery facts (closeout / governance / harness-memory /
issues-closed) — workspace-wide scalars alongside totals.
object
Closeout proposals approved in the window, windowed by decision time
(reviewed_at) so a stale pending proposal does not inflate the count.
Closeout proposals awaiting review, windowed by proposal time (created_at).
Closeout proposals rejected in the window (windowed by reviewed_at).
Project docs updated (#712 K-07) — task_outcomes whose standard-closeout
closeout_signals.project_docs_touched is true. 0 until the bw-infra runner
emits changed_paths (same NULL-until-runner degradation as lines_added).
Privileged-override governance decisions in the window — audit_events
rows matching the audited OVERRIDE_HINTS pattern set (grant / override /
transfer_ownership / suspend_member / remove_member / force / bypass).
Harness-captured memory writes in the window — memories rows with a
source_type LIKE 'harness_memory:%', windowed by updated_at.
Issues delivered — completed tasks that carried a linked issue
(tasks.config->>'link_issue_id'). The honest proxy for an issue closed,
since the issue itself transitions via the merged PR’s Fixes #N and no
dedicated issue-transition audit action exists to count directly.
User docs updated (#712 K-07) — task_outcomes whose
closeout_signals.user_docs_touched is true (0 until the runner emits paths).
The closeout WIKI step is not counted — a wiki note is not a repo file, so it
never appears in changed-paths; a wiki count needs a separate runner signal.
#626 §11 — the equal-length prior window’s totals, the baseline for the KPI
delta badges (the FE derives every % change from totals vs prev, so the
contract carries one reused struct, not a field-per-delta explosion).
object
Mean wall-clock seconds (completed_at - started_at) over the window’s
completed tasks; null when no task completed (an empty window has no
duration — NOT 0, which would read as instantaneous).
Median per-task cost over the window (the typical task cost, robust to a few expensive outliers the mean would skew).
Cost spent under a SUBSCRIPTION credential (tasks.credential_kind = 'oauth_token', mig 211) — the honest subscription-vs-API split. API-key
spend is cost_usd - cost_usd_subscription_covered.
LOC produced over the window — lines added/removed across the tasks’ git diffs (mig 252). COALESCE 0 (NULLABLE column), so a window with no LOC captured — e.g. before the runner image ships the diff stat — reads 0.
95th-percentile wall-clock seconds; null on an empty window.
PRs closed WITHOUT merging — outcomes with a non-NULL
pr_closed_unmerged_at (a PR that was rejected/abandoned, not merged).
PRs merged over the window — outcomes with a non-NULL pr_merged_at.
PRs opened over the window — tasks whose outcome carries a non-empty
pr_url (#547 honest deliverable, already per-task on task_outcomes).
Tasks that ended failed.
Tasks that ever started (tasks.started_at set) — the denominator for a
success-rate gauge.
#626 §11 — tasks that ended completed over the window (joined tasks.status).
#626 §19 — the run-kind donut (agent/workflow/script/app) from runs.
#626 §19 — one slice of the run-kind donut. Sourced from runs directly, so a
workflow/script/app run (which carries no task_outcomes row) is counted
honestly alongside agent.
object
The run kind — agent | workflow | script | app.
Top-level runs of this kind over the window (children excluded).
object
ISO date YYYY-MM-DD — a NaiveDate serializes to exactly this string.
#626 §11 — the 5 most expensive tasks over the window.
#626 §11 — one row of the Uebersicht “Teuerste Tasks” (top tasks by cost) list.
object
The project name, falling back to the project UUID string.
The task title (blank if the task row was deleted).
object
Mean wall-clock seconds (completed_at - started_at) over the window’s
completed tasks; null when no task completed (an empty window has no
duration — NOT 0, which would read as instantaneous).
Median per-task cost over the window (the typical task cost, robust to a few expensive outliers the mean would skew).
Cost spent under a SUBSCRIPTION credential (tasks.credential_kind = 'oauth_token', mig 211) — the honest subscription-vs-API split. API-key
spend is cost_usd - cost_usd_subscription_covered.
LOC produced over the window — lines added/removed across the tasks’ git diffs (mig 252). COALESCE 0 (NULLABLE column), so a window with no LOC captured — e.g. before the runner image ships the diff stat — reads 0.
95th-percentile wall-clock seconds; null on an empty window.
PRs closed WITHOUT merging — outcomes with a non-NULL
pr_closed_unmerged_at (a PR that was rejected/abandoned, not merged).
PRs merged over the window — outcomes with a non-NULL pr_merged_at.
PRs opened over the window — tasks whose outcome carries a non-empty
pr_url (#547 honest deliverable, already per-task on task_outcomes).
Tasks that ended failed.
Tasks that ever started (tasks.started_at set) — the denominator for a
success-rate gauge.
#626 §11 — tasks that ended completed over the window (joined tasks.status).
Examplegenerated
{ "breakdown": [ { "cost_usd": 1, "input_tokens": 1, "key": "example", "label": "example", "loc_added": 1, "loc_removed": 1, "output_tokens": 1, "tasks": 1 } ], "delivery": { "closeout_approved": 1, "closeout_pending": 1, "closeout_rejected": 1, "docs_updated": 1, "governance_decisions": 1, "harness_memory_updates": 1, "issues_closed": 1, "user_docs_updated": 1 }, "group_by": "example", "period": "example", "prev": { "avg_duration_secs": 1, "cost_usd": 1, "cost_usd_median": 1, "cost_usd_subscription_covered": 1, "input_tokens": 1, "loc_added": 1, "loc_removed": 1, "output_tokens": 1, "p95_duration_secs": 1, "prs_closed": 1, "prs_merged": 1, "prs_opened": 1, "tasks": 1, "tasks_failed": 1, "tasks_started": 1, "tasks_succeeded": 1 }, "run_kinds": [ { "kind": "example", "runs": 1 } ], "series": [ { "cost_usd": 1, "day": "example", "tasks": 1 } ], "top_tasks": [ { "cost_usd": 1, "project_label": "example", "task_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "title": "example" } ], "totals": { "avg_duration_secs": 1, "cost_usd": 1, "cost_usd_median": 1, "cost_usd_subscription_covered": 1, "input_tokens": 1, "loc_added": 1, "loc_removed": 1, "output_tokens": 1, "p95_duration_secs": 1, "prs_closed": 1, "prs_merged": 1, "prs_opened": 1, "tasks": 1, "tasks_failed": 1, "tasks_started": 1, "tasks_succeeded": 1 }}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"}