Authenticated plans, routine queues, and routine runs for user-facing training integrations.
AI Training provides plan-based routine APIs for authenticated end users. It owns the user's plan, routine queue, and routine-run summary. AI Move remains the exercise execution surface for individual exercise steps.
Send a Firebase ID token in the Authorization header for end-user routes:
Authorization: Bearer <firebase-id-token>The AI Training module must be available for the client. Client identity comes from the request hostname, and each user can access only their own plan, queue, and runs.
An application that already has a valid Firebase session can exchange its ID
token for a Firebase custom token through
POST /api/auth/exchange-token:
Authorization: Bearer <firebase-id-token>The request has no body and returns:
{
"customToken": "<firebase-custom-token>"
}Pass that value only as the customToken query parameter when opening the AI
Training play page:
https://{client}.gofa.app/ai-training/routine-run/{routineRunId}/play?customToken={token}&locale=zh-HantThe GOFA web application consumes the custom token to establish a browser session. It is not a bearer token for API requests. Keep both token types out of logs, URLs that may be retained, and browser source code after the handoff.
/api/ai-training/my-planReturns the latest plan for the authenticated user. A user without a plan
receives {"plan": null}.
{
"plan": {
"planId": "plan_001",
"clientId": "gofa",
"userId": "user_001",
"status": "active",
"goal": "balance",
"intensity": "moderate",
"frequency": 3,
"preferredSessionDurationMinutes": 20,
"equipmentAvailability": [],
"generationSource": "rules",
"assessmentSnapshot": {
"latestRiskTier": "moderate",
"availableInputs": ["fallRisk", "preferences"],
"missingInputs": ["mskAssessment", "cognitiveAssessment"]
}
}
}/api/ai-training/my-plan/generateGenerates a starter plan from routine templates visible to the client and
returns the plan and created routine instances with status 201.
All request fields are optional. Unknown fields are rejected.
| Field | Type | Description |
|---|---|---|
goal | "mobility" | "strength" | "balance" | "endurance" | "fall-prevention" | "general-fitness" | Preferred training goal. |
intensity | "low" | "moderate" | "high" | Preferred training intensity. |
frequency | integer 1–14 | Desired sessions per cycle. |
preferredSessionDurationMinutes | integer 5–180 | Preferred session duration. |
equipmentAvailability | string[] | Available equipment labels. |
allowPreferencesOnlyFallback | boolean | Allow generation from preferences when assessment inputs are unavailable. |
allowDuplicateRoutineTemplates | boolean | Opt in to repeated routine templates in generated instances. |
{
"goal": "balance",
"intensity": "moderate",
"frequency": 3,
"preferredSessionDurationMinutes": 20,
"equipmentAvailability": ["chair"]
}{
"plan": {
"planId": "plan_001",
"status": "active",
"goal": "balance",
"intensity": "moderate",
"frequency": 3
},
"routineInstances": [
{
"routineInstanceId": "instance_001",
"planId": "plan_001",
"routineTemplateId": "template_001",
"routineTemplateName": "Balance Builder A",
"queueIndex": 0,
"status": "queued",
"blocks": []
}
]
}The returned routine instances can contain exercise blocks and normalized image/video URLs used by the play experience.
/api/ai-training/my-routine-queueReturns the queued or in-progress routine instances for the authenticated user
inside a routineInstances property.
The optional allowDuplicateRoutineTemplates query parameter accepts true
or 1. It defaults to false, so duplicate routine-template instances are
hidden from the queue response unless the caller opts in.
{
"routineInstances": [
{
"routineInstanceId": "instance_001",
"routineTemplateId": "template_001",
"status": "queued",
"queueIndex": 0,
"deferCount": 0,
"maxDefers": 2,
"blocks": []
}
]
}/api/ai-training/routine-runsCreates a routine run for one queued routine instance.
| Field | Type | Required | Description |
|---|---|---|---|
routineInstanceId | string | Yes | Queued routine instance to start. |
startedFrom | "dashboard" | "next-plan-card" | "history" | "manual-selection" | "other" | Yes | User-facing entry point label. |
status | routine-run status | No | Optional initial status. |
{
"routineInstanceId": "instance_001",
"startedFrom": "dashboard"
}{
"routineRun": {
"routineRunId": "run_001",
"routineInstanceId": "instance_001",
"planId": "plan_001",
"clientId": "gofa",
"userId": "user_001",
"status": "created",
"startedFrom": "dashboard",
"summary": {
"completedExercises": 0,
"totalExercises": 4,
"completionRate": 0,
"totalDurationSeconds": 0,
"totalCaloriesBurned": 0
},
"exerciseSteps": [
{
"sequenceIndex": 0,
"stepId": "step_001",
"exerciseId": "march-basic",
"status": "pending"
}
]
}
}Routine-run statuses are created, in-progress, completed, partial,
failed, and abandoned.
/api/ai-training/routine-runsLists the authenticated user's routine runs:
{
"routineRuns": []
}/api/ai-training/routine-runs/[routineRunId]Returns one routine run owned by the authenticated user:
{
"routineRun": {
"routineRunId": "run_001",
"routineInstanceId": "instance_001",
"status": "in-progress",
"startedFrom": "dashboard",
"summary": {
"completedExercises": 1,
"totalExercises": 4,
"completionRate": 0.25,
"totalDurationSeconds": 120,
"totalCaloriesBurned": 12
},
"exerciseSteps": []
}
}/api/ai-training/routine-runs/[routineRunId]Updates a routine run owned by the authenticated user. The body is validated against the routine-run update schema; it can contain supported run status, timestamps, execution context, summary, and exercise-step updates. The successful response is:
{
"success": true
}/api/ai-training/routine-runs/[routineRunId]/syncSynchronizes a routine-run summary from an AI Move child session or a guided step. All fields are optional, but unknown fields are rejected.
| Field | Type | Description |
|---|---|---|
aiMoveSessionId | string | Child AI Move session to sync. |
sequenceIndex | integer | Step index, minimum 0. |
guidedComplete | boolean | Mark a guided step complete. |
executionMode | "guided" | "post-analysis" | "live-tracking" | How the step was executed. |
completionBasis | "elapsed" | "user-confirmed" | "algorithm" | Why completion was recorded. |
durationSeconds | number | Step duration, minimum 0. |
skipped | boolean | Mark a step skipped. |
skipReason | "guest-skipped-after-stall" | Requires skipped: true. |
abandonRemaining | boolean | Abandon remaining steps when supported by the run. |
{
"success": true,
"routineRun": {
"routineRunId": "run_001",
"status": "in-progress"
}
}/api/ai-training/routine-instances/[routineInstanceId]/deferDefers a queued routine instance for the authenticated user, subject to the instance's configured defer limit.
{
"success": true
}/api/ai-training/progress-reportReturns a lightweight adherence summary for the authenticated user.
{
"adherence": 0.67,
"totalRuns": 6,
"completedRuns": 4,
"completionRate": 0.67,
"series": [
{
"label": "Mar 27",
"completedRuns": 1,
"totalRuns": 2,
"completionRate": 0.5
}
]
}AI Training starts an AI Move session for each exercise step and can pass plan, routine, run, and sequence context to the AI Move session route. The routine sync route then summarizes the child session without changing the ownership boundary of the individual AI Move session.
This page covers the user runtime and the Firebase custom-token handoff. Admin assignment, reporting, routine-template authoring, catalog management, and physical-playtest routes are outside this external reference.