> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fitsociety.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Start or resume a multi-client coach group workout

> Starts or resumes only the participants submitted in the request body. For calendar events, a valid booking grants training access within that lesson regardless of the participant's home location, provided the coach can access the lesson location. Unselected booked clients are not started automatically. Manual workouts and unbooked additions retain normal member access.

Requires the workout_groups:write scope. This operation maps to /app/v1/coach/workout/group/start and retains its Workout V2 permission, feature-flag, and resource-scope checks.

The clientId path parameter is resolved inside the company bound to the Public API token when present.



## OpenAPI

````yaml /openapi/public-v1.json post /public/v1/workout/groups/start
openapi: 3.1.0
info:
  title: FITsociety Public API v1
  version: 1.0.0
  description: >-
    Developer Public API endpoints under `/public/v1`. This reference is
    filtered to OAuth/Bearer Public API resources and excludes provider callback
    receivers, storefront routes, public widgets, wishlist routes, and
    access-device validation endpoints.
  contact:
    name: FITsociety Engineering
servers:
  - url: https://api.fitsociety.io
    description: Production
security: []
tags:
  - name: Workout
    description: >-
      Workout V2 libraries, programmes, client plans, calendars, sessions,
      groups, settings and progress. AI operations are excluded.
  - name: OAuth
    description: Public API OAuth endpoints for server-to-server client credentials.
  - name: Health
    description: Public API token health checks.
  - name: Platform
    description: >-
      Inspect Public API client context, capabilities, scopes, and redacted
      audit logs.
  - name: Company Catalog
    description: Read and manage company profile metadata and locations.
  - name: Clients
    description: >-
      Create and manage clients through the Public API using Bearer access
      tokens.
  - name: Coaches
    description: Retrieve coaches for the authenticated company via integrations.
  - name: Calendar Events
    description: Read Public API calendar events.
  - name: Calendar Templates
    description: >-
      Read and manage event types and event templates used by calendar
      availability and bookings.
  - name: Calendar Extensions
    description: >-
      Read recurring bookings, booking requests, calendar tasks, and
      availability closure metadata.
  - name: Availability
    description: Read bookable availability slots and signed availability tokens.
  - name: Availability Management
    description: >-
      Manage coach and location availability templates used to derive bookable
      slots.
  - name: Bookings
    description: Read and manage Public API bookings.
  - name: Finance
    description: >-
      Read invoices, transactions, products, subscriptions, and memberships with
      guarded finance writes.
  - name: Credits
    description: >-
      Read company-wide and client-scoped credit allocations, mutations, and
      guarded credit adjustments.
  - name: Exports
    description: >-
      Create and monitor asynchronous company exports through Public API Bearer
      endpoints.
  - name: Webhooks
    description: >-
      Manage outbound webhook subscriptions and inspect delivery attempts
      through Public API Bearer endpoints.
  - name: Measurements
    description: Read and write client measurement entries.
  - name: Progress Photos
    description: Read client progress photo metadata and short-lived signed media URLs.
  - name: Forms
    description: Read, create, update, and archive company form templates.
  - name: Intakes
    description: Assign intake forms and read client intake assignments and submissions.
  - name: Check-ups
    description: >-
      Schedule and cancel client check-ups and read their status and
      submissions.
  - name: Documents
    description: >-
      Read client document and folder metadata, register external document
      links, update metadata, and archive documents from Public API listings.
      Binary upload, permanent deletion, and company-wide document management
      are not exposed.
  - name: Habits
    description: Read habits and habit entries.
  - name: Goals
    description: Read client goal summaries.
  - name: Conversations
    description: >-
      Read and manage direct and group chat conversations through the Public
      API.
  - name: Reports
    description: Read aggregate attendance, revenue, and retention summaries.
paths:
  /public/v1/workout/groups/start:
    post:
      tags:
        - Workout
      summary: Start or resume a multi-client coach group workout
      description: >-
        Starts or resumes only the participants submitted in the request body.
        For calendar events, a valid booking grants training access within that
        lesson regardless of the participant's home location, provided the coach
        can access the lesson location. Unselected booked clients are not
        started automatically. Manual workouts and unbooked additions retain
        normal member access.


        Requires the workout_groups:write scope. This operation maps to
        /app/v1/coach/workout/group/start and retains its Workout V2 permission,
        feature-flag, and resource-scope checks.


        The clientId path parameter is resolved inside the company bound to the
        Public API token when present.
      operationId: publicWorkoutpostPublicV1WorkoutGroupsStart
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 1
            maxLength: 200
            example: booking-create-20260714-001
          description: >-
            Required for Public API write requests. Reusing the same key with
            the same method, path, and body replays the stored successful
            response; reusing it with a different request returns `409
            idempotency.conflict`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: >-
                #/components/schemas/PublicWorkoutSourcePOSTAppV1CoachWorkoutGroupStartRequest
      responses:
        '200':
          description: Per-participant start/resume results.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/PublicApiWriteSuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: >-
                          #/components/schemas/PublicWorkoutSourcePOSTAppV1CoachWorkoutGroupStartResponse200
              examples:
                success:
                  summary: Successful response
                  value:
                    data:
                      run:
                        runId: 67f1234567890abcdef1234
                        source: calendar_event
                        status: active
                        calendarEventId: null
                        manualSessionKey: small-group-2026-06-04-09
                        startedAt: null
                        endedAt: null
                      results:
                        - clientId: 67f1234567890abcdef1234
                          ok: true
                          sessionId: null
                          sessionStatus: planned
                          workoutSource: auto_assigned_plan
                          sourceLabel: Full Body - Day 2
                          templateId: null
                          errorCode: ''
                          requiresConfirmation: false
                          confirmationToken: null
                          confirmationTokenExpiresAt: null
                          timerStartedAt: null
                          timerPausedAt: null
                          timerElapsedMs: 90000
                          runTimer:
                            timerStartedAt: null
                            timerPausedAt: null
                            timerElapsedMs: 300000
                      counts:
                        total: 2
                        started: 1
                        pendingConfirmation: 1
                        failed: 0
                    meta:
                      requestId: 4f849d7d-f4f1-45cc-b4b7-3984a3d17f83
                      rateLimit:
                        limit: 10
                        remaining: 9
                        resetSeconds: 1
                      idempotency:
                        replayed: false
        '400':
          description: Invalid source, manual key, clients, or workout source.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
              examples:
                invalidRequest:
                  summary: Invalid request
                  value:
                    error:
                      code: 400
                      key: request.invalid
                      message: The request is invalid.
                    meta:
                      requestId: 4f849d7d-f4f1-45cc-b4b7-3984a3d17f83
                      rateLimit:
                        limit: 10
                        remaining: 9
                        resetSeconds: 1
                idempotencyRequired:
                  summary: Missing Idempotency-Key
                  value:
                    error:
                      code: 400
                      key: idempotency.required
                      message: >-
                        Idempotency-Key header is required for Public API write
                        requests.
                    meta:
                      requestId: 4f849d7d-f4f1-45cc-b4b7-3984a3d17f83
                      rateLimit:
                        limit: 10
                        remaining: 9
                        resetSeconds: 1
                idempotencyInvalid:
                  summary: Invalid Idempotency-Key
                  value:
                    error:
                      code: 400
                      key: idempotency.invalid
                      message: Idempotency-Key header must be 200 characters or fewer.
                    meta:
                      requestId: 4f849d7d-f4f1-45cc-b4b7-3984a3d17f83
                      rateLimit:
                        limit: 10
                        remaining: 9
                        resetSeconds: 1
        '401':
          $ref: '#/components/schemas/ErrorResponse'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
              examples:
                missingBearer:
                  summary: Missing Bearer token
                  value:
                    error:
                      code: 401
                      key: auth.missing_bearer
                      message: Authorization Bearer token is required.
                    meta:
                      requestId: 4f849d7d-f4f1-45cc-b4b7-3984a3d17f83
                      rateLimit:
                        limit: 10
                        remaining: 9
                        resetSeconds: 1
                invalidToken:
                  summary: Invalid or expired token
                  value:
                    error:
                      code: 401
                      key: auth.invalid_token
                      message: The access token is invalid or expired.
                    meta:
                      requestId: 4f849d7d-f4f1-45cc-b4b7-3984a3d17f83
                      rateLimit:
                        limit: 10
                        remaining: 9
                        resetSeconds: 1
                invalidClient:
                  summary: Inactive or revoked client
                  value:
                    error:
                      code: 401
                      key: auth.invalid_client
                      message: The Public API client is inactive or revoked.
                    meta:
                      requestId: 4f849d7d-f4f1-45cc-b4b7-3984a3d17f83
                      rateLimit:
                        limit: 10
                        remaining: 9
                        resetSeconds: 1
        '403':
          description: Coach, company, event, or client access denied.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
              examples:
                insufficientScopes:
                  summary: Missing required scope
                  value:
                    error:
                      code: 403
                      key: scopes.insufficient
                      message: The access token does not include the required scope.
                      details:
                        requiredScopes:
                          - required:scope
                    meta:
                      requestId: 4f849d7d-f4f1-45cc-b4b7-3984a3d17f83
                      rateLimit:
                        limit: 10
                        remaining: 9
                        resetSeconds: 1
        '404':
          description: Calendar event, workout plan, or plan moment not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
              examples:
                notFound:
                  summary: Resource not found
                  value:
                    error:
                      code: 404
                      key: resource.not_found
                      message: The requested Public API resource was not found.
                    meta:
                      requestId: 4f849d7d-f4f1-45cc-b4b7-3984a3d17f83
                      rateLimit:
                        limit: 10
                        remaining: 9
                        resetSeconds: 1
        '409':
          description: >-
            Conflict key: `PROGRAMME_WEEK_NOT_AVAILABLE`. Locked programme weeks
            are rejected before a group run or session is persisted.
            Confirmation is represented by `requiresConfirmation` in the 200
            participant result; participant start failures remain
            per-participant results or make an empty new run return 400.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
              examples:
                idempotencyConflict:
                  summary: Idempotency-Key conflict
                  value:
                    error:
                      code: 409
                      key: idempotency.conflict
                      message: >-
                        Idempotency-Key was already used with a different
                        request.
                    meta:
                      requestId: 4f849d7d-f4f1-45cc-b4b7-3984a3d17f83
                      rateLimit:
                        limit: 10
                        remaining: 9
                        resetSeconds: 1
                idempotencyInProgress:
                  summary: Idempotency-Key in progress
                  value:
                    error:
                      code: 409
                      key: idempotency.in_progress
                      message: >-
                        Idempotency-Key is already processing for this Public
                        API client.
                    meta:
                      requestId: 4f849d7d-f4f1-45cc-b4b7-3984a3d17f83
                      rateLimit:
                        limit: 10
                        remaining: 9
                        resetSeconds: 1
        '422':
          $ref: '#/components/schemas/ErrorResponse'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
              examples:
                emptyBody:
                  summary: Empty or invalid JSON object body
                  value:
                    error:
                      code: 422
                      key: EMPTY_BODY
                      message: Request body must be a non-empty JSON object.
                    meta:
                      requestId: 4f849d7d-f4f1-45cc-b4b7-3984a3d17f83
                      rateLimit:
                        limit: 10
                        remaining: 9
                        resetSeconds: 1
        '429':
          $ref: '#/components/schemas/ErrorResponse'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
              examples:
                rateLimitExceeded:
                  summary: Rate limit exceeded
                  value:
                    error:
                      code: 429
                      key: rate_limit.exceeded
                      message: Too many Public API requests. Retry later.
                    meta:
                      requestId: 4f849d7d-f4f1-45cc-b4b7-3984a3d17f83
                      rateLimit:
                        limit: 10
                        remaining: 0
                        resetSeconds: 1
                        retryAfterSeconds: 1
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiError'
              examples:
                serverInternalError:
                  summary: Unexpected server error
                  value:
                    error:
                      code: 500
                      key: server.internal_error
                      message: An unexpected Public API server error occurred.
                    meta:
                      requestId: 4f849d7d-f4f1-45cc-b4b7-3984a3d17f83
                      rateLimit:
                        limit: 10
                        remaining: 9
                        resetSeconds: 1
      security:
        - PublicBearerAuth: []
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: >-
            curl -X POST
            "https://api.fitsociety.io/public/v1/workout/groups/start" \
              -H "Authorization: Bearer <access_token>" \
              -H "Idempotency-Key: <stable_request_key>" \
              -H "Content-Type: application/json" \
              -d '{}'
components:
  schemas:
    PublicWorkoutSourcePOSTAppV1CoachWorkoutGroupStartRequest:
      $ref: '#/components/schemas/PublicWorkoutSourceCoachGroupWorkoutStartPayload'
    PublicApiWriteSuccessResponse:
      type: object
      additionalProperties: false
      required:
        - data
        - meta
      properties:
        data:
          type: object
        meta:
          $ref: '#/components/schemas/PublicApiWriteMeta'
    PublicWorkoutSourcePOSTAppV1CoachWorkoutGroupStartResponse200:
      type: object
      properties:
        run:
          type: object
          properties:
            runId:
              type: string
              example: 67f1234567890abcdef1234
            source:
              type: string
              enum:
                - calendar_event
                - manual
            status:
              type: string
              enum:
                - active
                - completed
                - cancelled
            calendarEventId:
              type:
                - string
                - 'null'
              example: null
            manualSessionKey:
              type: string
              example: small-group-2026-06-04-09
            startedAt:
              type:
                - string
                - 'null'
              format: date-time
              example: null
            endedAt:
              type:
                - string
                - 'null'
              format: date-time
              example: null
        results:
          type: array
          items:
            type: object
            properties:
              clientId:
                type: string
                example: 67f1234567890abcdef1234
              ok:
                type: boolean
                example: true
              sessionId:
                type:
                  - string
                  - 'null'
                example: null
              sessionStatus:
                type: string
                enum:
                  - planned
                  - in_progress
                  - paused
                  - completed
                  - stopped
                  - cancelled
              workoutSource:
                type: string
                example: auto_assigned_plan
              sourceLabel:
                type: string
                example: Full Body - Day 2
              templateId:
                type:
                  - string
                  - 'null'
                example: null
              errorCode:
                type: string
                example: ''
              requiresConfirmation:
                type: boolean
                example: false
              confirmationToken:
                type:
                  - string
                  - 'null'
                example: null
              confirmationTokenExpiresAt:
                type:
                  - string
                  - 'null'
                format: date-time
                example: null
              timerStartedAt:
                type:
                  - string
                  - 'null'
                format: date-time
                example: null
              timerPausedAt:
                type:
                  - string
                  - 'null'
                format: date-time
                example: null
              timerElapsedMs:
                type: number
                example: 90000
              runTimer:
                type: object
                description: >-
                  Current central group-run timer after the participant status
                  change.
                properties:
                  timerStartedAt:
                    type:
                      - string
                      - 'null'
                    format: date-time
                    example: null
                  timerPausedAt:
                    type:
                      - string
                      - 'null'
                    format: date-time
                    example: null
                  timerElapsedMs:
                    type: number
                    example: 300000
        counts:
          type: object
          properties:
            total:
              type: number
              example: 2
            started:
              type: number
              example: 1
            pendingConfirmation:
              type: number
              example: 1
            failed:
              type: number
              example: 0
    PublicApiError:
      type: object
      additionalProperties: false
      required:
        - error
        - meta
      properties:
        error:
          type: object
          additionalProperties: false
          required:
            - code
            - key
            - message
          properties:
            code:
              type: integer
              example: 401
            key:
              type: string
              example: auth.invalid_token
            message:
              type: string
              example: The access token is invalid.
            details:
              type: object
              additionalProperties: true
        meta:
          $ref: '#/components/schemas/PublicApiMeta'
    ErrorResponse:
      allOf:
        - $ref: '#/components/schemas/StandardResponse'
        - example:
            status: 401
            error: true
            message: MISSING_AUTH
    PublicWorkoutSourceCoachGroupWorkoutStartPayload:
      type: object
      required:
        - source
        - participants
      properties:
        source:
          type: string
          enum:
            - calendar_event
            - manual
          example: manual
        calendarEventId:
          type:
            - string
            - 'null'
          example: null
        eventId:
          type:
            - string
            - 'null'
          example: null
        instanceStart:
          type: string
          format: date-time
          example: '2026-04-12T10:00:00.000Z'
          description: >-
            Optional occurrence start date for recurring calendar events. The
            backend also accepts calendarOccurrenceStartDate for the same value.
        calendarOccurrenceStartDate:
          type: string
          format: date-time
          example: '2026-04-12T10:00:00.000Z'
          description: >-
            Optional occurrence start date for recurring calendar events. Used
            to scope the group run to one recurring occurrence.
        manualSessionKey:
          type:
            - string
            - 'null'
          example: small-group-2026-06-04-09
        participants:
          type: array
          minItems: 1
          items:
            $ref: >-
              #/components/schemas/PublicWorkoutSourceCoachGroupWorkoutParticipantPayload
    PublicApiWriteMeta:
      type: object
      additionalProperties: false
      required:
        - requestId
      properties:
        requestId:
          type: string
          description: Stable request correlation id. Mirrors `X-Request-Id` when supplied.
          example: 4f849d7d-f4f1-45cc-b4b7-3984a3d17f83
        rateLimit:
          $ref: '#/components/schemas/PublicApiRateLimitMeta'
        idempotency:
          type: object
          additionalProperties: false
          properties:
            replayed:
              type: boolean
              description: >-
                True when the response was replayed from a previous request with
                the same `Idempotency-Key`.
              example: true
    PublicApiMeta:
      type: object
      additionalProperties: false
      required:
        - requestId
      properties:
        requestId:
          type: string
          description: Stable request correlation id. Mirrors `X-Request-Id` when supplied.
          example: 4f849d7d-f4f1-45cc-b4b7-3984a3d17f83
        rateLimit:
          $ref: '#/components/schemas/PublicApiRateLimitMeta'
    StandardResponse:
      type: object
      properties:
        status:
          type: integer
          example: 200
        error:
          type: boolean
          example: false
        message:
          type: string
          example: SUCCESS
      required:
        - status
        - error
        - message
    PublicWorkoutSourceCoachGroupWorkoutParticipantPayload:
      type: object
      required:
        - clientId
      properties:
        clientId:
          type: string
          example: 67f1234567890abcdef1234
        workoutSource:
          type: string
          enum:
            - auto_assigned_plan
            - manual_assigned_plan
            - template
            - group_workout_template
            - freestyle
            - wod
          example: auto_assigned_plan
        planId:
          type:
            - string
            - 'null'
          example: null
          description: >-
            Optional for manual_assigned_plan; when omitted the client
            active/latest assigned plan is used. Required when workoutSource is
            template or group_workout_template.
        planMomentId:
          type:
            - string
            - 'null'
          example: null
          description: >-
            Optional for manual_assigned_plan; when omitted the next available
            assigned plan moment is used. Required when workoutSource is
            template or group_workout_template.
        resumeAction:
          type: string
          enum:
            - continue
            - restart
          example: continue
        confirmationToken:
          type: string
          example: a0eb661b-bf61-4af6-98f0-d7d7ff8a3e75
    PublicApiRateLimitMeta:
      type: object
      additionalProperties: false
      properties:
        limit:
          type: integer
          example: 10
        remaining:
          type: integer
          example: 9
        resetSeconds:
          type: integer
          description: Seconds until the current rate limit window resets.
          example: 1
        retryAfterSeconds:
          type: integer
          description: Present when the request was rate limited.
          example: 1
  securitySchemes:
    PublicBearerAuth:
      type: http
      scheme: bearer
      bearerFormat: Opaque
      description: >-
        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`.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.