curl -X POST 'https://api.fitsociety.io/public/v1/workout/plans' \
-H 'Authorization: Bearer <access_token>' \
-H 'Idempotency-Key: public-v1-workout-plans-001' \
-H 'Content-Type: application/json' \
-d '{"name":[{"lang":"en","value":"Strength programme"}],"description":[{"lang":"en","value":"Progressive strength training."}],"category":"Strength","visibility":"Company","schedule":{"mode":"recurring","releasePolicy":"all_at_once","startDate":""},"useDefaultExerciseSettings":true,"defaultExerciseValues":{"sets":3,"reps":"8-12","rest":90,"weight":0,"repTempo":"3010","duration":0}}'const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({name: [{lang: 'en', value: 'Strength programme'}], visibility: 'Company'})
};
fetch('https://api.fitsociety.io/public/v1/workout/plans', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.fitsociety.io/public/v1/workout/plans"
payload = {
"name": [
{
"lang": "en",
"value": "Strength programme"
}
],
"visibility": "Company"
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"data": {
"_id": "67f1234567890abcdef1234",
"planId": "67f1234567890abcdef1234",
"externalReference": {
"externalId": "66f7b8b1e13c8d25f4d3d90a",
"revision": 1
}
},
"meta": {
"requestId": "4f849d7d-f4f1-45cc-b4b7-3984a3d17f83",
"rateLimit": {
"limit": 10,
"remaining": 9,
"resetSeconds": 1
},
"idempotency": {
"replayed": false
}
}
}Create a workout plan
Creates a workout plan in the authenticated company scope. Accepts application/json or multipart/form-data. In multipart requests, send structured arrays and objects (e.g. name, description, duration, defaultExerciseValues) as JSON strings. Use imageFiles and videoFiles for media uploads; the legacy aliases images and videos are still accepted. Returns planId for adding workout days and their exercises in subsequent requests.
Requires the workout_plans:write scope and the corresponding Workout features and permissions.
curl -X POST 'https://api.fitsociety.io/public/v1/workout/plans' \
-H 'Authorization: Bearer <access_token>' \
-H 'Idempotency-Key: public-v1-workout-plans-001' \
-H 'Content-Type: application/json' \
-d '{"name":[{"lang":"en","value":"Strength programme"}],"description":[{"lang":"en","value":"Progressive strength training."}],"category":"Strength","visibility":"Company","schedule":{"mode":"recurring","releasePolicy":"all_at_once","startDate":""},"useDefaultExerciseSettings":true,"defaultExerciseValues":{"sets":3,"reps":"8-12","rest":90,"weight":0,"repTempo":"3010","duration":0}}'const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({name: [{lang: 'en', value: 'Strength programme'}], visibility: 'Company'})
};
fetch('https://api.fitsociety.io/public/v1/workout/plans', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.fitsociety.io/public/v1/workout/plans"
payload = {
"name": [
{
"lang": "en",
"value": "Strength programme"
}
],
"visibility": "Company"
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"data": {
"_id": "67f1234567890abcdef1234",
"planId": "67f1234567890abcdef1234",
"externalReference": {
"externalId": "66f7b8b1e13c8d25f4d3d90a",
"revision": 1
}
},
"meta": {
"requestId": "4f849d7d-f4f1-45cc-b4b7-3984a3d17f83",
"rateLimit": {
"limit": 10,
"remaining": 9,
"resetSeconds": 1
},
"idempotency": {
"replayed": false
}
}
}Authorizations
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.
Headers
Required for Public API write requests. Reusing the same key with the same method, path, and body replays the stored successful response; reusing it with a different request returns 409 idempotency.conflict.
1 - 200"booking-create-20260714-001"
Body
Plan metadata and exercise defaults. Description is optional. Supply defaultExerciseValues unless useDefaultExerciseSettings is false; when disabled, omit the defaults or send null. Create workout days and their exercises through the separate moment/exercise endpoints after receiving planId.
1Show child attributes
Show child attributes
[
{
"lang": "en",
"value": "Full Body Strength"
},
{ "lang": "nl", "value": "Full Body Kracht" }
]
Everyone, Company, Fitsociety "Company"
Coach-managed client visibility for ordinary training plans, separate from library sharing. Missing values remain visible. False keeps the plan and linked session details in the coaching environment only; clients cannot change this field. WOD and multiweek plans are unaffected and ignore writes to this field.
1Show child attributes
Show child attributes
[
{
"lang": "en",
"value": "Full Body Strength"
},
{ "lang": "nl", "value": "Full Body Kracht" }
]
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 "Strength"
Weight Loss, Hypertrophy, Endurance, Flexibility, General Fitness, Strength "Strength"
Linear, Non-Linear, Block, Undulating, None "Linear"
Beginner, Intermediate, Advanced "Intermediate"
Low, Medium, High "Medium"
Active, Inactive, Draft "Draft"
Template, Assigned "Template"
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Whether new exercises use the plan-level defaults. When false, defaultExerciseValues must be null.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Optional opaque resource reference owned by the authenticated API client and company. Available only for application/json creation without file uploads. Trimmed, nonempty and at most 200 characters; control characters are rejected. Repeating the reference with the same creation content returns the existing resource; conflicting content returns 409.
1 - 200^[^\u0000-\u001F\u007F]+$"programme-v1"