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

# Export a coach-visible V2 plan as PDF

> Requires training.programmes.view in the active company and member scope, Training V2, and the programme calendar capability for flexible plans. Assigned plans use their saved personal prescriptions. Calendar exports contain the base programme only, never occurrence overrides or performance history. Automatic language uses the assigned member profile, otherwise the coach. PDF generation requires saved editor changes. QR links require the configured website assistant token with exercises.read and access to the requested language site. A website API failure returns 500; retry or explicitly request qr=false. No export preferences are persisted. Slow-request diagnostics separately measure plan reads, context reads, media resolution and PDF rendering, including failed phases.

Requires the workout_plans:read scope. This operation maps to /app/v1/workout/plans/:planId/export 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/{planId}/export
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/{planId}/export:
    get:
      tags:
        - Workout
      summary: Export a coach-visible V2 plan as PDF
      description: >-
        Requires training.programmes.view in the active company and member
        scope, Training V2, and the programme calendar capability for flexible
        plans. Assigned plans use their saved personal prescriptions. Calendar
        exports contain the base programme only, never occurrence overrides or
        performance history. Automatic language uses the assigned member
        profile, otherwise the coach. PDF generation requires saved editor
        changes. QR links require the configured website assistant token with
        exercises.read and access to the requested language site. A website API
        failure returns 500; retry or explicitly request qr=false. No export
        preferences are persisted. Slow-request diagnostics separately measure
        plan reads, context reads, media resolution and PDF rendering, including
        failed phases.


        Requires the workout_plans:read scope. This operation maps to
        /app/v1/workout/plans/:planId/export 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: publicWorkoutgetPublicV1WorkoutPlansPlanIdExport
      parameters:
        - name: planId
          in: path
          required: true
          schema:
            type: string
            pattern: ^[a-fA-F0-9]{24}$
        - name: layout
          in: query
          schema:
            type: string
            enum:
              - supercompact
              - handout
              - worksheet
              - logbook
            default: handout
          description: >-
            Supercompact uses two V1-style prescription cards per row, with
            full-width continuation tables for long exercises. It does not use
            the legacy V1 data/export endpoint. Handout starts each training day
            on a new page; worksheet includes blank result fields. Logbook uses
            landscape A4 with up to four weeks per sheet, exact per-week
            prescriptions and blank results for each set. Changed exercise
            sequences are separate blocks; absent weeks or sets have no writing
            fields.
        - name: logWeeks
          in: query
          schema:
            type: integer
            enum:
              - 4
              - 8
              - 12
            default: 4
          description: >-
            Only accepted for layout=logbook. Number of weeks to repeat a
            recurring single-week programme. Multi-week programmes always use
            the actual selected weeks and ignore this repeat count. Four weeks
            per sheet; additional bands start on a new sheet.
        - name: language
          in: query
          schema:
            type: string
            enum:
              - auto
              - nl
              - en
              - de
              - es
              - fr
            default: auto
        - name: selection
          in: query
          schema:
            type: string
            enum:
              - all
              - weeks
              - days
            default: all
        - name: weekNumbers
          in: query
          description: >-
            Comma-separated week numbers (1–999), required only with
            selection=weeks. At most 500 values.
          schema:
            type: string
            example: 1,2
        - name: momentIds
          in: query
          description: >-
            Comma-separated plan-moment IDs, required only with selection=days.
            At most 500 values. Calendar day selection includes these workouts
            only.
          schema:
            type: string
        - name: images
          in: query
          description: >-
            Defaults to true for supercompact and handout, false for worksheet
            and logbook.
          schema:
            type: boolean
        - name: notes
          in: query
          description: >-
            Include available localized exercise instructions and original
            written instructions. Defaults to false for logbook and true for the
            other layouts.
          schema:
            type: boolean
        - name: qr
          in: query
          description: >-
            Defaults to true for handout, false for supercompact, worksheet and
            logbook. No client data or tokens in public links.
          schema:
            type: boolean
      responses:
        '200':
          description: >-
            A4 PDF (landscape for logbook, portrait otherwise); private,
            no-store. Reuse this file for preview, print and download.
          headers:
            Content-Disposition:
              schema:
                type: string
              description: Attachment with a sanitized filename.
            Content-Language:
              schema:
                type: string
                enum:
                  - nl
                  - en
                  - de
                  - es
                  - fr
            X-Workout-Print-Missing-Qr:
              schema:
                type: integer
                minimum: 0
              description: >-
                Unique linked catalog exercises without an available publication
                in the requested language. Zero when qr=false. Own exercises
                without an explicit catalog identity are excluded.
            Cache-Control:
              schema:
                type: string
                const: private, no-store
          content:
            application/pdf:
              schema:
                type: string
                format: binary
        '400':
          description: >-
            Invalid options, empty selection, or selection exceeds 500 days /
            20,000 sets / 5,000 exercises / 1,000 sets per exercise. Recurring
            logbook expansion is limited to 20,000 set-week cells.
          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':
          description: Authentication required.
          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: >-
            Missing permission, member access or feature entitlement; client
            tokens are not allowed.
          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: Plan unavailable within the active company 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: PDF or website API failure; no partial PDF is returned.
          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/{planId}/export"
            \
              -H "Authorization: Bearer <access_token>"
components:
  schemas:
    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.