curl -X GET "https://api.fitsociety.io/public/v1/workout/cardio/clients/{clientId}/plans/{planId}/adaptation/overview" \
-H "Authorization: Bearer <access_token>"const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.fitsociety.io/public/v1/workout/cardio/clients/{clientId}/plans/{planId}/adaptation/overview', 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/cardio/clients/{clientId}/plans/{planId}/adaptation/overview"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"data": {
"planId": "66f7b8b1e13c8d25f4d3d90a",
"expectedUpdatedAt": "2026-07-14T10:00:00.000Z",
"reviewWeek": 1,
"due": true,
"lastReviewedWeek": 1,
"adaptationRevision": 1,
"niggleActive": true,
"today": "2026-07-14"
},
"meta": {
"requestId": "4f849d7d-f4f1-45cc-b4b7-3984a3d17f83",
"rateLimit": {
"limit": 10,
"remaining": 9,
"resetSeconds": 1
}
}
}{
"error": {
"code": 400,
"key": "request.invalid",
"message": "The request is invalid."
},
"meta": {
"requestId": "4f849d7d-f4f1-45cc-b4b7-3984a3d17f83",
"rateLimit": {
"limit": 10,
"remaining": 9,
"resetSeconds": 1
}
}
}{
"error": {
"code": 403,
"key": "scopes.insufficient",
"message": "The access token does not include the required scope.",
"details": {
"requiredScopes": [
"required:scope"
]
}
},
"meta": {
"requestId": "4f849d7d-f4f1-45cc-b4b7-3984a3d17f83",
"rateLimit": {
"limit": 10,
"remaining": 9,
"resetSeconds": 1
}
}
}{
"error": {
"code": 404,
"key": "resource.not_found",
"message": "The requested Public API resource was not found."
},
"meta": {
"requestId": "4f849d7d-f4f1-45cc-b4b7-3984a3d17f83",
"rateLimit": {
"limit": 10,
"remaining": 9,
"resetSeconds": 1
}
}
}{
"error": {
"code": 500,
"key": "server.internal_error",
"message": "An unexpected Public API server error occurred."
},
"meta": {
"requestId": "4f849d7d-f4f1-45cc-b4b7-3984a3d17f83",
"rateLimit": {
"limit": 10,
"remaining": 9,
"resetSeconds": 1
}
}
}Read the next due review and plan revision
Requires all cardio company gates and client Training V2. Staff reads/writes enforce linked-client member scope and training.programmes.view/update. Apply requires expectedUpdatedAt from preview and explicit complete prescriptions. Changes are transactional, preserve historical logs, IDs, unrelated activities and weekly volume limits. Goal time/challenge may change; distance/race date require a new plan. Undo uses stored server patches, requires the latest unchanged plan and no affected execution or past sessions, and cannot restore intensity during an active athlete niggle. Worker queues coach reviews rather than inventing prescription inputs. Undo intentionally accepts an empty body.
Requires the workout_client_plans:read scope. This operation maps to /app/v1/workout/cardio/clients/:clientId/plans/:planId/adaptation/overview 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 GET "https://api.fitsociety.io/public/v1/workout/cardio/clients/{clientId}/plans/{planId}/adaptation/overview" \
-H "Authorization: Bearer <access_token>"const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.fitsociety.io/public/v1/workout/cardio/clients/{clientId}/plans/{planId}/adaptation/overview', 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/cardio/clients/{clientId}/plans/{planId}/adaptation/overview"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"data": {
"planId": "66f7b8b1e13c8d25f4d3d90a",
"expectedUpdatedAt": "2026-07-14T10:00:00.000Z",
"reviewWeek": 1,
"due": true,
"lastReviewedWeek": 1,
"adaptationRevision": 1,
"niggleActive": true,
"today": "2026-07-14"
},
"meta": {
"requestId": "4f849d7d-f4f1-45cc-b4b7-3984a3d17f83",
"rateLimit": {
"limit": 10,
"remaining": 9,
"resetSeconds": 1
}
}
}{
"error": {
"code": 400,
"key": "request.invalid",
"message": "The request is invalid."
},
"meta": {
"requestId": "4f849d7d-f4f1-45cc-b4b7-3984a3d17f83",
"rateLimit": {
"limit": 10,
"remaining": 9,
"resetSeconds": 1
}
}
}{
"error": {
"code": 403,
"key": "scopes.insufficient",
"message": "The access token does not include the required scope.",
"details": {
"requiredScopes": [
"required:scope"
]
}
},
"meta": {
"requestId": "4f849d7d-f4f1-45cc-b4b7-3984a3d17f83",
"rateLimit": {
"limit": 10,
"remaining": 9,
"resetSeconds": 1
}
}
}{
"error": {
"code": 404,
"key": "resource.not_found",
"message": "The requested Public API resource was not found."
},
"meta": {
"requestId": "4f849d7d-f4f1-45cc-b4b7-3984a3d17f83",
"rateLimit": {
"limit": 10,
"remaining": 9,
"resetSeconds": 1
}
}
}{
"error": {
"code": 500,
"key": "server.internal_error",
"message": "An unexpected Public API server error occurred."
},
"meta": {
"requestId": "4f849d7d-f4f1-45cc-b4b7-3984a3d17f83",
"rateLimit": {
"limit": 10,
"remaining": 9,
"resetSeconds": 1
}
}
}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.