Skip to content

Get a produced Solution report

GET
/api/solutions/runs/{run_id}/
curl --request GET \
--url 'http://localhost:8000/api/solutions/runs/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/?reader_mode=amateur' \
--header 'Authorization: Bearer <token>'

The assembled report for a run: { manifest, meta, data }. data (ReportData) is keyed by block id and assembled from the bound sessions’ metrics + green zones; deferred blocks are omitted (the renderer skips absent ids). data numbers are metric (the client converts to imperial at render); ?units= only selects the AI-coach take whose prose matches the coach’s unit system, so the analysis never quotes cm against an imperial body.

meta.aiStale (#1528) flags that the cached AI text was written from inputs that have since changed (a bound session was re-analyzed, a threshold moved, a phase frame was re-picked) — the deterministic blocks are current, the prose is not. Regenerate via POST /api/solutions/runs/<id>/refresh-ai/.

meta.hiddenSections (#1977) is the coach’s STORED set for this run — what a control reflects and sends back, not something to filter on, since the blocks are already pruned out of manifest / data. meta.hiddenSectionsWithheld is the subset this report actually removed: a group the manifest never declares is stored all the same and withholds nothing, so a count or a note shown to the coach reads THAT one. Both absent when the report is full; the second alone is absent when the stored set acts on nothing here.

meta.audience (#2040) is the run’s tier when it is not the default practitioner — absent on a practitioner report, which is byte-identical to a report from before tiers existed. meta.audienceWithheld names the section groups the tier withholds from THIS report, and meta.audienceWithheldByTier the same answer for every tier (practitioner always empty), so a version picked before it is applied shows what it leaves out. On athlete the payload itself carries no joint-angle reading, and data["ai-coach-1"].focus names the athlete summary’s own artifact for the streaming and edit routes. include_hidden does not lift the tier.

run_id
required
string format: uuid
include_hidden
boolean

true assembles the run IGNORING its stored hidden_sections (#1977) — the coach’s preview of what their client will NOT see. Read-only: the setting is untouched, and meta.hiddenSections still reports it, so the client can label the state it is showing. The public share endpoint has no equivalent.

lang
string

en (default) / ru / es.

reader_mode
string
Allowed values: amateur coach

coach | amateur — whose words the result is written in: the coach’s, or an amateur’s (Bowler Mode on bowling). Defaults to the client’s own setting; an activity with no amateur copy always reads as coach.

units
string

metric (default) or imperial.

Media typeapplication/json

GET /api/solutions/runs/<id>/ — the produced report. manifest, meta, and data are open objects: the @aikynetix/ui renderer owns the block shapes, and data (ReportData) is keyed by block id. Absent block ids render as empty (the renderer’s BlockSlot skips them).

object
manifest
required

The SolutionDefinition.

object
key
additional properties
meta
required

ShellComponentMeta — title/subtitle/branding/sourceSession/cameraView. layoutDefault is the report canvas’s declared Layer-2 arrangement ([{id, w}], manifest order, w a 12-column span) that a coach’s saved layout (/api/me/report-layout/) is reconciled against.

object
key
additional properties
data
required

ReportData — { blockId: payload } assembled from the run’s sessions.

object
key
additional properties

Example generated

{
"manifest": {
"additionalProperty": "example"
},
"meta": {
"additionalProperty": "example"
},
"data": {
"additionalProperty": "example"
}
}
Media typeapplication/json
object
detail
required

Human-readable message, or a stable machine code for the cases a client branches on. The standard envelope for 400 (validation — a field-keyed object may appear instead), 401 (missing / invalid credentials), 403 (authenticated but not permitted), and 404 (absent — cross-team records are collapsed to 404 so the API never leaks the existence of another team’s data).

string

Example generated

{
"detail": "example"
}