List training plans

GET/api/public/training-plans

List training plans. Filter by traineeId or escortId.

Authentication

Requires an API key, sent as Authorization: Bearer cp_live_....

API keys carry scopes. Get the catalog of scopes and webhook events lists every scope.

Query parameters

Query parameters
NameTypeDescription
pageinteger

Page number (1-based, default 1)

Minimum: 1

limitinteger

Number of items to return (default 25, max 500)

Minimum: 1

Maximum: 500

traineeIdstring
escortIdstring

Request examples

cURL
curl --request GET \
  --url 'https://api.coach-platform.com/api/public/training-plans' \
  --header 'Authorization: Bearer cp_live_...'
JavaScript (fetch)
const response = await fetch('https://api.coach-platform.com/api/public/training-plans', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer cp_live_...',
  },
});

const data = await response.json();

Responses

200 OK

Successful response

Example body (application/json)
{
  "data": [
    {
      "id": "<string>",
      "coach": "<string>",
      "escorts": [
        "<string>"
      ],
      "title": "<string>",
      "notes": "<string>",
      "level": "Beginner",
      "maxDuration": 123,
      "isTemplate": true,
      "workouts": [
        {
          "trainingName": "<string>",
          "trainingType": "A",
          "exerciseOrder": "Sequential",
          "notes": "<string>",
          "timeBasedDetails": {
            "totalRounds": 123,
            "timeLimit": 123,
            "workInterval": 123,
            "restInterval": 123,
            "restBetweenRounds": 123
          },
          "exercises": [
            {
              "exerciseDetails": {
                "id": "<string>",
                "name": "<string>"
              },
              "setsNumber": "<string>",
              "repsNumber": "<string>",
              "restTime": "<string>",
              "isDurationBased": true,
              "setDuration": "<string>",
              "weightPercentage": 123,
              "customNotes": "<string>",
              "weight": 123,
              "sets": [
                {
                  "setNumber": 123,
                  "reps": "<string>",
                  "weight": 123,
                  "restTime": "<string>",
                  "intensityValue": 123,
                  "dropSet": "DropSet",
                  "isWarmupSet": true
                }
              ],
              "superSet": true,
              "superSetGroup": "<string>",
              "dropSet": "DropSet",
              "restPause": true,
              "cluster": true,
              "trackingType": "weight_reps",
              "intensityType": "Percentage",
              "intensityValue": 123,
              "tempo": {
                "eccentric": 123,
                "hold": 123,
                "concentric": 123,
                "rest": 123
              },
              "distance": 123,
              "distanceUnit": "meters",
              "specificAlternativeExercises": [
                "<string>"
              ]
            }
          ]
        }
      ],
      "createdAt": "<date-time>"
    }
  ],
  "pagination": {
    "page": 123,
    "limit": 123,
    "total": 123,
    "hasMore": true,
    "truncated": true
  }
}
Response fields (63)
Response fields
NameTypeDescription
dataobject[]
data[].idstring
data[].coachstring
data[].escortsstring[]
data[].titlestring
data[].notesstring
data[].levelstring

Allowed values: Beginner Intermediate Advanced

data[].maxDurationnumber

Target session length in minutes.

data[].isTemplateboolean

True when the plan is a reusable template.

data[].workoutsobject[]
data[].workouts[].trainingNamestring

Display name of the day, e.g. "Day A — Push".

data[].workouts[].trainingTypestring

Day label, e.g. "A", "B", "FullBody".

Allowed values: A B C D E FullBody CrossFit Tabata HIIT EMOM AMRAP Circuit ForTime

data[].workouts[].exerciseOrderstring

How exercises are performed. Defaults to Sequential.

Allowed values: Sequential Circuit Superset Complex

data[].workouts[].notesstring

Free-text note for the whole day.

data[].workouts[].timeBasedDetailsobject

Timing configuration for circuit-style days (Tabata, HIIT, EMOM, AMRAP). Seconds unless noted.

data[].workouts[].timeBasedDetails.totalRoundsnumber
data[].workouts[].timeBasedDetails.timeLimitnumber
data[].workouts[].timeBasedDetails.workIntervalnumber
data[].workouts[].timeBasedDetails.restIntervalnumber
data[].workouts[].timeBasedDetails.restBetweenRoundsnumber
data[].workouts[].exercisesobject[]
data[].workouts[].exercises[].exerciseDetailsobject

The exercise catalog entry. On write, pass exerciseDetails as the catalog id string (from GET /exercises).

data[].workouts[].exercises[].exerciseDetails.idstring
data[].workouts[].exercises[].exerciseDetails.namestring
data[].workouts[].exercises[].setsNumberstring

Number of sets, e.g. "3".

data[].workouts[].exercises[].repsNumberstring

Reps per set, e.g. "10" or "8-12".

data[].workouts[].exercises[].restTimestring

Rest between sets in seconds, e.g. "90".

data[].workouts[].exercises[].isDurationBasedboolean

True for timed exercises (e.g. plank) instead of reps.

data[].workouts[].exercises[].setDurationstring

Duration per set in seconds when isDurationBased is true.

data[].workouts[].exercises[].weightPercentagenumber

Working weight as % of 1RM, e.g. 75.

data[].workouts[].exercises[].customNotesstring

Free-text note shown to the trainee for this exercise.

data[].workouts[].exercises[].weightnumber

Working weight in kg for the exercise.

data[].workouts[].exercises[].setsobject[]

Per-set prescription. Takes precedence over setsNumber/repsNumber when present.

data[].workouts[].exercises[].sets[].setNumbernumber

1-based position of the set.

data[].workouts[].exercises[].sets[].repsstring

Reps for this set, e.g. "8".

data[].workouts[].exercises[].sets[].weightnumber

Working weight for this set.

data[].workouts[].exercises[].sets[].restTimestring

Rest after this set in seconds.

data[].workouts[].exercises[].sets[].intensityValuenumber

Intensity for this set, read against intensityType.

data[].workouts[].exercises[].sets[].dropSetstring

Allowed values: DropSet DoubleDropSet TripleDropSet

data[].workouts[].exercises[].sets[].isWarmupSetboolean

Warmup sets are not counted towards working volume.

data[].workouts[].exercises[].superSetboolean

True when this exercise belongs to a superset.

data[].workouts[].exercises[].superSetGroupstring

Shared identifier grouping the exercises performed together in one superset.

data[].workouts[].exercises[].dropSetstring

Allowed values: DropSet DoubleDropSet TripleDropSet

data[].workouts[].exercises[].restPauseboolean

Rest-pause technique.

data[].workouts[].exercises[].clusterboolean

Cluster-set technique.

data[].workouts[].exercises[].trackingTypestring

What the trainee logs for this exercise.

Allowed values: weight_reps reps_only duration completion

data[].workouts[].exercises[].intensityTypestring

How intensityValue is interpreted.

Allowed values: Percentage RPE RIR

data[].workouts[].exercises[].intensityValuenumber

Intensity target.

data[].workouts[].exercises[].tempoobject

Tempo in seconds per phase of the lift.

data[].workouts[].exercises[].tempo.eccentricnumber
data[].workouts[].exercises[].tempo.holdnumber
data[].workouts[].exercises[].tempo.concentricnumber
data[].workouts[].exercises[].tempo.restnumber
data[].workouts[].exercises[].distancenumber

Distance for cardio exercises.

data[].workouts[].exercises[].distanceUnitstring

Allowed values: meters km miles yards

data[].workouts[].exercises[].specificAlternativeExercisesstring[]

Catalog ids the trainee may swap in for this exercise.

data[].createdAtstring<date-time>
paginationobject
pagination.pagenumber
pagination.limitnumber
pagination.totalnumber | null

Total number of matching items. null when the underlying source cannot report an exact count for this page; use hasMore to keep paging.

pagination.hasMoreboolean
pagination.truncatedboolean

Present and true when the result set exceeded the in-memory scan cap and was truncated. Narrow your filters to page through all items.

Error responses

  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 429 Too Many Requests
  • 500 Internal Server Error

These statuses share the same response body.

Example body (application/json)
{
  "error": {
    "code": "<string>",
    "message": "<string>",
    "fix": "<string>",
    "details": {},
    "retryAfterMs": 123
  }
}
Error fields (6)
Error fields
NameTypeDescription
errorobject
error.codestring
error.messagestring
error.fixstring | null
error.detailsobject | null
error.retryAfterMsnumber | null

This page is also available as Markdown. Browse it in the interactive explorer or download the OpenAPI spec.