Skip to content
Select themeSelect language

GET /api/operator/v1/tenant/run-analytics — cross-run analytics for THIS workspace (#626 BIG15 C1 §28): the slowest workflow steps (per `workflow_node_key` p95 + max duration) and the failure counts per workflow. Read-only, scoped to the authorized workspace (owner/admin) — mirrors `tenant_dispatch_metrics`, with an optional `?since=` window bound.

GET
/api/operator/v1/tenant/run-analytics
curl --request GET \
--url https://example.com/api/operator/v1/tenant/run-analytics
since
string format: date-time

Range start (inclusive) on runs.created_at. Absent ⇒ the last 30 days.

Media typeapplication/json

The tenant run-analytics snapshot (#626 BIG15 C1 §28): the slowest steps + the per-workflow failure counts, both scoped to one workspace. Empty vectors read as 0-count on a workspace with no completed/failed runs in the window.

object
errors_per_workflow
required

The workflows with failures, most-failures first (≤20).

Array<object>

One workflow’s failure profile (the errors-per-workflow gauge): the workflow id + name, the number of failed runs and the total runs over the window.

object
failures
required

Runs in failed status.

integer format: int64
total
required

Total runs (any status) — the failure denominator.

integer format: int64
workflow_id
required
string format: uuid
workflow_name
required

The workflow name, or "" when the workflow row was deleted (honest-empty).

string
slowest_steps
required

The slowest workflow steps (by p95), most-slow first (≤20).

Array<object>

One slow workflow step (the slowest-steps gauge): a workflow_node_key with its p95 + max wall-clock duration (seconds) over the window and the run count the percentile is computed from.

object
max_secs
required

The maximum step duration in seconds.

number format: double
node_key
required

The workflow node key the runs share (e.g. implement, review).

string
p95_secs
required

The 95th-percentile step duration in seconds.

number format: double
runs
required

The number of completed runs the p95/max are computed from.

integer format: int64
Examplegenerated
{
"errors_per_workflow": [
{
"failures": 1,
"total": 1,
"workflow_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"workflow_name": "example"
}
],
"slowest_steps": [
{
"max_secs": 1,
"node_key": "example",
"p95_secs": 1,
"runs": 1
}
]
}

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"
}