> ## 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.

# Get workout v2 plan detail

> Requires the workout_plans:read scope. This operation maps to /app/v1/workout/plans/:id 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 get /public/v1/workout/plans/{id}
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/plans/{id}:
    get:
      tags:
        - Workout
      summary: Get workout v2 plan detail
      description: >-
        Requires the workout_plans:read scope. This operation maps to
        /app/v1/workout/plans/:id 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: publicWorkoutgetPublicV1WorkoutPlansId
      parameters:
        - in: path
          name: id
          required: true
          description: Workout plan id.
          schema:
            type: string
            example: 67f1234567890abcdef1234
      responses:
        '200':
          description: Stored workout-plan payload.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/PublicApiSuccessResponse'
                  - type: object
                    properties:
                      data:
                        $ref: >-
                          #/components/schemas/PublicWorkoutSourceGETAppV1WorkoutPlansIdResponse200
              examples:
                success:
                  summary: Successful response
                  value:
                    data:
                      runningPlan:
                        goal:
                          distance: 5K
                          goalTimeSec: 1
                          raceDate: '2026-07-14'
                          acceptGoalAsChallenge: true
                        goalUpdatedAt: '2026-07-14T10:00:00.000Z'
                        goalUpdatedBy: string
                        adaptationRevision: 1
                        lastReviewedWeek: 1
                        lastAdaptedAt: '2026-07-14T10:00:00.000Z'
                        generation:
                          templateKey: 5K
                          variant: true
                          runWeekdays:
                            - 1
                          qualityWeekdays:
                            - 1
                          longRunWeekday: 1
                          phases:
                            base: 1
                            threshold: 1
                            sharpen: 1
                          taperWeeks: 1
                          sourceVersion: plansjablonen-v259-1
                          policyVersion: safety-calendar-v1
                          generatedAt: '2026-07-14T10:00:00.000Z'
                          generatedBy: string
                          profileUpdatedAt: '2026-07-14T10:00:00.000Z'
                          totalWeeks: 1
                          concreteWeeks: 1
                          baselineKm: 1
                          peakKm: 1
                          thresholdSecPerKm: 1
                          warnings:
                            - string
                        weekSummaries:
                          - weekNumber: 1
                            weekStart: '2026-07-14'
                            phase: 1
                            phaseName: Base building
                            theme: Base building
                            weekKind: build
                            rotationWeek: 1
                            targetVolumeKm: 1
                            concrete: true
                            requestedVolumeKm: 1
                            allocatedKm: 1
                            remainingKm: 1
                            concreteRequested: true
                            sessions:
                              - weekday: 1
                                code: drempel_c
                                sessionType: threshold_continuous
                                controlMode: hr
                                longRunTargetMinutes: 1
                                ladder:
                                  step: 1
                                  reps: 1
                                  kmPerRep: 1
                                continuousMinutes: 1
                                recoveryRangeSec:
                                  low: 1
                                  high: 1
                                cardio:
                                  slotKey: string
                                  sessionType: easy
                                  controlMode: pace
                                  ladderStep: 1
                                  poolLengthM: 25
                                  blocks:
                                    - _id: 67f1234567890abcdef1234
                                      repeat: 1
                                      steps:
                                        - _id: 67f1234567890abcdef1234
                                          kind: warmup
                                          durationType: time
                                          durationValue: 1
                                          target:
                                            kind: paceZone
                                            zone: E
                                            basis: lthr
                                            low: 1
                                            high: 1
                                          secondaryTarget:
                                            kind: paceZone
                                            zone: E
                                            basis: lthr
                                            low: 1
                                            high: 1
                                          notes: string
                                          stroke: free
                                          equipment:
                                            - pullBuoy
                                          restMode: rest
                                          sendOffSec: 1
                                          cadence:
                                            low: 1
                                            high: 1
                                  sourceTemplateId: null
                                totals:
                                  durationSec: 1
                                  distanceM: 1
                                  plannedDurationMinutes: 1
                                  targetDistanceMeters: 1
                                  zoneTimeSec: {}
                      _id: 67f1234567890abcdef1234
                      companyId: 67f1234567890abcdef1234
                      clientId: null
                      sourceTemplateId: null
                      addedBy: 67f1234567890abcdef1234
                      addedByRole: Coach
                      status: Draft
                      templateType: Template
                      name:
                        - lang: en
                          value: Full Body Strength
                        - lang: nl
                          value: Full Body Kracht
                      description:
                        - lang: en
                          value: Full Body Strength
                        - lang: nl
                          value: Full Body Kracht
                      difficulty: Intermediate
                      intensity: Medium
                      duration:
                        startDate: '2026-04-15'
                        endDate: '2026-06-15'
                        hasEndDate: true
                      images:
                        - url: https://cdn.example.com/workouts/plan-cover.jpg
                          width: 1280
                          height: 720
                      videos:
                        - url: https://cdn.example.com/workouts/demo.mp4
                          platform: s3
                          videoId: ''
                          thumbnail: https://cdn.example.com/workouts/demo-thumb.jpg
                          duration: 84
                          width: 1920
                          height: 1080
                      category: Strength
                      goal: Strength
                      periodizationType: Linear
                      popularity: 0
                      useDefaultExerciseSettings: true
                      defaultExerciseValues:
                        sets: 3
                        reps: 10-12
                        rest: 90
                        weight: 0
                        repTempo: '3010'
                        duration: 0
                      planMoments:
                        - _id: 67f1234567890abcdef1234
                          name:
                            - lang: en
                              value: Full Body Strength
                            - lang: nl
                              value: Full Body Kracht
                          description:
                            - lang: en
                              value: Full Body Strength
                            - lang: nl
                              value: Full Body Kracht
                          dayOrder: 1
                          order: 0
                          weekNumber: 1
                          sessionOrder: 1
                          date: '2026-04-15'
                          scoringType: forTime
                          targetValue: null
                          descriptionOnly: true
                          timeDomain:
                            windowSeconds: null
                            timeCapSeconds: 900
                            rounds: 3
                            intervalSeconds: null
                            intervalCount: null
                            workSeconds: null
                            restSeconds: null
                          scoreValidation:
                            timeCapSeconds: 900
                            maxReps: null
                            expectedIntervals: null
                          exercises:
                            - _id: 67f1234567890abcdef1234
                              exerciseId: 67f1234567890abcdef1234
                              type: reps
                              minReps: 6
                              maxReps: 8
                              notes: Pause 1 second on the chest.
                              sets: 4
                              metric: kg
                              rest: 120
                              intensity: High
                              difficulty: Intermediate
                              groupId: super-a
                              rpe: 8
                              rmPercentage: 75
                              tempo: '3010'
                              perSetTrackingEnabled: true
                              rpeEnabled: false
                              showSetRpe: true
                              setsData:
                                - setNumber: 1
                                  setType: 'N'
                                  metric: '12'
                                  repetition: 8-12
                                  weight: 60
                                  rest: 90
                                  rpe: 7.5
                                  duration: 45
                                  distance: 250
                              setupSettingsEnabled: true
                              setupFields:
                                - key: seat
                                  label: Seat
                                  type: text
                                  unit: ''
                                  options:
                                    - '1'
                                    - '2'
                                    - '3'
                                    - '4'
                                  order: 1
                                  required: false
                                  enabled: true
                                  defaultValue: 3
                              order: 0
                              isDeleted: false
                              deletedAt: null
                              createdAt: '2026-04-12T10:00:00.000Z'
                              updatedAt: '2026-04-12T10:00:00.000Z'
                          isDeleted: false
                          deletedAt: null
                          createdAt: '2026-04-12T10:00:00.000Z'
                          updatedAt: '2026-04-12T10:00:00.000Z'
                      visibility: Company
                      isDeleted: false
                      deletedAt: null
                      createdAt: '2026-04-12T10:00:00.000Z'
                      updatedAt: '2026-04-12T10:00:00.000Z'
                    meta:
                      requestId: 4f849d7d-f4f1-45cc-b4b7-3984a3d17f83
                      rateLimit:
                        limit: 10
                        remaining: 9
                        resetSeconds: 1
        '400':
          description: Workout-plan id is malformed.
          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
        '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':
          $ref: '#/components/schemas/ErrorResponse'
          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: Workout plan was not found in the caller's visible scope.
          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':
          $ref: '#/components/schemas/ErrorResponse'
        '422':
          $ref: '#/components/schemas/ErrorResponse'
        '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 GET "https://api.fitsociety.io/public/v1/workout/plans/{id}"
            \
              -H "Authorization: Bearer <access_token>"
components:
  schemas:
    PublicApiSuccessResponse:
      type: object
      additionalProperties: false
      required:
        - data
        - meta
      properties:
        data:
          type: object
        meta:
          $ref: '#/components/schemas/PublicApiMeta'
    PublicWorkoutSourceGETAppV1WorkoutPlansIdResponse200:
      type: object
      properties:
        runningPlan:
          type: object
          properties:
            goal:
              type: object
              additionalProperties: false
              required:
                - distance
                - goalTimeSec
                - raceDate
              properties:
                distance:
                  type: string
                  enum:
                    - 5K
                    - 10K
                    - half
                    - marathon
                goalTimeSec:
                  type: number
                  exclusiveMinimum: 0
                  description: >-
                    Finish time in seconds. Localized numeric strings are
                    accepted on input.
                raceDate:
                  type: string
                  format: date
                  description: Canonical YYYY-MM-DD athlete calendar date.
                acceptGoalAsChallenge:
                  type: boolean
                  default: false
            goalUpdatedAt:
              type: string
              format: date-time
              readOnly: true
            goalUpdatedBy:
              type: string
              readOnly: true
            adaptationRevision:
              type: integer
              minimum: 0
              readOnly: true
            lastReviewedWeek:
              type: integer
              minimum: 0
              maximum: 104
              readOnly: true
            lastAdaptedAt:
              type: string
              format: date-time
              readOnly: true
            generation:
              type: object
              readOnly: true
              properties:
                templateKey:
                  type: string
                  enum:
                    - 5K
                    - 10K
                    - half
                    - marathon
                variant:
                  type: boolean
                runWeekdays:
                  type: array
                  uniqueItems: true
                  items:
                    type: integer
                    minimum: 1
                    maximum: 7
                qualityWeekdays:
                  type: array
                  uniqueItems: true
                  items:
                    type: integer
                    minimum: 1
                    maximum: 7
                longRunWeekday:
                  type: integer
                  minimum: 1
                  maximum: 7
                phases:
                  type: object
                  properties:
                    base:
                      type: integer
                    threshold:
                      type: integer
                    sharpen:
                      type: integer
                taperWeeks:
                  type: integer
                  enum:
                    - 1
                    - 2
                sourceVersion:
                  type: string
                  enum:
                    - plansjablonen-v259-1
                policyVersion:
                  type: string
                  enum:
                    - safety-calendar-v1
                generatedAt:
                  type: string
                  format: date-time
                generatedBy:
                  type: string
                profileUpdatedAt:
                  type: string
                  format: date-time
                totalWeeks:
                  type: integer
                  minimum: 1
                  maximum: 104
                concreteWeeks:
                  type: integer
                  minimum: 1
                  maximum: 3
                baselineKm:
                  type: number
                peakKm:
                  type: number
                thresholdSecPerKm:
                  type: number
                warnings:
                  type: array
                  items:
                    type: string
            weekSummaries:
              type: array
              items:
                type: object
                properties:
                  weekNumber:
                    type: integer
                  weekStart:
                    type: string
                    format: date
                  phase:
                    type: integer
                    enum:
                      - 1
                      - 2
                      - 3
                  phaseName:
                    type: string
                    enum:
                      - Base building
                      - Threshold development
                      - Sharpening
                  theme:
                    type: string
                    enum:
                      - Base building
                      - Threshold development
                      - Sharpening
                  weekKind:
                    type: string
                    enum:
                      - build
                      - race
                      - taper
                      - sharpen
                      - deload
                  rotationWeek:
                    type: integer
                    enum:
                      - 1
                      - 2
                      - 3
                  targetVolumeKm:
                    type: number
                  concrete:
                    type: boolean
                  requestedVolumeKm:
                    type: number
                  allocatedKm:
                    type: number
                  remainingKm:
                    type: number
                  concreteRequested:
                    type: boolean
                  sessions:
                    type: array
                    items:
                      type: object
                      properties:
                        weekday:
                          type: integer
                          minimum: 1
                          maximum: 7
                        code:
                          type: string
                          enum:
                            - drempel_c
                            - drempel_r
                            - interval
                            - doeltempo
                            - zone2
                            - long_run
                        sessionType:
                          type: string
                          enum:
                            - threshold_continuous
                            - threshold_reps
                            - interval
                            - race_pace
                            - zone2
                            - long_run
                        controlMode:
                          type: string
                          enum:
                            - hr
                            - pace
                        longRunTargetMinutes:
                          type: number
                        ladder:
                          type: object
                          required:
                            - step
                            - reps
                            - kmPerRep
                          properties:
                            step:
                              type: integer
                              minimum: 1
                              maximum: 8
                            reps:
                              type: integer
                              minimum: 1
                            kmPerRep:
                              type: number
                              exclusiveMinimum: 0
                        continuousMinutes:
                          type: number
                        recoveryRangeSec:
                          type: object
                          properties:
                            low:
                              type: number
                            high:
                              type: number
                        cardio:
                          type: object
                          additionalProperties: false
                          description: >-
                            Optional structured activity prescription. Requires
                            workoutsectionv2 + workoutV2ProgrammeCalendar +
                            workoutV2CardioBuilder. Omitted from disabled reads.
                            Supported sports: running (paceZone E/T/I/R/RP,
                            absolute pace, absolute HR, RPE), walking (pace, HR,
                            RPE), cycling (power, HR, RPE), rowing (pace, power,
                            HR, RPE), swimming (pace, RPE). Rejected for
                            workout, padel, mobility and other items. Totals
                            overwrite planned duration/distance; unknown time or
                            distance contributes zero.
                          properties:
                            slotKey:
                              type: string
                              description: >-
                                Generated when missing; retain across edits,
                                copies and weeks.
                            sessionType:
                              type: string
                              enum:
                                - easy
                                - zone2
                                - long_run
                                - threshold_continuous
                                - threshold_reps
                                - interval
                                - race_pace
                                - time_trial
                                - race
                              description: >-
                                Running only. Template session codes:
                                threshold_continuous = drempel_c, threshold_reps
                                = drempel_r, interval, race_pace = doeltempo,
                                zone2. A typed session with empty blocks is a
                                skeleton to be filled later.
                            controlMode:
                              type: string
                              enum:
                                - pace
                                - hr
                              description: >-
                                Binding signal. Defaults from sessionType: hr
                                for easy, zone2 and long_run; pace for
                                threshold_continuous, threshold_reps, interval
                                and race_pace; none for time_trial and race. A
                                contradicting value is rejected.
                            ladderStep:
                              type: integer
                              minimum: 1
                              description: >-
                                Ladder position: interval 1–8, threshold_reps
                                1–7, threshold_continuous 1–5 (15/18/20/22/25
                                min). Rejected for other session types.
                            poolLengthM:
                              type: number
                              enum:
                                - 25
                                - 50
                              description: Swimming only.
                            blocks:
                              type: array
                              maxItems: 10
                              items:
                                type: object
                                additionalProperties: false
                                properties:
                                  _id:
                                    type: string
                                    example: 67f1234567890abcdef1234
                                  repeat:
                                    type: integer
                                    minimum: 1
                                    maximum: 50
                                    default: 1
                                  steps:
                                    type: array
                                    maxItems: 20
                                    items:
                                      type: object
                                      additionalProperties: false
                                      required:
                                        - kind
                                        - durationType
                                      properties:
                                        _id:
                                          type: string
                                          example: 67f1234567890abcdef1234
                                        kind:
                                          type: string
                                          enum:
                                            - warmup
                                            - work
                                            - recovery
                                            - rest
                                            - cooldown
                                        durationType:
                                          type: string
                                          enum:
                                            - time
                                            - distance
                                            - open
                                        durationValue:
                                          type:
                                            - number
                                            - 'null'
                                          minimum: 0
                                          default: null
                                          description: >-
                                            Required seconds for time or metres for
                                            distance; null/omitted for open.
                                        target:
                                          type: object
                                          additionalProperties: false
                                          required:
                                            - kind
                                          description: >-
                                            Allowed kinds and zones depend on the
                                            sport. Zone targets require zone; other
                                            targets require ordered low/high bounds.
                                            Pace is seconds/km for running/walking,
                                            seconds/500m for rowing, seconds/100m
                                            for swimming. Percentages are percent
                                            values; HR is bpm, power is watts, RPE
                                            is 1–10. Numeric strings with dot or
                                            comma decimals are accepted.
                                          properties:
                                            kind:
                                              type: string
                                              enum:
                                                - paceZone
                                                - pacePct
                                                - pace
                                                - hrZone
                                                - hrPct
                                                - hr
                                                - powerZone
                                                - powerPct
                                                - power
                                                - rpe
                                            zone:
                                              type: string
                                              enum:
                                                - E
                                                - T
                                                - I
                                                - R
                                                - RP
                                                - Z1
                                                - Z2
                                                - Z3
                                                - Z4
                                                - Z5
                                                - Z6
                                                - Z7
                                                - easy
                                                - endurance
                                                - threshold
                                                - speed
                                              description: >-
                                                Run pace: E (easy), T (threshold), I
                                                (interval), R (repetition), RP (race
                                                pace = goal time / goal distance, never
                                                derived from T). Running has no HR
                                                zones; HR bands are absolute bpm from
                                                athlete data. Walking/rowing pace and
                                                five-zone HR: Z1–Z5. Bike/row power:
                                                Z1–Z7. Swimming pace: easy, endurance,
                                                threshold, speed.
                                            basis:
                                              type: string
                                              enum:
                                                - lthr
                                                - maxHr
                                              description: HR zone/percentage targets only.
                                            low:
                                              type: number
                                              minimum: 0
                                            high:
                                              type: number
                                              minimum: 0
                                        secondaryTarget:
                                          type: object
                                          additionalProperties: false
                                          required:
                                            - kind
                                          description: >-
                                            Allowed kinds and zones depend on the
                                            sport. Zone targets require zone; other
                                            targets require ordered low/high bounds.
                                            Pace is seconds/km for running/walking,
                                            seconds/500m for rowing, seconds/100m
                                            for swimming. Percentages are percent
                                            values; HR is bpm, power is watts, RPE
                                            is 1–10. Numeric strings with dot or
                                            comma decimals are accepted.
                                          properties:
                                            kind:
                                              type: string
                                              enum:
                                                - paceZone
                                                - pacePct
                                                - pace
                                                - hrZone
                                                - hrPct
                                                - hr
                                                - powerZone
                                                - powerPct
                                                - power
                                                - rpe
                                            zone:
                                              type: string
                                              enum:
                                                - E
                                                - T
                                                - I
                                                - R
                                                - RP
                                                - Z1
                                                - Z2
                                                - Z3
                                                - Z4
                                                - Z5
                                                - Z6
                                                - Z7
                                                - easy
                                                - endurance
                                                - threshold
                                                - speed
                                              description: >-
                                                Run pace: E (easy), T (threshold), I
                                                (interval), R (repetition), RP (race
                                                pace = goal time / goal distance, never
                                                derived from T). Running has no HR
                                                zones; HR bands are absolute bpm from
                                                athlete data. Walking/rowing pace and
                                                five-zone HR: Z1–Z5. Bike/row power:
                                                Z1–Z7. Swimming pace: easy, endurance,
                                                threshold, speed.
                                            basis:
                                              type: string
                                              enum:
                                                - lthr
                                                - maxHr
                                              description: HR zone/percentage targets only.
                                            low:
                                              type: number
                                              minimum: 0
                                            high:
                                              type: number
                                              minimum: 0
                                        notes:
                                          type: string
                                          default: ''
                                        stroke:
                                          type: string
                                          enum:
                                            - free
                                            - back
                                            - breast
                                            - fly
                                            - im
                                            - choice
                                            - kick
                                            - drill
                                          description: Swimming only.
                                        equipment:
                                          type: array
                                          items:
                                            type: string
                                            enum:
                                              - pullBuoy
                                              - paddles
                                              - fins
                                              - kickboard
                                              - snorkel
                                          description: Swimming only.
                                        restMode:
                                          type: string
                                          enum:
                                            - rest
                                            - sendOff
                                          description: >-
                                            Swimming only. sendOff requires
                                            sendOffSec.
                                        sendOffSec:
                                          type: number
                                          minimum: 1
                                          description: Swimming sendOff only.
                                        cadence:
                                          type: object
                                          additionalProperties: false
                                          required:
                                            - low
                                            - high
                                          properties:
                                            low:
                                              type: number
                                              minimum: 0
                                            high:
                                              type: number
                                              minimum: 0
                                    default: []
                              default: []
                            sourceTemplateId:
                              type:
                                - string
                                - 'null'
                              example: null
                        totals:
                          type: object
                          properties:
                            durationSec:
                              type: number
                              minimum: 0
                            distanceM:
                              type: number
                              minimum: 0
                            plannedDurationMinutes:
                              type: number
                              minimum: 0
                            targetDistanceMeters:
                              type: number
                              minimum: 0
                            zoneTimeSec:
                              type: object
                              additionalProperties:
                                type: number
                                minimum: 0
                          additionalProperties: false
        _id:
          type: string
          example: 67f1234567890abcdef1234
        companyId:
          type: string
          example: 67f1234567890abcdef1234
        clientId:
          type:
            - string
            - 'null'
          example: null
        sourceTemplateId:
          type:
            - string
            - 'null'
          example: null
        addedBy:
          type: string
          example: 67f1234567890abcdef1234
        addedByRole:
          type: string
          enum:
            - Coach
            - Client
            - Fitsociety
            - Admin
          example: Coach
        status:
          type: string
          enum:
            - Active
            - Inactive
            - Draft
          example: Draft
        templateType:
          type: string
          enum:
            - Template
            - Assigned
          example: Template
        name:
          type: array
          minItems: 1
          items:
            type: object
            required:
              - lang
              - value
            properties:
              lang:
                type: string
                enum:
                  - en
                  - nl
                  - fr
                  - de
                  - es
                example: en
              value:
                type: string
                example: Full Body Strength
          example:
            - lang: en
              value: Full Body Strength
            - lang: nl
              value: Full Body Kracht
        description:
          type: array
          minItems: 1
          items:
            type: object
            required:
              - lang
              - value
            properties:
              lang:
                type: string
                enum:
                  - en
                  - nl
                  - fr
                  - de
                  - es
                example: en
              value:
                type: string
                example: Full Body Strength
          example:
            - lang: en
              value: Full Body Strength
            - lang: nl
              value: Full Body Kracht
        difficulty:
          type: string
          enum:
            - Beginner
            - Intermediate
            - Advanced
          example: Intermediate
        intensity:
          type: string
          enum:
            - Low
            - Medium
            - High
          example: Medium
        duration:
          type: object
          properties:
            startDate:
              type: string
              example: '2026-04-15'
            endDate:
              type: string
              example: '2026-06-15'
            hasEndDate:
              type: boolean
              example: true
        images:
          type: array
          items:
            type: object
            required:
              - url
            properties:
              url:
                type: string
                format: uri
                example: https://cdn.example.com/workouts/plan-cover.jpg
              width:
                type:
                  - number
                  - 'null'
                example: 1280
              height:
                type:
                  - number
                  - 'null'
                example: 720
        videos:
          type: array
          items:
            type: object
            required:
              - url
              - platform
            properties:
              url:
                type: string
                format: uri
                example: https://cdn.example.com/workouts/demo.mp4
              platform:
                type: string
                enum:
                  - s3
                  - youtube
                  - tiktok
                example: s3
              videoId:
                type: string
                example: ''
              thumbnail:
                type: string
                format: uri
                example: https://cdn.example.com/workouts/demo-thumb.jpg
              duration:
                type:
                  - number
                  - 'null'
                example: 84
              width:
                type:
                  - number
                  - 'null'
                example: 1920
              height:
                type:
                  - number
                  - 'null'
                example: 1080
        category:
          type: string
          enum:
            - Agility & Speed
            - Strength
            - Hypertrophy
            - Strength - Dynamic
            - Strength - Explosive
            - Strength - Static
            - Cardio
            - Cardio - Duration
            - Cardio - Interval
            - HIIT
            - Crossfit
            - Mobility
            - Stretching
            - Core
            - Coordination & Balance
            - Movement Prep
            - Functional Training
            - Recovery
            - Sports
            - Martial Arts
            - Yoga
            - Other
            - GROUP_WORKOUT_TEMPLATE
            - Plyometric
            - Cycling
            - Cardio - interval
            - Mobilisation
            - Stabilisation
            - Daily Living
            - Target zone
            - Respiration
            - Breathing
            - Massage
            - Outdoor sports
            - Indoor sports
            - Dance
            - Group Lessons
            - Martial arts
            - Material Arts
            - Fight skills
            - Mind and body
            - ''
            - default
          example: Strength
        goal:
          type: string
          enum:
            - Weight Loss
            - Hypertrophy
            - Endurance
            - Flexibility
            - General Fitness
            - Strength
          example: Strength
        periodizationType:
          type: string
          enum:
            - Linear
            - Non-Linear
            - Block
            - Undulating
            - None
          example: Linear
        popularity:
          type: number
          example: 0
        useDefaultExerciseSettings:
          type: boolean
          example: true
        defaultExerciseValues:
          oneOf:
            - type: object
              required:
                - sets
                - reps
                - rest
                - repTempo
              properties:
                sets:
                  type: number
                  minimum: 1
                  example: 3
                reps:
                  oneOf:
                    - type: string
                      pattern: ^\d+(-\d+)?$
                    - type: number
                      minimum: 1
                  example: 10-12
                rest:
                  type: number
                  minimum: 0
                  example: 90
                weight:
                  type: number
                  example: 0
                repTempo:
                  type: string
                  example: '3010'
                duration:
                  type: number
                  example: 0
            - type: 'null'
        planMoments:
          type: array
          items:
            type: object
            properties:
              _id:
                type: string
                example: 67f1234567890abcdef1234
              name:
                type: array
                minItems: 1
                items:
                  type: object
                  required:
                    - lang
                    - value
                  properties:
                    lang:
                      type: string
                      enum:
                        - en
                        - nl
                        - fr
                        - de
                        - es
                      example: en
                    value:
                      type: string
                      example: Full Body Strength
                example:
                  - lang: en
                    value: Full Body Strength
                  - lang: nl
                    value: Full Body Kracht
              description:
                type: array
                minItems: 1
                items:
                  type: object
                  required:
                    - lang
                    - value
                  properties:
                    lang:
                      type: string
                      enum:
                        - en
                        - nl
                        - fr
                        - de
                        - es
                      example: en
                    value:
                      type: string
                      example: Full Body Strength
                example:
                  - lang: en
                    value: Full Body Strength
                  - lang: nl
                    value: Full Body Kracht
              dayOrder:
                type: number
                example: 1
              order:
                type: number
                example: 0
              weekNumber:
                type: integer
                minimum: 1
                example: 1
              sessionOrder:
                type: integer
                minimum: 1
                example: 1
              date:
                type: string
                example: '2026-04-15'
              scoringType:
                type: string
                enum:
                  - standard
                  - forTime
                  - amrap
                  - emom
                  - tabata
                  - maxLoad
                default: standard
                example: forTime
                description: >-
                  Scoring mechanism. Must not be `standard` when
                  `descriptionOnly` is true.
              targetValue:
                type: number
                nullable: true
                minimum: 0
                example: null
              descriptionOnly:
                type: boolean
                default: false
                example: true
                description: >-
                  Marks an exercise-free scored day: the full workout lives in
                  `description` (required), `exercises` must stay empty,
                  `scoringType` must not be standard, and amrap/emom/tabata
                  require their full `timeDomain`. Completing the day requires a
                  manual `wodResult`. Enforced on every write path, including
                  client day edits. Moments that merely have no exercises are
                  NOT scored unless this is true.
              timeDomain:
                type: object
                nullable: true
                description: >-
                  Clock prescription, same contract as a WOD `timeDomain`.
                  Allowed fields depend on `scoringType`: amrap → windowSeconds
                  (required); forTime → timeCapSeconds, rounds (defaults to 1);
                  emom → intervalSeconds, intervalCount (both required); tabata
                  → workSeconds, restSeconds, intervalCount (all required);
                  standard/maxLoad → none.
                properties:
                  windowSeconds:
                    type: integer
                    nullable: true
                    minimum: 1
                    example: null
                  timeCapSeconds:
                    type: integer
                    nullable: true
                    minimum: 1
                    example: 900
                  rounds:
                    type: integer
                    nullable: true
                    minimum: 1
                    example: 3
                  intervalSeconds:
                    type: integer
                    nullable: true
                    minimum: 1
                    example: null
                  intervalCount:
                    type: integer
                    nullable: true
                    minimum: 1
                    example: null
                  workSeconds:
                    type: integer
                    nullable: true
                    minimum: 1
                    example: null
                  restSeconds:
                    type: integer
                    nullable: true
                    minimum: 0
                    example: null
              scoreValidation:
                type: object
                nullable: true
                description: >-
                  Optional result caps. timeCapSeconds and expectedIntervals are
                  derived from `timeDomain` when one is set.
                properties:
                  timeCapSeconds:
                    type: integer
                    nullable: true
                    minimum: 1
                    example: 900
                  maxReps:
                    type: integer
                    nullable: true
                    minimum: 1
                    example: null
                  expectedIntervals:
                    type: integer
                    nullable: true
                    minimum: 1
                    example: null
              exercises:
                type: array
                items:
                  type: object
                  properties:
                    _id:
                      type: string
                      example: 67f1234567890abcdef1234
                    exerciseId:
                      type: string
                      example: 67f1234567890abcdef1234
                    type:
                      type: string
                      enum:
                        - reps
                        - time
                        - distance
                      example: reps
                    minReps:
                      type: number
                      example: 6
                    maxReps:
                      type: number
                      example: 8
                    notes:
                      type: string
                      example: Pause 1 second on the chest.
                    sets:
                      type: number
                      example: 4
                    metric:
                      type: string
                      example: kg
                    rest:
                      type: number
                      example: 120
                    intensity:
                      type: string
                      enum:
                        - Low
                        - Medium
                        - High
                      example: High
                    difficulty:
                      type: string
                      enum:
                        - Beginner
                        - Intermediate
                        - Advanced
                      example: Intermediate
                    groupId:
                      type: string
                      example: super-a
                    rpe:
                      type: number
                      example: 8
                    rmPercentage:
                      type: number
                      example: 75
                    tempo:
                      type: string
                      example: '3010'
                    perSetTrackingEnabled:
                      type: boolean
                      example: true
                    rpeEnabled:
                      type: boolean
                      example: false
                      description: >-
                        Master RPE switch for this plan exercise. False hides
                        current targets and inputs without clearing
                        prescriptions or recorded history. Missing legacy values
                        retain RPE when an exercise target or per-set preference
                        exists. Independent from showSetRpe.
                    showSetRpe:
                      type: boolean
                      example: true
                      description: >-
                        Stored per-set RPE preference. Live input is visible
                        only when RPE is enabled; authoring retains this
                        preference while rpeEnabled is false.
                    setsData:
                      type: array
                      items:
                        type: object
                        properties:
                          setNumber:
                            type: integer
                            minimum: 1
                            example: 1
                          setType:
                            type: string
                            enum:
                              - 'N'
                              - W
                              - D
                              - F
                            example: 'N'
                            description: >-
                              Planned set type: N normal, W warm-up, D drop set,
                              F to failure.
                          metric:
                            type: string
                            example: '12'
                          repetition:
                            type: string
                            example: 8-12
                          weight:
                            type: number
                            example: 60
                          rest:
                            type: number
                            example: 90
                          rpe:
                            type:
                              - number
                              - 'null'
                            minimum: 0
                            maximum: 10
                            example: 7.5
                            description: >-
                              Optional target RPE for this set. It does not
                              inherit the exercise-level RPE value.
                          duration:
                            type: number
                            example: 45
                          distance:
                            type: number
                            example: 250
                    setupSettingsEnabled:
                      type: boolean
                      example: true
                      description: >-
                        Enables the exercise-level machine or equipment setup
                        settings block.
                    setupFields:
                      type: array
                      maxItems: 8
                      items:
                        type: object
                        required:
                          - key
                          - label
                        properties:
                          key:
                            type: string
                            example: seat
                          label:
                            type: string
                            example: Seat
                          type:
                            type: string
                            enum:
                              - text
                              - number
                              - select
                            example: text
                          unit:
                            type: string
                            example: ''
                          options:
                            type: array
                            items:
                              type: string
                            example:
                              - '1'
                              - '2'
                              - '3'
                              - '4'
                          order:
                            type: number
                            example: 1
                          required:
                            type: boolean
                            example: false
                          enabled:
                            type: boolean
                            example: true
                          defaultValue:
                            oneOf:
                              - type: string
                              - type: number
                            example: 3
                    order:
                      type: number
                      example: 0
                    isDeleted:
                      type: boolean
                      example: false
                    deletedAt:
                      type:
                        - string
                        - 'null'
                      format: date-time
                      example: null
                    createdAt:
                      type: string
                      format: date-time
                      example: '2026-04-12T10:00:00.000Z'
                    updatedAt:
                      type: string
                      format: date-time
                      example: '2026-04-12T10:00:00.000Z'
              isDeleted:
                type: boolean
                example: false
              deletedAt:
                type:
                  - string
                  - 'null'
                format: date-time
                example: null
              createdAt:
                type: string
                format: date-time
                example: '2026-04-12T10:00:00.000Z'
              updatedAt:
                type: string
                format: date-time
                example: '2026-04-12T10:00:00.000Z'
        visibility:
          type: string
          enum:
            - Everyone
            - Company
            - Fitsociety
          example: Company
        isDeleted:
          type: boolean
          example: false
        deletedAt:
          type:
            - string
            - 'null'
          format: date-time
          example: null
        createdAt:
          type: string
          format: date-time
          example: '2026-04-12T10:00:00.000Z'
        updatedAt:
          type: string
          format: date-time
          example: '2026-04-12T10:00:00.000Z'
    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
    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
    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.