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

# List active training plans for an athlete

> Returns active training plans for an athlete who is a member of the organization.
V1 exposes only `status=active` plans.

Required scope: `plans:read`




## OpenAPI

````yaml /api-reference/openapi.json get /training-plans
openapi: 3.1.0
info:
  title: NexRex Developer API
  version: '2026-07-01'
  contact:
    name: NexRex Developer Support
    email: api@nexrex.ai
  description: >
    The NexRex Developer API provides programmatic access to your organization's
    training data.

    Access is authenticated with API keys issued in the NexRex Coach Console
    under

    **Settings → Developer API**.


    ## Authentication


    All endpoints except `GET /openapi.json` require a valid API key. Two
    schemes are supported:


    - **Bearer token** (recommended): `Authorization: Bearer nrx_<key>`

    - **API key header**: `X-API-Key: nrx_<key>`


    Keys are org-scoped: a key can only access data belonging to the issuing
    organization.


    ## Scopes


    Each API key carries one or more scopes. Endpoints require the scope listed
    in their

    description. Requests with an insufficient scope receive HTTP 403 with code
    `missing_scope`.


    | Scope | Description |

    |---|---|

    | `org:read` | Read organization metadata (name, athlete count) |

    | `athletes:read` | List and read athlete profiles |

    | `activities:read` | Read athlete activity data (privacy-filtered to
    org-API ceiling) |

    | `plans:read` | Read athlete active training plans |

    | `groups:read` | Read organization group metadata |

    | `exports:create` | Create asynchronous data export jobs |

    | `exports:read` | List, inspect, and download export jobs |


    **Legacy aliases**: `read` → all five read scopes; `admin` → all scopes.


    ## Rate Limits


    All authenticated endpoints share per-key limits:


    | Window | Limit |

    |---|---|

    | Per minute | 60 requests |

    | Per hour | 1,000 requests |


    `POST /exports` carries an additional **5 requests/hour** per key limit.


    Rate limit status is returned on every response via response headers (see
    below).

    When a limit is exceeded the API returns HTTP 429 with code `rate_limited`
    and a

    `Retry-After` header indicating seconds until reset.


    ## Response Headers


    Every authenticated response includes the following headers:


    | Header | Description |

    |---|---|

    | `X-Request-ID` | Unique request identifier for distributed tracing |

    | `X-API-Version` | API version date string (`2026-07-01`) |

    | `X-RateLimit-Limit` | Request limit for the current window |

    | `X-RateLimit-Remaining` | Requests remaining in the current window |

    | `X-RateLimit-Reset` | Unix timestamp (seconds) when the rate limit window
    resets |


    ## Error Envelope


    All error responses follow a consistent envelope:


    ```json

    {
      "success": false,
      "error": "Human-readable message",
      "code": "machine_readable_code",
      "request_id": "req_..."
    }

    ```


    | Code | HTTP | Description |

    |---|---|---|

    | `invalid_key` | 401 | Key does not exist or cannot be parsed |

    | `key_expired` | 401 | Key has passed its expiry date |

    | `key_revoked` | 401 | Key has been revoked by the organization |

    | `feature_not_enabled` | 403 | Developer API not enabled for this
    organization |

    | `missing_scope` | 403 | Key lacks the required scope for this endpoint |

    | `not_found` | 404 | Resource does not exist or is not visible to this key
    |

    | `rate_limited` | 429 | Per-key rate limit exceeded |

    | `validation_error` | 400 | Request parameter or body failed validation |


    ## Deprecation Policy


    Breaking changes are announced at least 90 days in advance except where a
    security or legal

    emergency requires immediate change. See the NexRex Data Portability
    Promise.
servers:
  - url: https://api.nexrex.ai/api/v1/developer/v1
    description: Production
security:
  - bearerAuth: []
  - apiKeyHeader: []
paths:
  /training-plans:
    get:
      summary: List active training plans for an athlete
      description: >
        Returns active training plans for an athlete who is a member of the
        organization.

        V1 exposes only `status=active` plans.


        Required scope: `plans:read`
      operationId: listTrainingPlans
      parameters:
        - name: athlete_id
          in: query
          required: true
          schema:
            type: string
          description: Athlete user ID (must be a member of the API key's organization)
      responses:
        '200':
          description: List of active training plan instances
          headers:
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
            X-API-Version:
              $ref: '#/components/headers/X-API-Version'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - data
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      plans:
                        type: array
                        items:
                          $ref: '#/components/schemas/PlanInstance'
                      athlete_id:
                        type: string
        '400':
          $ref: '#/components/responses/ValidationError'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
      security:
        - bearerAuth: []
        - apiKeyHeader: []
components:
  headers:
    X-Request-ID:
      description: Unique request identifier for distributed tracing
      schema:
        type: string
    X-API-Version:
      description: API version date string
      schema:
        type: string
        example: '2026-07-01'
    X-RateLimit-Limit:
      description: Total request limit for the current window
      schema:
        type: integer
    X-RateLimit-Remaining:
      description: Requests remaining in the current window
      schema:
        type: integer
    X-RateLimit-Reset:
      description: Unix timestamp (seconds) when the current rate limit window resets
      schema:
        type: integer
  schemas:
    PlanInstance:
      type: object
      description: Active training plan instance for an athlete
      properties:
        plan_instance_id:
          type:
            - string
            - 'null'
          description: Plan instance ID
        name:
          type:
            - string
            - 'null'
          description: >-
            Plan display name (resolved from plan_name / plan_instance_name /
            training_plan_name)
        status:
          type:
            - string
            - 'null'
          description: Plan status (e.g. `active`)
        start_date:
          type:
            - number
            - 'null'
          description: Plan start date as epoch seconds (UTC)
        end_date:
          type:
            - number
            - 'null'
          description: >-
            Plan end date as epoch seconds (UTC); computed from start_date +
            total_weeks
        current_week:
          type: integer
          description: >-
            Current 1-indexed week number based on today's date (UTC week
            boundaries)
        total_weeks:
          type:
            - integer
            - 'null'
          description: Total plan duration in weeks
    ErrorResponse:
      type: object
      required:
        - success
        - error
        - code
      properties:
        success:
          type: boolean
          enum:
            - false
        error:
          type: string
          description: Human-readable error message
        code:
          type: string
          description: Machine-readable error code
          enum:
            - invalid_key
            - key_expired
            - key_revoked
            - feature_not_enabled
            - missing_scope
            - not_found
            - rate_limited
            - validation_error
        request_id:
          type:
            - string
            - 'null'
          description: >-
            Request ID echoing X-Request-ID (may be null if the error occurs
            before request context is established)
  responses:
    ValidationError:
      description: Request parameter or body failed validation (`validation_error`)
      headers:
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
        X-API-Version:
          $ref: '#/components/headers/X-API-Version'
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Unauthorized:
      description: >
        Authentication failed. Possible codes: `invalid_key`, `key_expired`,
        `key_revoked`,

        `feature_not_enabled`
      headers:
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
        X-API-Version:
          $ref: '#/components/headers/X-API-Version'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Forbidden:
      description: Key lacks the required scope for this endpoint (`missing_scope`)
      headers:
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
        X-API-Version:
          $ref: '#/components/headers/X-API-Version'
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    NotFound:
      description: Resource does not exist or is not visible to this key (`not_found`)
      headers:
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
        X-API-Version:
          $ref: '#/components/headers/X-API-Version'
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    RateLimited:
      description: Per-key rate limit exceeded (`rate_limited`)
      headers:
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
        X-API-Version:
          $ref: '#/components/headers/X-API-Version'
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        Retry-After:
          description: Seconds until the rate limit resets
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: nrx_<key>
      description: |
        Bearer token. Pass the full API key as the bearer credential.
        Format: `Authorization: Bearer nrx_<key>`
    apiKeyHeader:
      type: apiKey
      in: header
      name: X-API-Key
      description: |
        API key in a request header. Format: `X-API-Key: nrx_<key>`

````