Skip to main content

AI Move API

AI Move provides authenticated client-facing exercise and session APIs used by GOFA mobile and web experiences.

Authentication

Use a Firebase user token in the Authorization: Bearer <firebase_jwt> header.

note

The AI Move module must be enabled for your client. The visible exercise catalog is tenant-aware — end users only receive exercises that are currently available to their client.

Exercises

GET /api/ai-move/exercises

Returns the exercises visible to the current client.

  • For the GOFA tenant: returns enabled GOFA library exercises ordered by the library default order.
  • For other clients: returns the client's enabled custom exercises plus the GOFA library exercises currently selected for that client.
Response
{
"exercises": [
{
"exerciseId": "squat-basic",
"clientId": "gofa",
"name": "Basic Squat",
"type": "rep",
"targetValue": 10,
"category": "strength",
"difficulty": "beginner",
"enabled": true,
"sortOrder": 10
}
]
}

GET /api/ai-move/exercises/[exerciseId]

Returns a single exercise with full algorithm data if that exercise is visible to the current client.

  • A GOFA library exercise is only returned when it is currently enabled and included in the requesting client's catalog.
  • A client custom exercise is returned when it belongs to the current client and is enabled.
Response
{
"exercise": {
"exerciseId": "squat-basic",
"clientId": "gofa",
"name": "Basic Squat",
"nameZh": "基礎深蹲",
"description": "Lower into a squat and return to standing.",
"category": "strength",
"difficulty": "beginner",
"imageUrl": "/assets/ai-move/squat-basic.webp",
"type": "rep",
"targetValue": 10,
"estimatedCalories": 8,
"algorithm": {
"mode": "rule"
},
"enabled": true,
"sortOrder": 10
}
}

Error Responses:

StatusDescription
404Exercise not found

Sessions

POST /api/ai-move/sessions

Create a new exercise session for the authenticated user.

Request Body:

FieldTypeRequiredDescription
exerciseIdstringYesThe exercise to perform
exerciseType"rep" | "timer"YesExercise mode
targetRepsnumberNoTarget rep count (min: 1, for rep type)
targetDurationSecondsnumberNoTarget duration in seconds (min: 1, for timer type)
Request
{
"exerciseId": "squat-basic",
"exerciseType": "rep",
"targetReps": 10
}
Response (201)
{
"sessionId": "abc123",
"clientId": "gofa",
"userId": "user-001",
"exerciseId": "squat-basic",
"exerciseType": "rep",
"targetReps": 10,
"repsCompleted": 0,
"durationSeconds": 0,
"caloriesBurned": 0,
"poseAccuracy": 0,
"formScore": null,
"holdTimeSeconds": 0,
"retryCountRemaining": null,
"retryCountUsed": 0,
"failureReason": null,
"formViolations": [],
"completionOutcome": null,
"status": "created",
"createdAt": "2026-03-17T10:00:00Z",
"completedAt": null
}

GET /api/ai-move/sessions

List sessions for the authenticated user.

Query Parameters:

ParameterTypeDefaultDescription
limitnumber20Max results per page (max: 100)
startAfterstringSession ID for cursor-based pagination
Response
{
"sessions": [
{
"sessionId": "abc123",
"exerciseId": "squat-basic",
"exerciseType": "rep",
"status": "completed",
"repsCompleted": 10,
"durationSeconds": 45,
"caloriesBurned": 8,
"poseAccuracy": 0.92,
"formScore": 0.88,
"createdAt": "2026-03-17T10:00:00Z",
"completedAt": "2026-03-17T10:01:00Z"
}
]
}

GET /api/ai-move/sessions/[sessionId]

Fetch detailed data for a specific session. The authenticated user must own the session.

Response
{
"session": {
"sessionId": "abc123",
"clientId": "gofa",
"userId": "user-001",
"exerciseId": "squat-basic",
"exerciseType": "rep",
"targetReps": 10,
"repsCompleted": 10,
"durationSeconds": 45,
"caloriesBurned": 8,
"poseAccuracy": 0.92,
"formScore": 0.88,
"holdTimeSeconds": 0,
"retryCountUsed": 0,
"formViolations": [],
"completionOutcome": "success",
"status": "completed",
"createdAt": "2026-03-17T10:00:00Z",
"completedAt": "2026-03-17T10:01:00Z"
}
}

Error Responses:

StatusDescription
403User does not own this session
404Session not found

PATCH /api/ai-move/sessions/[sessionId]

Update a session with exercise results. The authenticated user must own the session.

Request Body (all fields optional):

FieldTypeDescription
status"created" | "in-progress" | "completed" | "failed" | "abandoned"Session status
completionOutcome"success" | "failed"Final outcome
repsCompletednumberReps completed (min: 0)
durationSecondsnumberDuration in seconds (min: 0)
caloriesBurnednumberCalories burned (min: 0)
poseAccuracynumberPose accuracy score (0–1)
formScorenumberForm quality score (0–1)
holdTimeSecondsnumberTotal hold time (min: 0)
retryCountRemainingnumberRetries remaining (min: 0)
retryCountUsednumberRetries used (min: 0)
failureReasonstringReason for failure
formViolationsarrayForm violation records (see below)

Form Violation Record:

FieldTypeDescription
keystringViolation identifier
labelstringDisplay label
labelZhstringChinese display label (optional)
weightnumberScoring weight
totalChecksnumberTotal times checked
violationCountnumberTimes violated
violationRatenumberViolation rate
Request
{
"status": "completed",
"completionOutcome": "success",
"repsCompleted": 10,
"durationSeconds": 45,
"caloriesBurned": 8,
"poseAccuracy": 0.92,
"formScore": 0.88
}
Response
{
"success": true
}
note

When a session is marked as "completed", the user's aggregate exercise statistics are automatically updated.

Error Responses:

StatusDescription
403User does not own this session
404Session not found

Admin Records

GET /api/ai-move/records

Admin-only endpoint to list AI Move session records for a client. Requires admin authentication.

Query Parameters:

ParameterTypeDefaultDescription
clientIdstringTarget client ID (admin can query other clients)
limitnumber50Max results (1–500)
Response
{
"data": [
{
"id": "session-001",
"clientId": "gofa",
"userId": "user-001",
"exerciseId": "squat-basic",
"exerciseType": "rep",
"status": "completed",
"repsCompleted": 10,
"durationSeconds": 45,
"caloriesBurned": 8,
"createdAt": "2026-03-17T10:00:00.000Z",
"completedAt": "2026-03-17T10:01:00.000Z"
}
],
"count": 1
}

Error Responses:

StatusDescription
401Unauthorized — admin authentication required
403AI Move module not enabled for this client
500Internal server error
note

Results are ordered by createdAt descending. The AI Move module must be enabled for the target client.

Notes

  • AI Move catalog-management endpoints are intentionally not documented on this public site.
  • Client administrators configure library selection and ordering through GOFA-managed admin experiences.