Skip to content

Replace the coach's arrangement for one report

PUT
/api/me/report-layout/
curl --request PUT \
--url http://localhost:8000/api/me/report-layout/ \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "surface": "solution", "key": "running-gait", "fp": "c1-5d0e9a41", "items": [ { "id": "section-metrics-breakdown", "w": 12 }, { "id": "section-spyder-sagittal", "w": 6 }, { "id": "section-graphs", "w": 6 }, { "id": "section-phase-slider", "w": 12 }, { "id": "section-spyder-frontal", "w": 6 }, { "id": "section-backview-skeleton", "w": 6 } ] }'

The signed-in coach’s arrangement of one report’s panels on the report canvas (#1781): their order and their width on a 12-column grid. A view preference stored on the coach’s account, so it follows them across devices; per coach, with no owner or team gate. Exports never read it — the PDFs and the public share links always render the report’s default order. Addressed by surface + key: solution + the report slug, or player + <activity>:<exercise>.

Full replace, not a patch: send the COMPLETE merged panel list, including panels absent from the view on screen (another camera view, a hidden section), or they lose their place. The server stores the list as sent and returns it; resetting to the default is a DELETE, not a PUT of the default list.

PUT /api/me/report-layout/ request — REPLACE the coach’s arrangement for one report with the full merged list (panels absent from the view on screen included, or they lose their place).

object
surface
required

solution (a Solutions report) or player (the session player).

  • solution - Solutions report
  • player - Session player
string
Allowed values: solution player
key
required

solution: the report slug (e.g. running-gait). player: <activity>:<exercise> — the exercise may be empty (running:).

string
>= 1 characters <= 160 characters
fp
required

Fingerprint of the declared default this layout was arranged against.

string
>= 1 characters <= 64 characters
items
required

The full ordered panel list, ids unique, 1–32 entries. Stored as sent; the canvas resets with DELETE rather than by saving the default.

Array<object>
>= 1 items <= 32 items

One arranged panel: its id and its span on the 12-column canvas.

object
id
required

Panel id — a Layer-2 section id on a Solutions report (e.g. section-graphs), a panel id on the player (e.g. panel-video).

string
>= 1 characters <= 64 characters
w
required

Width in columns of the 12-column canvas (1–12).

integer
>= 1 <= 12

Examples

ExampleSaveARunningGaitArrangement

Replace the arrangement with the full merged list

{
"surface": "solution",
"key": "running-gait",
"fp": "c1-5d0e9a41",
"items": [
{
"id": "section-metrics-breakdown",
"w": 12
},
{
"id": "section-spyder-sagittal",
"w": 6
},
{
"id": "section-graphs",
"w": 6
},
{
"id": "section-phase-slider",
"w": 12
},
{
"id": "section-spyder-frontal",
"w": 6
},
{
"id": "section-backview-skeleton",
"w": 6
}
]
}
Media typeapplication/json

GET / PUT /api/me/report-layout/ response — the signed-in coach’s arrangement for one report, layout: null when there is none.

object
surface
required

solution (a Solutions report) or player (the session player).

  • solution - Solutions report
  • player - Session player
string
Allowed values: solution player
key
required

The report slug (solution) or <activity>:<exercise> (player).

string
layout
required

The saved arrangement, or null when the coach has none (render the default).

object
fp
required

The client’s fingerprint of the declared default the layout was arranged against (meta.layoutDefault on a Solutions report). Stored opaquely; a mismatch tells the client the save is stale.

string
<= 64 characters
items
required

Every arranged panel, in display order.

Array<object>

One arranged panel: its id and its span on the 12-column canvas.

object
id
required

Panel id — a Layer-2 section id on a Solutions report (e.g. section-graphs), a panel id on the player (e.g. panel-video).

string
<= 64 characters
w
required

Width in columns of the 12-column canvas (1–12).

integer
>= 1 <= 12

Examples

ExampleSavedArrangement

Saved arrangement

{
"surface": "solution",
"key": "running-gait",
"layout": {
"fp": "c1-5d0e9a41",
"items": [
{
"id": "section-metrics-breakdown",
"w": 12
},
{
"id": "section-spyder-sagittal",
"w": 6
},
{
"id": "section-graphs",
"w": 6
},
{
"id": "section-phase-slider",
"w": 12
},
{
"id": "section-spyder-frontal",
"w": 6
},
{
"id": "section-backview-skeleton",
"w": 6
}
]
}
}

The address errors of GET; a blank or over-long fp; items empty, longer than 32 or with repeated ids (a list of messages); invalid panels — a blank or over-long id, a span outside 1–12 — as an object keyed by the failing panel’s index; a NEW key past the 256-layout cap (on key); or a save that would grow the coach’s stored layouts past 160 KB (on items).

Media typeapplication/json

Validation errors keyed by field. Each value is a list of human-readable messages — except a per-panel items error, which is an object keyed by the failing panel’s index (only failing panels appear), each holding that panel’s field-keyed messages, or a list of messages when the panel is not an object at all (e.g. null).

object
key
additional properties
Any of:
Array<string>

Examples

400 — Unknown report

{
"key": [
"Unknown Solutions report 'runing-gait'."
]
}
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"
}
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"
}