---
title: "POST /api/public/training-plans"
method: POST
path: "/api/public/training-plans"
tags: ["Training Plans"]
---

# POST /api/public/training-plans

`POST /api/public/training-plans`

Create a training plan. Provide traineeId (or escortId) to attach it to a coaching period, or omit both to leave it unassigned. Set isTemplate to save it as a reusable template. The workouts array holds an ordered list of workout days; each day has a trainingName and an exercises array. Each exercise references a catalog id via exerciseDetails (get ids from GET /exercises).

BREAKING CHANGE: the plan name is now "title". The previous "name" field has been removed, so a request sending "name" is rejected with 400 "must have required property title". This matches the field name used in every read response. The same rename applies to PATCH /training-plans/{planId}.

To build a plan from an existing one, do not read it and re-create it: that silently drops per-set prescriptions, supersets, tempo and intensity. Use POST /training-plans/{planId}/duplicate instead.

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `traineeId` string — Owning trainee id. Omit both traineeId and escortId to leave the plan unassigned.
  - `isTemplate` boolean — Save as a reusable template. A template cannot be assigned, so omit traineeId and escortId.
  - `escortId` string — Optional coaching period id
  - `title` string, required — Plan title shown to the trainee
  - `description` string
  - `level` 'Beginner' | 'Intermediate' | 'Advanced' — Difficulty level of the plan.
  - `maxDuration` number — Target session length in minutes.
  - `workouts` object[] — Ordered workout days (e.g. A/B/C splits)
    - `trainingName` string — Display name of the day, e.g. "Day A — Push".
    - `trainingType` 'A' | 'B' | 'C' | 'D' | 'E' | 'FullBody' | 'CrossFit' | 'Tabata' | 'HIIT' | 'EMOM' | 'AMRAP' | 'Circuit' | 'ForTime' — Day label, e.g. "A", "B", "FullBody".
    - `exerciseOrder` 'Sequential' | 'Circuit' | 'Superset' | 'Complex' — How exercises are performed. Defaults to Sequential.
    - `notes` string — Free-text note for the whole day.
    - `timeBasedDetails` object — Timing configuration for circuit-style days (Tabata, HIIT, EMOM, AMRAP). Seconds unless noted.
      - `totalRounds` number
      - `timeLimit` number
      - `workInterval` number
      - `restInterval` number
      - `restBetweenRounds` number
    - `exercises` object[]
      - `exerciseDetails` string — Exercise catalog id, taken from GET /exercises.
      - `setsNumber` string — Number of sets, e.g. "3".
      - `repsNumber` string — Reps per set, e.g. "10" or "8-12".
      - `restTime` string — Rest between sets in seconds, e.g. "90".
      - `isDurationBased` boolean — True for timed exercises (e.g. plank) instead of reps.
      - `setDuration` string — Duration per set in seconds when isDurationBased is true.
      - `weightPercentage` number — Working weight as % of 1RM, e.g. 75.
      - `customNotes` string — Free-text note shown to the trainee for this exercise.
      - `weight` number — Working weight in kg for the exercise.
      - `sets` object[] — Per-set prescription. Takes precedence over setsNumber/repsNumber when present.
        - `setNumber` number — 1-based position of the set.
        - `reps` string — Reps for this set, e.g. "8".
        - `weight` number — Working weight for this set.
        - `restTime` string — Rest after this set in seconds.
        - `intensityValue` number — Intensity for this set, read against intensityType.
        - `dropSet` 'DropSet' | 'DoubleDropSet' | 'TripleDropSet'
        - `isWarmupSet` boolean — Warmup sets are not counted towards working volume.
      - `superSet` boolean — True when this exercise belongs to a superset.
      - `superSetGroup` string — Shared identifier grouping the exercises performed together in one superset.
      - `dropSet` 'DropSet' | 'DoubleDropSet' | 'TripleDropSet'
      - `restPause` boolean — Rest-pause technique.
      - `cluster` boolean — Cluster-set technique.
      - `trackingType` 'weight_reps' | 'reps_only' | 'duration' | 'completion' — What the trainee logs for this exercise.
      - `intensityType` 'Percentage' | 'RPE' | 'RIR' — How intensityValue is interpreted.
      - `intensityValue` number — Intensity target.
      - `tempo` object — Tempo in seconds per phase of the lift.
        - `eccentric` number
        - `hold` number
        - `concentric` number
        - `rest` number
      - `distance` number — Distance for cardio exercises.
      - `distanceUnit` 'meters' | 'km' | 'miles' | 'yards'
      - `specificAlternativeExercises` string[] — Catalog ids the trainee may swap in for this exercise.

## Response `201`

Created

- object — Created
  - `data` object
    - `id` string
    - `coach` string
    - `escorts` string[]
    - `title` string
    - `notes` string
    - `level` 'Beginner' | 'Intermediate' | 'Advanced'
    - `maxDuration` number — Target session length in minutes.
    - `isTemplate` boolean — True when the plan is a reusable template.
    - `workouts` object[]
      - `trainingName` string — Display name of the day, e.g. "Day A — Push".
      - `trainingType` 'A' | 'B' | 'C' | 'D' | 'E' | 'FullBody' | 'CrossFit' | 'Tabata' | 'HIIT' | 'EMOM' | 'AMRAP' | 'Circuit' | 'ForTime' — Day label, e.g. "A", "B", "FullBody".
      - `exerciseOrder` 'Sequential' | 'Circuit' | 'Superset' | 'Complex' — How exercises are performed. Defaults to Sequential.
      - `notes` string — Free-text note for the whole day.
      - `timeBasedDetails` object — Timing configuration for circuit-style days (Tabata, HIIT, EMOM, AMRAP). Seconds unless noted.
        - `totalRounds` number
        - `timeLimit` number
        - `workInterval` number
        - `restInterval` number
        - `restBetweenRounds` number
      - `exercises` object[]
        - `exerciseDetails` object — The exercise catalog entry. On write, pass exerciseDetails as the catalog id string (from GET /exercises).
          - `id` string
          - `name` string
        - `setsNumber` string — Number of sets, e.g. "3".
        - `repsNumber` string — Reps per set, e.g. "10" or "8-12".
        - `restTime` string — Rest between sets in seconds, e.g. "90".
        - `isDurationBased` boolean — True for timed exercises (e.g. plank) instead of reps.
        - `setDuration` string — Duration per set in seconds when isDurationBased is true.
        - `weightPercentage` number — Working weight as % of 1RM, e.g. 75.
        - `customNotes` string — Free-text note shown to the trainee for this exercise.
        - `weight` number — Working weight in kg for the exercise.
        - `sets` object[] — Per-set prescription. Takes precedence over setsNumber/repsNumber when present.
          - `setNumber` number — 1-based position of the set.
          - `reps` string — Reps for this set, e.g. "8".
          - `weight` number — Working weight for this set.
          - `restTime` string — Rest after this set in seconds.
          - `intensityValue` number — Intensity for this set, read against intensityType.
          - `dropSet` 'DropSet' | 'DoubleDropSet' | 'TripleDropSet'
          - `isWarmupSet` boolean — Warmup sets are not counted towards working volume.
        - `superSet` boolean — True when this exercise belongs to a superset.
        - `superSetGroup` string — Shared identifier grouping the exercises performed together in one superset.
        - `dropSet` 'DropSet' | 'DoubleDropSet' | 'TripleDropSet'
        - `restPause` boolean — Rest-pause technique.
        - `cluster` boolean — Cluster-set technique.
        - `trackingType` 'weight_reps' | 'reps_only' | 'duration' | 'completion' — What the trainee logs for this exercise.
        - `intensityType` 'Percentage' | 'RPE' | 'RIR' — How intensityValue is interpreted.
        - `intensityValue` number — Intensity target.
        - `tempo` object — Tempo in seconds per phase of the lift.
          - `eccentric` number
          - `hold` number
          - `concentric` number
          - `rest` number
        - `distance` number — Distance for cardio exercises.
        - `distanceUnit` 'meters' | 'km' | 'miles' | 'yards'
        - `specificAlternativeExercises` string[] — Catalog ids the trainee may swap in for this exercise.
    - `createdAt` string, date-time
  - `warnings` object[] — Non-fatal problems with follow-up writes. The resource was created, but each listed field was not applied.
    - `field` string
    - `message` string

## Other responses

- `400` — Default Response
- `401` — Default Response
- `403` — Default Response
- `404` — Default Response
- `409` — Default Response
- `429` — Default Response
- `500` — Default Response

---

[API](https://skmtc.dev/coach-platform/apis/coach-platform-api.md) · [All operations](https://skmtc.dev/coach-platform/apis/coach-platform-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/coach-platform/coach-platform-api/revisions/3d18b514ae8c/schema)
