Challenge Plays API
GET /api/challenge-plays
List all challenge plays for the authenticated client/user, with support for pagination, filtering, and sorting.
Query Parameters
clientId: string (required) — The client identifier. If not found, a 500 error is returned.page: number (optional, default: 1) — The page number (1-based).pageSize: number (optional, default: 20, max: 100) — Number of results per page.sortBy: string (optional, default:createdAt) — Field to sort by (e.g.,createdAt).sortOrder: string (optional, default:desc) — Sort order:ascordesc.userId: string (optional) — Filter by user ID.challengeId: string (optional) — Filter by challenge ID.startAfter: any (optional) — Cursor value for pagination (use the value of thesortByfield from the last item of the previous page).
Headers:
Authorization: Bearer <JWT>
Response
-
200 OK:Success Response{
"data": [ChallengePlay, ...],
"page": number,
"pageSize": number,
"hasMore": boolean,
"nextPageToken": any
} -
401 Unauthorized:{ "error": string } -
500 Internal Server Error:{ "error": "Client ID not found" | string } -
500 Firestore index required:{ "error": "Firestore index required", "details": string }
Use nextPageToken as the startAfter value for the next page request.
Filtering and sorting combinations may require Firestore composite indexes. If an index is missing, the error response will include a link to create it.
POST /api/challenge-plays
Create a new challenge play record for a user or guest.
Authenticated B2B API requests to create challenge-play activity records are part of GOFA's billable usage direction. Low-cost list and read traffic may remain primarily rate-limited, while successful activity-creation and activity-completion actions are the main candidates for credit consumption as the commercial API platform expands. This note does not change the current request or response contract for existing integrations.
Depending on the client's configured commercial policy, this endpoint can reject a request before creation when request-rate, quota, or available-credit limits are exceeded. Successful requests may consume credits according to the client's active commercial setup.
Query Parameters
clientId: string (required) — The client identifier. If not found, a 500 error is returned.
Headers:
Authorization: Bearer <JWT>
Request Body:
{
"challengeId": "string", // Required. The challenge ID
"userId": "string", // Optional. User's ID
"email": "string", // Optional. User's email
"displayName": "string", // Optional. User's display name
"photoURL": "string", // Optional. User's profile photo URL
"targetRepCount": 50, // Optional. Target repetitions
"targetDuration": 60 // Optional. Target duration (seconds)
}
Response
-
200 OK:Success Response{
"challengePlayId": "string", // Unique ID for the challenge play
"redirectUrl": "string", // URL to redirect the user to the challenge play
"createdAt": "string" // ISO date of creation
} -
400 Bad Request:{ "error": "string" } -
429 Too Many Requests:{ "error": string, "code": "api_rate_limited" | "api_quota_exceeded" | "api_balance_exhausted", "retryAfterSeconds": number | null } -
500 Internal Server Error:{ "error": "string" }
ChallengePlay Object (for reference)
id: string — Unique challenge play IDclientId: string — Client IDuserId: string (optional) — User IDchallengeId: string — Challenge IDcreatedAt: string — ISO datecompletedAt: string (optional, nullable) — ISO dateactivityTime: number (optional) — Seconds spent in activityrepCount: number (optional) — Number of reps completedgrade: string (optional) — Grade achievedtargetRepCount: number (optional) — Target reps (Time Attack)targetDuration: number (optional) — Target duration in seconds (Endurance)caloriesBurned: number (optional)email: string (optional)displayName: string (optional)photoURL: string (optional)status: string (optional) —pending,started,completed,cancelled
{
"id": "play123",
"clientId": "gofa",
"userId": "user456",
"challengeId": "challenge123",
"createdAt": "2024-05-25T10:00:00.000Z",
"completedAt": null,
"activityTime": 60,
"repCount": 50,
"grade": "S",
"targetRepCount": 50,
"targetDuration": 60,
"caloriesBurned": 25,
"email": "user@example.com",
"displayName": "User Name",
"photoURL": "https://example.com/photo.jpg",
"status": "completed"
}
Requires a valid JWT for the client.
Validates challenge and user existence.
The actual schema may include additional fields. For the most up-to-date schema, refer to the challenge play model/interface in your codebase.
All fields may not be present on every challenge play. Optional and nullable fields are indicated above.