curl -X PATCH "https://api.fitsociety.io/public/v1/workout/plans/template/{planId}/days/reorder" \
-H "Authorization: Bearer <access_token>" \
-H "Idempotency-Key: <stable_request_key>" \
-H "Content-Type: application/json" \
-d '{}'const options = {
method: 'PATCH',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
planMomentIds: [
'69e87ccf47a7d03bb5b5ab57',
'69e87ccf47a7d03bb5b5ab58',
'69e87ccf47a7d03bb5b5ab59'
]
})
};
fetch('https://api.fitsociety.io/public/v1/workout/plans/template/{planId}/days/reorder', 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/template/{planId}/days/reorder"
payload = { "planMomentIds": ["69e87ccf47a7d03bb5b5ab57", "69e87ccf47a7d03bb5b5ab58", "69e87ccf47a7d03bb5b5ab59"] }
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text){
"data": {
"planId": "67f1234567890abcdef1234",
"templateType": "Template",
"dayCount": 3,
"days": [
{
"planMomentId": "67f1234567890abcdef1234",
"name": "Upper Body",
"dayOrder": 1,
"order": 1,
"weekNumber": 1,
"sessionOrder": 1
}
]
},
"meta": {
"requestId": "4f849d7d-f4f1-45cc-b4b7-3984a3d17f83",
"rateLimit": {
"limit": 10,
"remaining": 9,
"resetSeconds": 1
},
"idempotency": {
"replayed": false
}
}
}Reorder the days of a workout plan
Reorder the DAYS (plan moments) of a plan the caller owns. Resolves the plan through the shared plan authorization scope, so it covers a library Template as well as an Assigned copy — unlike PATCH /app/v1/workout/plans/client/template/{templateId}/reorder-days, which is pinned to templateType: "Assigned" plus a clientId and therefore answers TEMPLATE_NOT_FOUND for a Template.
planMomentIds must be an exact permutation of the plan’s ACTIVE (non-deleted, non-archived) days; each one’s dayOrder becomes its index. Archived days are excluded from the permutation and stay pinned after the active days. sessionOrder is renumbered 1..n within each day’s own weekNumber alongside dayOrder, because reads sort by weekNumber → sessionOrder → dayOrder — without it the plan’s normalizer would sort the days straight back on save.
Requires the workout_plans:write scope. This operation maps to /app/v1/workout/plans/template/:planId/days/reorder and retains its Workout V2 permission, feature-flag, and resource-scope checks.
The clientId path parameter is resolved inside the company bound to the Public API token when present.
curl -X PATCH "https://api.fitsociety.io/public/v1/workout/plans/template/{planId}/days/reorder" \
-H "Authorization: Bearer <access_token>" \
-H "Idempotency-Key: <stable_request_key>" \
-H "Content-Type: application/json" \
-d '{}'const options = {
method: 'PATCH',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
planMomentIds: [
'69e87ccf47a7d03bb5b5ab57',
'69e87ccf47a7d03bb5b5ab58',
'69e87ccf47a7d03bb5b5ab59'
]
})
};
fetch('https://api.fitsociety.io/public/v1/workout/plans/template/{planId}/days/reorder', 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/template/{planId}/days/reorder"
payload = { "planMomentIds": ["69e87ccf47a7d03bb5b5ab57", "69e87ccf47a7d03bb5b5ab58", "69e87ccf47a7d03bb5b5ab59"] }
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text){
"data": {
"planId": "67f1234567890abcdef1234",
"templateType": "Template",
"dayCount": 3,
"days": [
{
"planMomentId": "67f1234567890abcdef1234",
"name": "Upper Body",
"dayOrder": 1,
"order": 1,
"weekNumber": 1,
"sessionOrder": 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
Workout plan id (Template or Assigned).
"67f1234567890abcdef1234"
Body
Every ACTIVE plan-moment _id, in the new top-to-bottom order.
1[
"69e87ccf47a7d03bb5b5ab57",
"69e87ccf47a7d03bb5b5ab58",
"69e87ccf47a7d03bb5b5ab59"
]