curl -X GET "https://api.fitsociety.io/public/v1/workout/clients/{clientId}/plans/template/{templateId}/day/{planMomentId}/workout" \
-H "Authorization: Bearer <access_token>"const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.fitsociety.io/public/v1/workout/clients/{clientId}/plans/template/{templateId}/day/{planMomentId}/workout', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.fitsociety.io/public/v1/workout/clients/{clientId}/plans/template/{templateId}/day/{planMomentId}/workout"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)Get the day workout-execution screen
The day execution screen reached by tapping a day on the day-progress page. Keyed by the assigned plan (templateId) + the day (planMomentId) — NOT a sessionId, since the session may not exist yet or may be an unfinished one needing a Resume prompt.
Resolves the relevant session (active in_progress/paused if any, else the most-recent completed) and returns:
Stopped and cancelled attempts are excluded from current/resumable selection; when only such attempts exist session is null and resumeState is create. Their performances are not mapped as current exercise progress.
-
resumeState:create(no session) |start(active, nothing logged) |continue(active with logged work) |completed. -
requiresResumePrompt: true only forcontinue. -
requiresConfirmation/confirmationToken/confirmationTokenExpiresAt: a pending resume/restart handshake token (surfaced, not issued — seePOST /performance/sessions/start). Pass it back withresumeAction: continue|restart. -
day.progress: cross-session completion (same basis as the day-progress page). -
exercises[]: ONE ordered array — standalone exercises are{ type: "exercise", …, data: [] }; a superset is{ type: "superset", …, data: [member items] }at its first member’s position. -
Per-set
sets(plan exercises withperSetTrackingEnabled): the coach’s prescribed rows are prefilled ONLY for a not-yet-logged exercise. Once the client has logged,setsreflects exactly their saved rows — deleted sets persist and are NOT re-padded back to the prescribed set count on refresh.hasHistoryincludes saved sets from a displayed completed session, while Previous excludes the displayed session. Both require a non-deleted completed parent session; their eligibility rules remain distinct when sharing history reads. -
Per-set placeholders. Every
sets[]row carries twelve extra fields:repsPlaceholderCoach,weightPlaceholderCoach,timeSecondsPlaceholderCoach,distanceMetersPlaceholderCoach,rpePlaceholderCoach,restSecondsPlaceholderCoach, and the same six without theCoachsuffix. A placeholder is the greyed hint an EMPTY input shows. ·*PlaceholderCoachis the coach’s prescription for that set index (WorkoutPlansetsData).nullfor a metric this exercise type does not track (atimeexercise has no reps hint), for a set beyond the prescribed count, for a metric the coach left blank, and for freestyle, which has no prescription at all. ·*Placeholderis the hint to actually show. The coach wins: it is the*PlaceholderCoachvalue whenever there is one, and falls back to the client’s own stored placeholder only where the coach prescribed nothing. So it is identical to*PlaceholderCoachon any prescribed set, and always reflects the CURRENT prescription — a coach editing 8 reps to 12 changes the hint immediately, with no stale client copy able to outlive it. · The client’s stored placeholder (sent per set onPUT /app/v1/workout/performance/sessions/{sessionId}/exercises/{exerciseId}) is therefore a FALLBACK for sets the coach never prescribed, not an override. Send one only where*PlaceholderCoachisnull; sending it elsewhere is accepted but ignored. · Placeholders are never logged work — excluded from every total, volume, PR and completion check — so a hint left showing after a value is cleared does not make the set count. They are emitted on logged rows too, because clearing a logged value is exactly when the hint has to reappear. · Committing a hint. When the athlete marks a set completed without typing, send the shown NUMERIC hint as the real value ({ reps: 22, completed: true }); it then counts as their performance. A RANGE hint ("8-12") must NOT be submitted on a completed set — the client should prompt the athlete to enter a value and skip the call, because a range reaching a completed set is stored as its MINIMUM ("12-24"→ 12 reps, 120 volume), silently under-crediting them. An unticked set sends its metric asnullwithcompleted: falseand simply keeps showing the hint.
Requires the workout_client_plans:read scope. This operation maps to /app/v1/workout/plans/client/template/:templateId/day/:planMomentId/workout and retains its Workout V2 permission, feature-flag, and resource-scope checks.
The clientId path parameter identifies the client represented by the request context.
curl -X GET "https://api.fitsociety.io/public/v1/workout/clients/{clientId}/plans/template/{templateId}/day/{planMomentId}/workout" \
-H "Authorization: Bearer <access_token>"const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.fitsociety.io/public/v1/workout/clients/{clientId}/plans/template/{templateId}/day/{planMomentId}/workout', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.fitsociety.io/public/v1/workout/clients/{clientId}/plans/template/{templateId}/day/{planMomentId}/workout"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)Authorizations
Public API access token issued by /public/v1/oauth/token. Example: Authorization: Bearer fspt_.... Each resource request rechecks the token company's current provider access. Disabling access blocks existing tokens with 403 auth.provider_unavailable.
Path Parameters
Assigned workout plan id.
"67f1234567890abcdef1234"
Plan moment (day) id.
"67f1234567890abcdef1234"
Client in the company bound to the Public API token.
^[a-fA-F0-9]{24}$Query Parameters
Only for coach/admin callers; clients resolve from the token.
"67f1234567890abcdef1234"
Calendar schedule item id. Must be supplied together with plannedDate; omit both for legacy plan-moment behavior.
"67f1234567890abcdef1234"
Exact company-local occurrence date. Must be supplied together with programmeScheduleItemId.
^\d{4}-\d{2}-\d{2}$"2026-09-08"