Skip to content

Create (or reuse) a public share link for a session comparison

POST
/api/sessions/compare/share/
curl --request POST \
--url http://localhost:8000/api/sessions/compare/share/ \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "ids": [ "5c836d7d-3301-49df-bfa0-9cff0550fd0e", "29f151e9-3449-4e5b-8539-73ac377c76c5" ] }'

Issues a public, token-gated URL for a side-by-side comparison of 2–4 completed sessions (#1002) — the before/after report a coach sends to the athlete. Mirrors the single-session share: reuses the most recent active token for the exact same ordered session set (the URL the coach sent yesterday keeps working); each call (re-)stamps the share’s locale from ?lang= (clamped to en / ru / es, default en); expired tokens stay as audit trail and a fresh one is minted alongside. Read the shared comparison via GET /api/shared/compare/<token>/.

404 session_not_found when any id is unknown or belongs to another team. 409 session_not_completed unless every session has finished analysis.

lang
string

Active UI language (en / ru / es) to freeze on the share. Defaults to en when omitted or unrecognised.

Body of POST /api/sessions/compare/share/ (#1002) — the ordered session set to freeze on the public comparison link.

object
ids
required

2–4 session UUIDs in the card order to show on the public comparison page (e.g. before → after). All must belong to the caller’s team and have status == 'completed'.

Array<string>
>= 2 items <= 4 items
Examples
ExampleBefore/AfterPair

Before / after pair

{
"ids": [
"5c836d7d-3301-49df-bfa0-9cff0550fd0e",
"29f151e9-3449-4e5b-8539-73ac377c76c5"
]
}
Media typeapplication/json
object
token
required

Opaque, URL-safe share token. Treat as a secret — anyone with it can read the report.

string
url
required

Relative public path (/r/<token>). Prefix with your web origin to share.

string
expires_at
required

ISO-8601 UTC expiry — SHARE_LINK_TTL_DAYS out (30 by default), re-stamped to a full window on every re-share, past which the public route returns 410. null only on links minted before the TTL landed (#1400).

string format: date-time
nullable
locale
required

Language frozen on this share (en / ru / es). The public shared coaching stream renders the AI paragraph in this locale regardless of the recipient’s browser settings. Re-issuing the share with a different ?lang= re-stamps it.

string
Examples
ExampleActiveComparisonShareLink

Active comparison share link

{
"token": "mB4t7w1zR6qXs9cV2kJfHdA8",
"url": "/r/c/mB4t7w1zR6qXs9cV2kJfHdA8",
"expires_at": "2027-03-15T10:22:00Z",
"locale": "en"
}
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
Examples
Example400—BadIds

Fewer than 2 / more than 4 / duplicate session ids

{
"ids": [
"Pass 2-4 distinct session ids."
]
}
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
Examplegenerated
{
"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
Examples
Example404—NoSuchSessionOnThisTeam

Absent, or owned by another team (collapsed to 404)

{
"detail": "session_not_found"
}
Media typeapplication/json
object
detail
required

409 — the request conflicts with current state. detail is a stable code (e.g. reanalyze_in_flight, already_on_plan, email_in_use). Some 409s carry extra context fields alongside detail; those are documented on the specific endpoint that emits them.

string
Examples
Example409—SessionAnalysisNotComplete

PDF / Share rejected while the session is still pending or processing

{
"detail": "session_not_completed"
}