curl -X POST 'https://api.fitsociety.io/public/v1/workout/clients/66f7b8b1e13c8d25f4d3d90c/exercises' \
-H 'Authorization: Bearer <access_token>' \
-H 'Idempotency-Key: public-v1-workout-clients-clientId-exercises-001' \
-H 'Content-Type: application/json' \
-d '{"name":[{"lang":"en","value":"Barbell Bench Press"}],"description":[{"lang":"en","value":"Flat horizontal press."}],"primaryCategory":"Strength","primaryMuscle":"Chest","visibility":"Company"}'const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: [
{lang: 'en', value: 'Full Body Strength'},
{lang: 'nl', value: 'Full Body Kracht'}
],
description: [
{lang: 'en', value: 'Full Body Strength'},
{lang: 'nl', value: 'Full Body Kracht'}
],
primaryCategory: 'Strength',
primaryMuscle: 'Chest'
})
};
fetch('https://api.fitsociety.io/public/v1/workout/clients/{clientId}/exercises', 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/clients/{clientId}/exercises"
payload = {
"name": [
{
"lang": "en",
"value": "Full Body Strength"
},
{
"lang": "nl",
"value": "Full Body Kracht"
}
],
"description": [
{
"lang": "en",
"value": "Full Body Strength"
},
{
"lang": "nl",
"value": "Full Body Kracht"
}
],
"primaryCategory": "Strength",
"primaryMuscle": "Chest"
}
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",
"exerciseId": "67f1234567890abcdef1234",
"exercise": {
"name": "Barbell Bench Press",
"description": "Flat horizontal press.",
"primaryCategory": "Strength",
"secondaryCategories": [
"Agility & Speed"
],
"primaryMuscle": "Chest",
"secondaryMuscles": [
"Chest"
],
"primaryJoint": "Shoulder",
"equipment": [
"Dumbbells"
],
"popularity": 82,
"difficulty": "Intermediate",
"intensity": "Above Average",
"visibility": "Everyone",
"createdAt": "2026-04-12T10:00:00.000Z",
"images": [
{
"url": "https://cdn.example.com/workouts/plan-cover.jpg",
"width": 1280,
"height": 720
}
],
"videos": [
{
"url": "https://cdn.example.com/workouts/demo.mp4",
"platform": "s3",
"videoId": "",
"thumbnail": "https://cdn.example.com/workouts/demo-thumb.jpg",
"duration": 84,
"width": 1920,
"height": 1080
}
],
"muscleActivation": {
"raw": {
"chest": 18,
"shoulders": 12,
"triceps": 8
},
"normalized": {
"chest": 18,
"shoulders": 12,
"triceps": 8
},
"maxValue": 18,
"topMuscles": [
{
"muscle": "chest",
"value": 18
}
]
}
},
"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 exercise as a client
Videos share the company video-library storage allowance (25 decimal GB by default, admin adjustable). Coach web clients should use the exercise video-uploads presign/complete/status flow and send ready video URLs. Existing native multipart video uploads remain supported up to 100 MiB per file; these reserve the same quota and wait for the same compression worker. Client-facing counterpart of POST /app/v1/workout/exercises — lets a client create their own exercise (stored under the client’s active company scope with addedByRole: Client). Requires a client token. Accepts either application/json or multipart/form-data; in multipart requests, send structured arrays/objects as JSON strings, use imageFiles and videoFiles for uploads (the legacy binary aliases images and videos are still accepted). Any visibility in the body is ignored — client-created exercises are always forced to visibility=Company by the controller.
Requires the workout_client_plans:write scope and the corresponding Workout features and permissions.
The clientId path parameter identifies a client in the company bound to the Public API token.
curl -X POST 'https://api.fitsociety.io/public/v1/workout/clients/66f7b8b1e13c8d25f4d3d90c/exercises' \
-H 'Authorization: Bearer <access_token>' \
-H 'Idempotency-Key: public-v1-workout-clients-clientId-exercises-001' \
-H 'Content-Type: application/json' \
-d '{"name":[{"lang":"en","value":"Barbell Bench Press"}],"description":[{"lang":"en","value":"Flat horizontal press."}],"primaryCategory":"Strength","primaryMuscle":"Chest","visibility":"Company"}'const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: [
{lang: 'en', value: 'Full Body Strength'},
{lang: 'nl', value: 'Full Body Kracht'}
],
description: [
{lang: 'en', value: 'Full Body Strength'},
{lang: 'nl', value: 'Full Body Kracht'}
],
primaryCategory: 'Strength',
primaryMuscle: 'Chest'
})
};
fetch('https://api.fitsociety.io/public/v1/workout/clients/{clientId}/exercises', 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/clients/{clientId}/exercises"
payload = {
"name": [
{
"lang": "en",
"value": "Full Body Strength"
},
{
"lang": "nl",
"value": "Full Body Kracht"
}
],
"description": [
{
"lang": "en",
"value": "Full Body Strength"
},
{
"lang": "nl",
"value": "Full Body Kracht"
}
],
"primaryCategory": "Strength",
"primaryMuscle": "Chest"
}
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",
"exerciseId": "67f1234567890abcdef1234",
"exercise": {
"name": "Barbell Bench Press",
"description": "Flat horizontal press.",
"primaryCategory": "Strength",
"secondaryCategories": [
"Agility & Speed"
],
"primaryMuscle": "Chest",
"secondaryMuscles": [
"Chest"
],
"primaryJoint": "Shoulder",
"equipment": [
"Dumbbells"
],
"popularity": 82,
"difficulty": "Intermediate",
"intensity": "Above Average",
"visibility": "Everyone",
"createdAt": "2026-04-12T10:00:00.000Z",
"images": [
{
"url": "https://cdn.example.com/workouts/plan-cover.jpg",
"width": 1280,
"height": 720
}
],
"videos": [
{
"url": "https://cdn.example.com/workouts/demo.mp4",
"platform": "s3",
"videoId": "",
"thumbnail": "https://cdn.example.com/workouts/demo-thumb.jpg",
"duration": 84,
"width": 1920,
"height": 1080
}
],
"muscleActivation": {
"raw": {
"chest": 18,
"shoulders": 12,
"triceps": 8
},
"normalized": {
"chest": 18,
"shoulders": 12,
"triceps": 8
},
"maxValue": 18,
"topMuscles": [
{
"muscle": "chest",
"value": 18
}
]
}
},
"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"
Path Parameters
Client in the company bound to the Public API token.
^[a-fA-F0-9]{24}$Body
1Show child attributes
Show child attributes
[
{
"lang": "en",
"value": "Full Body Strength"
},
{ "lang": "nl", "value": "Full Body Kracht" }
]
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"
Chest, Back, Lats, Traps, Shoulders, Biceps, Triceps, Forearms, Core, Abs, Obliques, Glutes, Quads, Hamstrings, Calves, Adductors, Abductors, Hip Flexors, Full Body, Cardio / Conditioning, Neck, Lower Back "Chest"
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 ["General Fitness"]
Chest, Back, Lats, Traps, Shoulders, Biceps, Triceps, Forearms, Core, Abs, Obliques, Glutes, Quads, Hamstrings, Calves, Adductors, Abductors, Hip Flexors, Full Body, Cardio / Conditioning, Neck, Lower Back ["Shoulders", "Triceps"]
, Ankle, Combination, Core, Elbow, Fingers, Hip, Knee, Neck, Shoulder, Spine, Wrist "Shoulder"
Dumbbells, AdjustableDumbbells, Kettlebell, AdjustableKettlebell, CompetitionKettlebell, Medicineball, SlamBall, WallBall, Weightplate, BumperPlates, FractionalPlates, LoadableDumbbellHandle, Sandbag, StrongmanSandbag, Bulgarianbag, Aquabag, Aquaball, Hydrovest, MagneticBell, Macebell, SteelClub, IndianClub, Barbell, OlympicBarbell, TechniqueBar, EZBar, TrapBar, SafetySquatBar, SwissBar, CamberedBar, AxleBar, Landmine, Bench, FlatBench, AdjustableBench, InclineBench, DeclineBench, SealRowBench, HipThrustBench, BenchPressRack, SquatRack, SquatStand, PowerRack, WallMountedRack, HalfRack, SmithMachine, Monolift, JammerArms, BarbellJack, WeightTree, PlateStorage, DeadliftPlatform, Rig, StrengthMachinesPlateloaded, StrengthMachinesWeightstack, StrengthMachinesPneumatic, MultiGym, LegPressMachine, VerticalLegPressMachine, LeverageSquatMachine, LinearHackSquatMachine, BeltSquatMachine, PendulumSquatMachine, VSquatMachine, HackSquatMachine, LegExtensionMachine, LegCurlMachine, SeatedLegCurlMachine, LyingLegCurlMachine, StandingLegCurlMachine, StandingCalfRaiseMachine, SeatedCalfRaiseMachine, CalfPressMachine, HipThrustMachine, GluteDriveMachine, GluteKickbackMachine, HipExtensionMachine, HipAbductionMachine, HipAdductionMachine, ChestPressMachine, VerticalChestPressMachine, InclineChestPressMachine, DeclineChestPressMachine, IsoLateralChestPressMachine, IsoLateralInclinePressMachine, ShoulderPressMachine, IsoLateralShoulderPressMachine, MultiPressMachine, LateralRaiseMachine, RearDeltMachine, PecDeckMachine, PulloverMachine, LatPulldownMachine, IsoLateralLatPulldownMachine, AssistedPullupMachine, AssistedDipMachine, SeatedDipMachine, SeatedRowMachine, LowRowMachine, HighRowMachine, IsoLateralRowMachine, ChestSupportedRowMachine, TBarRowMachine, BicepsCurlMachine, PreacherCurlMachine, TricepsExtensionMachine, AbCrunchMachine, AbCoasterMachine, RotaryTorsoMachine, BackExtensionMachine, SeatedBackExtensionMachine, HyperextensionBench, ReverseHyper, GHD, Kinesis, Pulley, CableMachine, CableStation, CableColumn, CableCrossover, DualAdjustablePulley, SingleCableTower, FunctionalTrainer, TotalGymGTS, Gymstick, ViPR, RipTrainer, Battlerope, ProwlerSled, FarmersHandles, Yoke, Tire, Sledgehammer, TorqueTank, SledTrack, WallBallTarget, AgilityPoles, MiniHurdles, SprintParachute, PullUpBar, Parallelbars, DipBars, Equalizer, Suspensiontrainer, SuspensionSlingTrainer, GymnasticRings, MonkeyBars, PegBoard, RopeClimb, Wall, StallBars, DoorPullUpBar, PushUpHandles, AbStraps, Boxstep, SoftPlyoBox, Hurdle, Speedladder, Parallettes, NordicBench, SissySquatBench, Cardio, Treadmill, CurvedTreadmill, AirRunner, AssaultRunner, StationaryBike, UprightBike, RecumbentBike, BikeErg, SpinBike, AirBike, Rower, WaterRower, FanRower, ArmErgometer, SkiErg, Elliptical, ArcTrainer, NuStep, StairClimber, StepMill, JacobsLadder, VersaClimber, Bosu, Balanceball, Exerciseball, PilatesTennisball, PilatesRing, YogaMat, YogaBlock, YogaWheel, StretchStrap, MobilityStick, MassageBall, PeanutMassageBall, Airpad, Balanceboard, BalancePad, WobbleBoard, Glidedisc, Foamroller, Elasticbands, TherapyBand, Resistanceband, MiniBand, PullUpAssistBand, Powertube, AnkleWeights, SlantBoard, Vibrationtraining, CableRope, StraightBarAttachment, CurlBarAttachment, LatBarAttachment, TricepsBarAttachment, RowHandle, DHandle, DoubleDHandle, AnkleCuff, CableCuff, LandmineHandle, MagGripAttachment, DipBelt, AbWheel, WristRoller, FatGrip, Chain, DoorAnchor, JumpRope, SpeedRope, WeightedJumpRope, SledHarness, LiftingStraps, LiftingHooks, WristWraps, WeightliftingBelt, Clubbel, Stick, Bodybow, BuddySystem, Multinet, Flowin, Aerialhoop, Dancingpole, Trapeze, HulaHoop, Trampoline, XCO, PilatesReformer, PilatesChair, PilatesCadillac, PilatesBarrel, PilatesSpringboard, BalanceBeam, TreatmentTable, RehabTable, SlideBoard ["Barbell", "Bench"]
6
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
, Beginner, Intermediate, Advanced "Intermediate"
, Beginner, Below Average, Average, Above Average, High Intensity "Above Average"
["compound", "push"]
Everyone, Company, Fitsociety "Company"
Optional fallback tracking type for freestyle sessions.
, reps, time, distance "reps"
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"