curl -X POST "https://api.fitsociety.io/public/v1/workout/plans/moments/exercises/{planId}/{planMomentId}" \
-H "Authorization: Bearer <access_token>" \
-H "Idempotency-Key: <stable_request_key>" \
-H "Content-Type: application/json" \
-d '{}'const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({exerciseId: '67f1234567890abcdef1234', type: 'reps', sets: 4})
};
fetch('https://api.fitsociety.io/public/v1/workout/plans/moments/exercises/{planId}/{planMomentId}', 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/moments/exercises/{planId}/{planMomentId}"
payload = {
"exerciseId": "67f1234567890abcdef1234",
"type": "reps",
"sets": 4
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"data": {
"workoutExercise": {
"_id": "67f1234567890abcdef1234",
"exerciseId": "67f1234567890abcdef1234",
"type": "reps",
"minReps": 6,
"maxReps": 8,
"notes": "Pause 1 second on the chest.",
"sets": 4,
"metric": "kg",
"rest": 120,
"intensity": "High",
"difficulty": "Intermediate",
"groupId": "super-a",
"rpe": 8,
"rmPercentage": 75,
"tempo": "3010",
"perSetTrackingEnabled": true,
"rpeEnabled": false,
"showSetRpe": true,
"setsData": [
{
"setNumber": 1,
"setType": "N",
"metric": "12",
"repetition": "8-12",
"weight": 60,
"rest": 90,
"rpe": 7.5,
"duration": 45,
"distance": 250
}
],
"setupSettingsEnabled": true,
"setupFields": [
{
"key": "seat",
"label": "Seat",
"type": "text",
"unit": "",
"options": [
"1",
"2",
"3",
"4"
],
"order": 1,
"required": false,
"enabled": true,
"defaultValue": 3
}
],
"order": 0,
"isDeleted": false,
"deletedAt": null,
"createdAt": "2026-04-12T10:00:00.000Z",
"updatedAt": "2026-04-12T10:00:00.000Z"
}
},
"meta": {
"requestId": "4f849d7d-f4f1-45cc-b4b7-3984a3d17f83",
"rateLimit": {
"limit": 10,
"remaining": 9,
"resetSeconds": 1
},
"idempotency": {
"replayed": false
}
}
}Create a workout exercise inside a workout plan moment
Requires the workout_plans:write scope and the corresponding Workout features and permissions.
curl -X POST "https://api.fitsociety.io/public/v1/workout/plans/moments/exercises/{planId}/{planMomentId}" \
-H "Authorization: Bearer <access_token>" \
-H "Idempotency-Key: <stable_request_key>" \
-H "Content-Type: application/json" \
-d '{}'const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({exerciseId: '67f1234567890abcdef1234', type: 'reps', sets: 4})
};
fetch('https://api.fitsociety.io/public/v1/workout/plans/moments/exercises/{planId}/{planMomentId}', 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/moments/exercises/{planId}/{planMomentId}"
payload = {
"exerciseId": "67f1234567890abcdef1234",
"type": "reps",
"sets": 4
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"data": {
"workoutExercise": {
"_id": "67f1234567890abcdef1234",
"exerciseId": "67f1234567890abcdef1234",
"type": "reps",
"minReps": 6,
"maxReps": 8,
"notes": "Pause 1 second on the chest.",
"sets": 4,
"metric": "kg",
"rest": 120,
"intensity": "High",
"difficulty": "Intermediate",
"groupId": "super-a",
"rpe": 8,
"rmPercentage": 75,
"tempo": "3010",
"perSetTrackingEnabled": true,
"rpeEnabled": false,
"showSetRpe": true,
"setsData": [
{
"setNumber": 1,
"setType": "N",
"metric": "12",
"repetition": "8-12",
"weight": 60,
"rest": 90,
"rpe": 7.5,
"duration": 45,
"distance": 250
}
],
"setupSettingsEnabled": true,
"setupFields": [
{
"key": "seat",
"label": "Seat",
"type": "text",
"unit": "",
"options": [
"1",
"2",
"3",
"4"
],
"order": 1,
"required": false,
"enabled": true,
"defaultValue": 3
}
],
"order": 0,
"isDeleted": false,
"deletedAt": null,
"createdAt": "2026-04-12T10:00:00.000Z",
"updatedAt": "2026-04-12T10:00:00.000Z"
}
},
"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
Workout plan id.
"67f1234567890abcdef1234"
Embedded workout plan-moment id.
"67f1234567890abcdef1234"
Body
"67f1234567890abcdef1234"
reps, time, distance "reps"
4
6
8
"Pause 1 second on the chest."
"kg"
120
Low, Medium, High "High"
Beginner, Intermediate, Advanced "Intermediate"
"super-a"
8
75
"3010"
true
Master RPE switch for this plan exercise. False hides current targets and inputs without clearing prescriptions or recorded history. Missing legacy values retain RPE when an exercise target or per-set preference exists. Independent from showSetRpe.
false
Stored per-set RPE preference. Live input is visible only when RPE is enabled; authoring retains this preference while rpeEnabled is false.
true
Show child attributes
Show child attributes
Enables the exercise-level machine or equipment setup settings block.
true
8Show child attributes
Show child attributes
0