{"openapi":"3.0.0","paths":{"/v1/workouts/metadata":{"get":{"operationId":"WorkoutsApi_getWorkoutMetadata","summary":"Get available workout categories and difficulties","description":"\n## Workout categories & difficulties\n\nReturns category ids/names and difficulty strings for filters and AI generate `categoryId`.\n\n**Try it:** `GET /v1/workouts/metadata` with `X-Api-Key`. Optional `locale`.\n\n**Related:** `GET /v1/workouts/equipment/metadata`, `GET /v1/workouts/exercises/metadata`, `POST /v1/orgs/{orgId}/workouts/generate`.\n    ","parameters":[{"name":"locale","required":false,"in":"query","description":"Preferred language locale (e.g., fr-FR)","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved category and difficulty lists.","content":{"application/json":{"schema":{"type":"object","properties":{"categories":{"type":"array","description":"List of all available workout categories.","items":{"type":"object","properties":{"id":{"type":"string","description":"Category ID","example":"615aa3f0dbe7140012c59e94"},"name":{"type":"string","description":"Category display name","example":"HIIT"}},"required":["id","name"]}},"difficulties":{"type":"array","description":"List of all available difficulty levels.","items":{"type":"string","example":"intermediate"}}},"example":{"categories":[{"id":"615aa3f0dbe7140012c59e94","name":"HIIT"},{"id":"615aa3dadbe7140012c59e90","name":"Strength"},{"id":"615aa3e5dbe7140012c59e92","name":"Mobility"}],"difficulties":["beginner","intermediate","advanced"]}}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["workouts"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/workouts/metadata' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getWorkoutMetadata() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/workouts/metadata', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/workouts/metadata\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/workouts/equipment/metadata":{"get":{"operationId":"WorkoutsApi_getEquipmentMetadata","summary":"Get available equipment categories and equipment items","description":"\n## Equipment metadata\n\nReturns equipment categories and items for filters and generate `preferredEquipmentCategoryIds`.\n\n**Try it:** `GET /v1/workouts/equipment/metadata` with `X-Api-Key`. Optional `locale`.\n\n**Related:** `GET /v1/workouts/metadata`, `POST /v1/orgs/{orgId}/workouts/generate`.\n    ","parameters":[{"name":"locale","required":false,"in":"query","description":"Preferred language locale (e.g., fr-FR)","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved equipment and category lists.","content":{"application/json":{"schema":{"type":"object","properties":{"categories":{"type":"array","description":"List of all available equipment categories.","items":{"type":"object","properties":{"id":{"type":"string","description":"Category ID","example":"67deb36a6a5e49797c122f56"},"name":{"type":"string","description":"Category display name","example":"Bodyweight"},"category":{"type":"string","description":"Broader category grouping","example":"bodyweight"}},"required":["id","name","category"]}},"equipment":{"type":"array","description":"List of all available equipment items.","items":{"type":"object","properties":{"id":{"type":"string","description":"Equipment ID","example":"60812dea606fc90011eb4405"},"name":{"type":"string","description":"Equipment display name","example":"Dumbbell"},"equipmentCategoryId":{"type":"string","description":"ID of the category this equipment belongs to (optional)","example":"67deb3696a5e49797c122f55","nullable":true}},"required":["id","name"]}}},"example":{"categories":[{"id":"67deb36a6a5e49797c122f56","name":"Bodyweight","category":"bodyweight"},{"id":"67deb3696a5e49797c122f55","name":"Free Weights","category":"free_weights"},{"id":"67deb36a6a5e49797c122f57","name":"Gym Equipment","category":"gym"}],"equipment":[{"id":"60812dea606fc90011eb4405","name":"Dumbbell","equipmentCategoryId":"67deb3696a5e49797c122f55"},{"id":"60812dd5606fc90011eb4404","name":"Kettlebell","equipmentCategoryId":"67deb3696a5e49797c122f55"},{"id":"60812e08606fc90011eb4408","name":"Mat","equipmentCategoryId":"67deb36a6a5e49797c122f56"}]}}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["workouts"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/workouts/equipment/metadata' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getEquipmentMetadata() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/workouts/equipment/metadata', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/workouts/equipment/metadata\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/workouts/{workoutId}":{"get":{"operationId":"WorkoutsApi_getWorkout","summary":"Get workout details","description":"\n## Workout details\n\nFull document for a **persisted** workout id, wrapped as `{ data: { id, name, duration, difficulty, categories, equipment, muscleGroupPercentages, preview, mixBgMusic, videoAudioMode, ... } }`.\n\n**Try it:** `GET /v1/workouts/{workoutId}` with `X-Api-Key`. Optional `locale` for localized display fields.\n\n**Related:** `GET /v1/workouts/{id}/playlist`, `GET /v1/workouts/{id}/music`, `GET /v1/orgs/{orgId}/workouts`.\n    ","parameters":[{"name":"workoutId","required":true,"in":"path","description":"The unique identifier (24-character hex string) of the workout to retrieve.","example":"12ab3efd45c67c1234566cd1","schema":{"type":"string"}},{"name":"locale","required":false,"in":"query","description":"Preferred language locale (e.g., fr-FR)","schema":{"type":"string"}}],"responses":{"200":{"description":"Workout details retrieved successfully.","schema":{"example":{"data":{"id":"12ab3efd45c67c1234566cd1","name":"Full Body HIIT Power","description":"A high-intensity interval training session targeting full body strength and cardiovascular fitness","duration":1800,"difficulty":"intermediate","visibility":"public","locked":false,"createdAt":"2023-10-26T10:00:00.000Z","updatedAt":"2023-10-27T11:30:00.000Z","trainer":{"id":"64f1a2b3c4d5e6f7a8b9c0d4","name":"Sarah Johnson"},"categories":[{"id":"615aa3f0dbe7140012c59e94","name":"HIIT"},{"id":"615aa3ebdbe7140012c59e93","name":"Cardio"}],"equipment":[{"id":"60812dea606fc90011eb4405","name":"Dumbbell","equipmentCategoryId":"67deb3696a5e49797c122f55"},{"id":"60812e08606fc90011eb4408","name":"Mat","equipmentCategoryId":"67deb36a6a5e49797c122f56"}],"muscleGroupPercentages":[{"muscleGroupId":"604b0129beaba770c284ff40","muscleGroupName":"Arms","percentage":25.5},{"muscleGroupId":"604b0169076fe2727354d740","muscleGroupName":"Chest","percentage":20},{"muscleGroupId":"604b0177076fe2727354d743","muscleGroupName":"Legs","percentage":30},{"muscleGroupId":"604b0170076fe2727354d741","muscleGroupName":"Core","percentage":24.5}],"preview":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/workout-preview.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://images.hyperhuman.cc/workout-poster.jpg","thumbnail":"https://images.hyperhuman.cc/workout-thumb.jpg"},"audioIntro":null,"audioOutro":null,"musicPlaylists":{"spotify":{"url":"https://open.spotify.com/playlist/37i9dQZF1DX76Wlfdnj7AP"},"youtube":null,"appleMusic":null,"amazonMusic":null},"shareLink":{"url":"https://app.hyperhuman.cc/workouts/12ab3efd45c67c1234566cd1"},"organization":null,"rating":4.5,"mixBgMusic":true,"presentationStyle":"full","skipWorkoutPreview":false,"skipWorkoutCompletionScreen":false,"videoAudioMode":"full","allowAssessment":false,"assessmentType":null}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutResponse"}}}},"401":{"description":"Authentication failed - API key is missing, invalid, or Bearer token is missing/invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The specified workout ID does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["workouts"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getWorkout() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/workouts/{workoutId}/export/video/stream_url":{"get":{"operationId":"WorkoutsApi_getExportVideoStream","summary":"Get complete workout video export URL","description":"\n## Full workout video export\n\nReturns a presigned URL to the full-workout video export for a persisted workout id.\n\n**Response:** **200** `Content-Type: text/plain` — body is a **single** URL string (not JSON), valid ~**7 days**. Linked asset matches the stored render (commonly MP4).\n\n**Locale:** omit → latest available export; provide `locale` → exact locale only (**404** if that locale is not rendered — no English fallback). Still processing / missing → **404** (typically 2–5 minutes after create).\n\n**Rate limit:** **10x**. Prefer `/playlist` for interactive segment playback.\n\n**Related:** `GET /v1/workouts/{id}`, `GET /v1/workouts/{id}/playlist`, `GET /v1/workouts/{id}/export/audio/stream_url`.\n    ","parameters":[{"name":"workoutId","required":true,"in":"path","description":"The unique identifier of the workout.","example":"12ab3efd45c67c1234566cd1","schema":{"type":"string"}},{"name":"locale","required":false,"in":"query","description":"Language locale (e.g., de-DE, fr-FR, en-US). When omitted, the latest available export is returned. When provided, only the exact-locale export is returned; if it does not exist the endpoint returns 404 (no en-US/default fallback).","example":"en-US","schema":{"type":"string"}}],"responses":{"200":{"description":"text/plain body: a single presigned HTTPS URL to the full video export (valid 7 days). Format of the linked asset matches the stored render (commonly MP4; see operation description).","content":{"application/json":{"schema":{"type":"string"}}}},"401":{"description":"Authentication failed - API key is missing, invalid, or Bearer token is missing/invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Workout not found, video export not available for the requested locale, or video is still being generated (processing typically takes 2-5 minutes after workout creation).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["workouts"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/export/video/stream_url' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getExportVideoStream() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/export/video/stream_url', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/export/video/stream_url\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/workouts/{workoutId}/export/audio/stream_url":{"get":{"operationId":"WorkoutsApi_getExportAudioStream","summary":"Get audio-only workout export URL","description":"\n## Full workout audio export\n\nReturns a presigned URL to the full narrative audio export for a persisted workout id.\n\n**Response:** **200** `Content-Type: text/plain` — body is a **single** URL string (not JSON), valid ~**7 days** (commonly M4A).\n\n**Locale:** omit → resolve with the trainer **preferred locale** (language-family fallback within that language; never cross-language). Provide `locale` → exact match, then same-language family; missing / still processing → **404** (not the same as video export’s “latest any locale / exact-or-404”).\n\n**Rate limit:** **10x**.\n\n**Related:** `GET /v1/workouts/{id}/export/video/stream_url`, `GET /v1/workouts/{id}/playlist`, `GET /v1/workouts/{id}`.\n    ","parameters":[{"name":"workoutId","required":true,"in":"path","description":"The unique identifier of the workout.","example":"12ab3efd45c67c1234566cd1","schema":{"type":"string"}},{"name":"locale","required":false,"in":"query","description":"Language locale for audio narration (e.g., de-DE, fr-FR, en-US). When omitted, uses the trainer preferred locale with same-language family fallback. When provided, exact then family match; if none exists → 404 (never falls back to another language). Differs from video export locale rules.","example":"en-US","schema":{"type":"string"}}],"responses":{"200":{"description":"text/plain body: a single presigned HTTPS URL to the full narrative audio export (valid 7 days; commonly M4A/AAC).","content":{"application/json":{"schema":{"type":"string"}}}},"401":{"description":"Authentication failed - API key is missing, invalid, or Bearer token is missing/invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Workout not found, audio export not available for the requested locale, or audio is still being generated (processing typically takes 1-3 minutes after workout creation).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["workouts"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/export/audio/stream_url' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getExportAudioStream() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/export/audio/stream_url', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/export/audio/stream_url\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/workouts/exercises/metadata":{"get":{"operationId":"WorkoutsApi_getExercisesMetadata","summary":"Get available muscle groups and exercise collections","description":"\n## Muscle groups & exercise collections\n\nReturns muscle group ids/names and collection names/counts for generate `muscleGroupIds` / `excludeExerciseCollections`.\n\n**Try it:** `GET /v1/workouts/exercises/metadata` with `X-Api-Key`. Optional `locale`.\n\n**Related:** `GET /v1/workouts/metadata`, `POST /v1/orgs/{orgId}/workouts/generate`.\n    ","parameters":[{"name":"locale","required":false,"in":"query","description":"Preferred language locale (e.g., fr-FR)","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved list of muscle groups and exercise collections.","content":{"application/json":{"schema":{"type":"object","properties":{"muscleGroups":{"type":"array","description":"List of all available muscle groups.","items":{"type":"object","properties":{"id":{"type":"string","description":"Muscle group ID","example":"604b0129beaba770c284ff40"},"name":{"type":"string","description":"Muscle group display name","example":"Arms"}},"required":["id","name"]}},"collections":{"type":"array","description":"List of all available exercise collections with exercise counts.","items":{"type":"object","properties":{"name":{"type":"string","description":"Collection name","example":"Premium - Neutral"},"count":{"type":"number","description":"Number of exercises in this collection","example":808}},"required":["name","count"]}}},"example":{"muscleGroups":[{"id":"604b0129beaba770c284ff40","name":"Arms"},{"id":"604b0169076fe2727354d740","name":"Chest"},{"id":"604b0177076fe2727354d743","name":"Legs"}],"collections":[{"name":"Premium - Neutral","count":808},{"name":"Premium - Industrial","count":200},{"name":"Free - Eclectic Home","count":239}]}}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["workouts"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/workouts/exercises/metadata' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getExercisesMetadata() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/workouts/exercises/metadata', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/workouts/exercises/metadata\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/workouts":{"get":{"operationId":"OrganizationWorkoutsApi_getOrganizationWorkouts","summary":"List organization-specific workouts","description":"\n## Organization Workout Library\n\nPaginated list of **published** workouts for your organization (workspace).\n\n**Try it (minimal):** `GET /v1/orgs/{organizationId}/workouts?limit=20` with header `X-Api-Key`. Use your organization id from **Settings → Integrations**. Leave optional filters empty on the first call.\n\n**Pagination:** `limit` (default **20**, max **50**). Follow `links.next` in the response to advance pages.\n\n**Optional filters:** `visibility` (`all` default), `difficulty`, `categoryIds` (comma-separated hex ids from `GET /v1/workouts/metadata`), `duration` (`min-max` minutes), `q`, `sort` (`+` / `-` prefix, e.g. `-createdAt`), `allowAssessment`, `locale`.\n\n**Related:** `POST /v1/orgs/{orgId}/workouts/generate`, `POST /v1/orgs/{orgId}/workouts/recommend`, `GET /v1/workouts/{id}`, `GET /v1/workouts/metadata`.\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"Unique organization (workspace) resource id — opaque 24-character hex string. Use the organization id from Settings → Integrations.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Maximum number of items to return per page.","example":20,"schema":{"minimum":1,"maximum":50,"default":20,"type":"number"}},{"name":"q","required":false,"in":"query","description":"Search text","schema":{"type":"string"}},{"name":"sort","required":false,"in":"query","description":"Fields to sort. Prefix them with - (descending) or + (ascending): +someField,-otherField","schema":{"type":"string"}},{"name":"locale","required":false,"in":"query","description":"BCP-47 locale (e.g. en-US, fr-FR). Localizes text and locale-aware media when this operation supports it. Falls back to English when unsupported.","example":"en-US","schema":{"type":"string"}},{"name":"visibility","required":false,"in":"query","description":"Filter workouts by their visibility status. Defaults to `all` when omitted (private and public).","schema":{"enum":["private","public","all"],"type":"string"}},{"name":"difficulty","required":false,"in":"query","description":"Filter workouts by difficulty level.","schema":{"enum":["beginner","intermediate","advanced"],"type":"string"}},{"name":"categoryIds","required":false,"in":"query","description":"Filter workouts by one or more workout category IDs (comma-separated 24-character hex DB ids). Discover ids via `GET /v1/workouts/metadata`. Optional tokens prefixed with `custom:` are filtered in memory (e.g. `custom:duration_short`).","schema":{"type":"string"}},{"name":"duration","required":false,"in":"query","description":"Filter workouts by duration range in minutes. Use \"min-max\" (e.g., \"10-30\") or an open-ended range like \"60-\" (60+ min) or \"-30\" (up to 30 min).","schema":{"pattern":"^(\\d+-\\d*|\\d*-\\d+)$","type":"string"}},{"name":"allowAssessment","required":false,"in":"query","description":"Filter workouts by assessment support","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Successfully retrieved paginated list of workouts for the organization.","schema":{"example":{"data":[{"id":"64f1a2b3c4d5e6f7a8b9c0d1","trainer":{"id":"64f1a2b3c4d5e6f7a8b9c0d4","name":"Sarah Johnson"},"createdAt":"2025-09-15T10:30:00.000Z","updatedAt":"2025-09-16T08:00:00.000Z","name":"Morning Power HIIT","description":"High-intensity intervals to start your day","duration":1800,"difficulty":"intermediate","visibility":"public","categories":[{"id":"615aa3f0dbe7140012c59e94","name":"HIIT"}],"preview":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/morning-hiit.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://images.hyperhuman.cc/morning-hiit-poster.jpg","thumbnail":"https://images.hyperhuman.cc/morning-hiit-poster.jpg"},"rating":4.6,"locked":false,"mixBgMusic":true,"presentationStyle":"full","skipWorkoutPreview":false,"skipWorkoutCompletionScreen":false,"videoAudioMode":"full","allowAssessment":false,"assessmentType":null}],"links":{"next":"https://content.api.hyperhuman.cc/v1/orgs/63415bf67a9c7000126616c1/workouts?offset=20&limit=20","total":45}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutListResponse"}}}},"400":{"description":"Invalid pagination or filter parameters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The specified organization ID does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["workouts"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"Minimal","source":"curl -s 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/workouts?limit=20' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"curl","label":"With filters","source":"curl -s 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/workouts?limit=20&visibility=public&difficulty=intermediate&categoryIds=615aa3f0dbe7140012c59e94&duration=20-30&q=HIIT' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getOrganizationWorkouts() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/workouts?limit=20', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/workouts?limit=20\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/workouts/recommend":{"post":{"operationId":"OrganizationWorkoutRecommendation_getWorkoutRecommendations","summary":"Get workout recommendations from existing library","description":"\n## Recommend workouts from your library\n\nRanks **existing published workouts** in your organization library for a user profile. Use this when your team already creates workouts and you want to pair the best match (e.g. after a quiz). For a brand-new workout structure, use `POST .../workouts/generate` instead.\n\n**Try it (minimal):** body `{ \"endUserProfileDetails\": { \"age\": 30, \"fitnessLevels\": [\"beginner\"] } }` with header `X-Api-Key`. Response is a bare object `{ workouts, reasoning }` (not wrapped in `data`). Up to **12** workouts; each item includes a `recommendation` text reason (not a numeric score).\n\n**Body:** only `endUserProfileDetails` and optional `locale` — unknown keys return `400 ValidationError`.\n\n**Rate limit:** counts as **10x** toward hourly/daily limits.\n\n**Related:** `POST /v1/orgs/{orgId}/workouts/generate`, `GET /v1/orgs/{orgId}/workouts`, `GET /v1/workouts/metadata`, `GET /v1/workouts/{id}`.\n        ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"Organization/Team unique identifier","example":"67e2e9d0e23f010013e19dec","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutRecommendationRequestDto"},"examples":{"minimal":{"summary":"Minimal profile","value":{"endUserProfileDetails":{"age":30,"fitnessLevels":["beginner"],"gender":"female"}}}}}}},"responses":{"200":{"description":"Ranked list of recommended workouts with per-item recommendation text and overall reasoning","schema":{"example":{"workouts":[{"id":"6a3cf00b9fe2d4001a58d605","name":"Beginner Flow & Core Pilates","description":"","duration":1185,"difficulty":"beginner","thumbnailUrl":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/poster_a_720p.jpg","recommendation":"Sculpt your core and legs with this beginner-friendly pilates flow.","categories":[{"id":"615aa3f5dbe7140012c59e95","name":"Pilates"}],"preview":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/preview.mp4","poster":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/poster_a_720p.jpg","thumbnail":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/poster_a_720p.jpg"}}],"reasoning":"Workouts recommended based on your profile and preferences."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutRecommendationResponseDto"}}}},"401":{"description":"Unauthorized - Invalid API key"},"404":{"description":"Organization/Team not found"}},"tags":["ai-recommendation"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/workouts/recommend' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getWorkoutRecommendations() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/workouts/recommend', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/workouts/recommend\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/workouts/generate":{"post":{"operationId":"OrganizationWorkoutGeneration_generateWorkout","summary":"Generate personalized on-the-fly workouts based on user profile details, duration preferences, and exercise sources.","description":"\n## Generate a workout\n\nCreates an AI workout from profile, `categoryId`, duration options, and exercise sources. Prefer `POST .../workouts/recommend` when you only need a match from your existing library.\n\n**Playback / storage:** Response is **ephemeral JSON** (`name`, `instances[]` with `kind` `single-exercise`|`rest`, `totalDurationSeconds`, …) with **no top-level persisted workout `id`**. Not listed by `GET /v1/orgs/{orgId}/workouts`. Play via the JSON-receiver embed (`/embed/workout-json-receiver` + `HYPERHUMAN_EMBED_INIT`) or a custom player; the embed resolves media via `GET /v1/video-asset/{exerciseId}`. Do **not** call `/playlist` or `/music` (need a persisted id). JSON-receiver has **no** PulseMix and **no** session/feedback tracking — use the pre-built `/embed/workout/{id}` for those. Persist the JSON yourself if you need replay/audit later. See API overview **Embedded Player**.\n\n**Try it (minimal):** body `{ \"endUserProfileDetails\": { \"age\": 28, \"fitnessLevels\": [\"beginner\"] }, \"exerciseSources\": [\"premium_stock\"], \"durationOptions\": { \"minMinutes\": 10, \"maxMinutes\": 15 }, \"categoryId\": \"<from GET /v1/workouts/metadata>\" }` with `X-Api-Key`.\n\n**Sources:** `premium_stock` (production), `free_stock` (dev/test), `team_exercises` (your catalog). Omit → free+premium stock. Prefer `premium_stock` or `team_exercises` alone in production.\n\n**Exercise collections:** optional `includeExerciseCollections` (allowlist — only these `collectionName` values) or `excludeExerciseCollections` (denylist). Mutually exclusive — both non-empty → `400`. Compose with `exerciseSources` (AND). Prefer **include** to lock trainer/location/brand look; do not simulate include by excluding every other collection. Discover names via `GET /v1/workouts/exercises/metadata`. Filtered pool must have ≥ 10 exercises or request returns `400`.\n\n**Localization:** optional body `locale` (BCP-47). Unsupported → `400`. Additive `*Localized` / `nameTranslations` / `difficultyLabel` when non-English; legacy `name` / `difficulty` stay English.\n\n**Rate limit:** counts as **10x**.\n\n**Related:** `POST /v1/orgs/{orgId}/workouts/recommend`, `POST /v1/orgs/{orgId}/workouts/{workoutId}/adapt`, `GET /v1/video-asset/{id}`, `GET /v1/workouts/metadata`, `GET /v1/workouts/exercises/metadata`.\n","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"67e2e9d0e23f010013e19dec","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Workout generation request with user profile and preferences.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutGenerationRequestDto"},"examples":{"beginner-hiit-20min":{"summary":"Beginner HIIT - 20 Minutes","description":"Full-body HIIT workout for beginners with minimal equipment","value":{"endUserProfileDetails":{"age":28,"gender":"female","fitnessLevels":["beginner"],"trainingDaysPerWeek":3,"preferredEquipmentCategoryIds":["67deb36a6a5e49797c122f56"]},"exerciseSources":["premium_stock"],"durationOptions":{"minMinutes":15,"maxMinutes":20},"categoryId":"615aa3f0dbe7140012c59e94"}},"advanced-strength-upper-body":{"summary":"Advanced Strength - Upper Body Focus","description":"Advanced strength training targeting chest, arms, and shoulders with free weights","value":{"endUserProfileDetails":{"age":35,"gender":"male","fitnessLevels":["advanced"],"trainingDaysPerWeek":5,"preferredEquipmentCategoryIds":["67deb3696a5e49797c122f55"]},"exerciseSources":["premium_stock"],"durationOptions":{"minMinutes":30,"maxMinutes":45},"categoryId":"615aa3dadbe7140012c59e90","muscleGroupIds":["604b0169076fe2727354d740","604b0129beaba770c284ff40","604b0165076fe2727354d73e"],"excludeExerciseCollections":["Free - Outdoor"]}},"intermediate-mobility-recovery":{"summary":"Intermediate Mobility & Recovery","description":"Low-intensity mobility workout for active recovery","value":{"endUserProfileDetails":{"age":42,"gender":"female","fitnessLevels":["intermediate"],"trainingDaysPerWeek":4,"preferredEquipmentCategoryIds":["67deb36a6a5e49797c122f56"]},"exerciseSources":["premium_stock"],"durationOptions":{"minMinutes":10,"maxMinutes":15},"categoryId":"615aa3e5dbe7140012c59e92","userRequirements":"Focus on low-impact movements. Emphasize flexibility and joint mobility. Avoid high-intensity exercises."}},"team-branded-workout":{"summary":"Custom Team Exercises Only","description":"Use your organization's exercises for complete brand alignment","value":{"endUserProfileDetails":{"age":30,"gender":"male","fitnessLevels":["intermediate"],"trainingDaysPerWeek":3,"preferredEquipmentCategoryIds":["67deb3696a5e49797c122f55"]},"exerciseSources":["team_exercises"],"durationOptions":{"minMinutes":20,"maxMinutes":30},"categoryId":"615aa3f0dbe7140012c59e94"}},"team-branded-single-collection":{"summary":"Same trainer / location (include collections)","description":"Restrict the AI pool to one or more team exercise collections so every clip shares the same trainer and filming location. Prefer includeExerciseCollections over excluding every other collection.","value":{"endUserProfileDetails":{"age":30,"gender":"female","fitnessLevels":["intermediate"],"trainingDaysPerWeek":3,"preferredEquipmentCategoryIds":["67deb36a6a5e49797c122f56"]},"exerciseSources":["team_exercises"],"includeExerciseCollections":["Coach Mia - Loft"],"durationOptions":{"minMinutes":20,"maxMinutes":30},"categoryId":"615aa3f0dbe7140012c59e94"}},"cardio-legs-focus":{"summary":"Cardio with Legs Focus","description":"Cardio workout emphasizing leg muscles","value":{"endUserProfileDetails":{"age":26,"gender":"female","fitnessLevels":["intermediate"],"trainingDaysPerWeek":4,"preferredEquipmentCategoryIds":["67deb36a6a5e49797c122f56"]},"exerciseSources":["premium_stock"],"durationOptions":{"minMinutes":25,"maxMinutes":35},"categoryId":"615aa3ebdbe7140012c59e93","muscleGroupIds":["604b0177076fe2727354d743","604b0173076fe2727354d742"],"excludeExerciseCollections":["Premium - Industrial"]}},"complete-all-parameters":{"summary":"Complete Example - All Parameters","description":"Real-world example with ALL available parameters filled out to demonstrate the full API capability. This shows every possible field that can be included in a workout generation request.","value":{"endUserProfileDetails":{"age":32,"gender":"male","fitnessLevels":["intermediate","advanced"],"goalIds":["63c92926f920a9005c4e619c","63c92926f920a9005c4e619d"],"trainingDaysPerWeek":5,"preferredEquipmentCategoryIds":["67deb36a6a5e49797c122f56","67deb3696a5e49797c122f55"],"endUserId":"64e3bca9d1b7e600141a9712"},"exerciseSources":["premium_stock","team_exercises"],"durationOptions":{"minMinutes":30,"maxMinutes":45},"categoryId":"615aa3dadbe7140012c59e90","muscleGroupIds":["604b0169076fe2727354d740","604b0129beaba770c284ff40","604b0165076fe2727354d73e","604b016c076fe2727354d740","604b0170076fe2727354d741"],"excludeExerciseCollections":["Free - Eclectic Home","Free - Outdoor","Premium - Industrial"],"userRequirements":"Intermediate strength / stimulus, one-sided exercises, rep schemes. Focus on controlled movements suitable for osteoporosis patients. CRITICAL: USE up to 3 unique exercises in the whole workout.","locale":"fr-FR"}},"localized-fr-FR":{"summary":"Localized Workout (French)","description":"Minimal request with locale — returns French AI title and localized exercise metadata via additive *Localized fields.","value":{"endUserProfileDetails":{"age":28,"fitnessLevels":["intermediate"]},"exerciseSources":["premium_stock"],"durationOptions":{"minMinutes":10,"maxMinutes":15},"categoryId":"615aa3f0dbe7140012c59e94","locale":"fr-FR"}}}}}},"responses":{"200":{"description":"Successfully generated workout plan with automatic warm-up and cooldown sections. AI may adjust final difficulty based on exercise availability and safety considerations.","schema":{"example":{"name":"Intermediate Strength Builder","nameTranslations":{"en-US":"Intermediate Strength Builder","fr-FR":"Renforcement Musculaire Intermédiaire"},"totalDurationSeconds":660,"difficulty":"intermediate","difficultyLabel":"Intermédiaire","categoryId":"615aa3f0dbe7140012c59e94","category":{"id":"615aa3f0dbe7140012c59e94","name":"HIIT"},"instances":[{"id":"64f1a2b3c4d5e6f7a8b9c0d1","kind":"single-exercise","durationSeconds":30,"skipIntro":false,"pace":"medium","exercise":{"id":"6a2d0e568d5154001ac3ede8","name":"Lateral Hip Opener","nameLocalized":"Lateral Hip Opener","thumbnailUrl":"https://cdn.example.com/exercises/thumbnails/lateral-hip-opener.jpg","videoUri":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/lateral-hip-opener.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","estimatedRepDuration":1500,"muscleGroups":["Legs","Glutes"],"muscleGroupsLocalized":[{"id":"604b0177076fe2727354d743","name":"Jambes"},{"id":"604b0173076fe2727354d742","name":"fessiers"}],"equipment":["Mat"],"equipmentLocalized":[{"id":"60812e08606fc90011eb4408","name":"Tapis"}]}},{"id":"64f1a2b3c4d5e6f7a8b9c0d2","kind":"rest","durationSeconds":15},{"id":"64f1a2b3c4d5e6f7a8b9c0d3","kind":"single-exercise","reps":12,"skipIntro":true,"weightLevel":"medium","exercise":{"id":"60812dea606fc90011eb4406","name":"Push-ups","nameLocalized":"Pompes","thumbnailUrl":"https://cdn.example.com/exercises/thumbnails/push-ups.jpg","videoUri":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/push-ups.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","estimatedRepDuration":2000,"muscleGroups":["Chest","Arms","Core"],"muscleGroupsLocalized":[{"id":"604b0169076fe2727354d740","name":"Poitrine"},{"id":"604b0129beaba770c284ff40","name":"Bras"}],"equipment":["Bodyweight"],"equipmentLocalized":[{"id":"67deb36a6a5e49797c122f56","name":"Poids du corps"}]}}]}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutGenerationResponseDto"}}}},"400":{"description":"Bad Request — invalid input, unsupported locale, include+exclude collections together, or filtered exercise pool below 10 after collection/source filters.","schema":{"example":{"error":{"message":"Invalid categoryId provided","statusCode":400,"errorCode":"INVALID_CATEGORY_ID","details":"The categoryId '615aa3f0dbe7140012c59e99' does not exist. Please use GET /v1/workouts/metadata to fetch valid category IDs."}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid API key.","schema":{"example":{"error":{"message":"Invalid API key","statusCode":401,"errorCode":"UNAUTHORIZED"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - API key required or insufficient permissions.","schema":{"example":{"error":{"message":"API key required","statusCode":403,"errorCode":"FORBIDDEN","details":"This endpoint requires a valid API key. Please include the X-Api-Key header with your request."}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Organization or other resources not found.","schema":{"example":{"error":{"message":"Organization not found","statusCode":404,"errorCode":"ORGANIZATION_NOT_FOUND","details":"The organization with ID '67e2e9d0e23f010013e19dec' does not exist or your API key does not have access to it."}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error - Failed to generate workout.","schema":{"example":{"error":{"message":"Failed to generate workout plan due to an internal issue.","statusCode":500,"errorCode":"INTERNAL_SERVER_ERROR"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["ai-generation"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/workouts/generate' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function generateWorkout() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/workouts/generate', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/workouts/generate\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/workouts/{workoutId}/adapt":{"post":{"operationId":"OrganizationWorkoutAdaptation_adaptWorkout","summary":"Adapt an existing team workout based on user profile and data","description":"\n## Adapt a team workout\n\nPersonalizes an existing organization workout (intensity, duration, exercise substitutions) from profile signals, recent session/feedback history, optional wearable context, and `userGuidance`. Goals and overall structure intent of the source workout are preserved. The source `{workoutId}` must belong to `{organizationId}` (otherwise `404`).\n\n**Playback / storage:** Same as workout **generate** — ephemeral `{ name, instances[], … }` (no top-level workout `id`). Play via the JSON-receiver **iframe** + `HYPERHUMAN_EMBED_INIT` (media via `GET /v1/video-asset/{exerciseId}`) or a custom player. No `/playlist`, `/music`, or sessions/feedback. Prefer `POST .../workouts/recommend` for a library match. See API overview **Embedded Player**.\n\n**Rate limit:** counts as **10x**.\n\n**Related:** `POST /v1/orgs/{orgId}/workouts/generate`, `POST /v1/orgs/{orgId}/workouts/recommend`, `GET /v1/orgs/{orgId}/workouts`, `GET /v1/workouts/{id}`.\n        ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"Organization/Team ID","example":"67e2e9d0e23f010013e19dec","schema":{"type":"string"}},{"name":"workoutId","required":true,"in":"path","description":"Workout ID to adapt","example":"67e2e9d0e23f010013e19def","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Workout adaptation request with user profile and preferences","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutAdaptationRequestDto"},"examples":{"basic-adaptation":{"summary":"Basic Adaptation - Intermediate User","description":"Adapt a workout for an intermediate fitness level user","value":{"endUserProfileDetails":{"age":32,"gender":"female","fitnessLevels":["intermediate"],"trainingDaysPerWeek":4},"exerciseSources":["premium_stock","team_exercises"]}},"injury-adaptation":{"summary":"Adaptation with Injury Guidance","description":"Adapt a workout considering user injury","value":{"endUserProfileId":"64e3bca9d1b7e600141a9712","endUserProfileDetails":{"age":45,"gender":"male","fitnessLevels":["beginner"],"trainingDaysPerWeek":3},"exerciseSources":["premium_stock"],"userGuidance":"I have a slight knee injury. Please avoid high-impact exercises like jumping and running. Prefer low-impact alternatives."}},"full-personalization":{"summary":"Full Personalization with User Data","description":"Adapt using 60-day wearable data and full user profile","value":{"endUserProfileId":"64e3bca9d1b7e600141a9712","endUserProfileDetails":{"age":28,"gender":"female","fitnessLevels":["advanced"],"goalIds":["63c92926f920a9005c4e619c"],"trainingDaysPerWeek":5,"preferredEquipmentCategoryIds":["67deb36a6a5e49797c122f56","67deb3696a5e49797c122f55"]},"exerciseSources":["premium_stock","team_exercises"],"userGuidance":"Training for a 10K run in 2 months. Focus on building endurance. Limited time today, prefer shorter workout."}}}}}},"responses":{"200":{"description":"Adapted workout with personalized adjustments","schema":{"example":{"name":"Adapted: Full Body HIIT Power","totalDurationSeconds":1050,"difficulty":"intermediate","categoryId":"615aa3f0dbe7140012c59e94","adaptationReasoning":"Reduced workout duration from 20 to 17.5 minutes to accommodate your current fitness level. Adjusted rest periods to 20 seconds (from 15) to allow better recovery. Modified exercise intensity by reducing reps for high-impact movements to protect your knee. Substituted jumping exercises with low-impact alternatives.","instances":[{"id":"64f1a2b3c4d5e6f7a8b9c0d1","kind":"single-exercise","durationSeconds":30,"skipIntro":false,"pace":"medium","exercise":{"id":"60812dea606fc90011eb4405","name":"Jumping Jacks","description":"Full body cardio warm-up exercise","thumbnailUrl":"https://cdn.example.com/exercises/thumbnails/jumping-jacks.jpg","videoUri":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/jumping-jacks.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","estimatedRepDuration":1500,"muscleGroups":["Full Body","Cardio"],"equipment":["Bodyweight"],"collectionName":"Premium - Neutral","coach":"female","skillLevel":"beginner","categories":["warmup","cardio"]}},{"id":"64f1a2b3c4d5e6f7a8b9c0d2","kind":"rest","durationSeconds":20},{"id":"64f1a2b3c4d5e6f7a8b9c0d3","kind":"single-exercise","reps":10,"skipIntro":true,"weightLevel":"medium","rpe":7,"exercise":{"id":"60812dea606fc90011eb4406","name":"Modified Push-ups","description":"Upper body strength exercise adapted for lower intensity","thumbnailUrl":"https://cdn.example.com/exercises/thumbnails/push-ups.jpg","videoUri":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/push-ups.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","estimatedRepDuration":2000,"muscleGroups":["Chest","Arms"],"equipment":["Bodyweight"],"collectionName":"Premium - Neutral","coach":"female","skillLevel":"intermediate","categories":["strength"]}}]}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutAdaptationResponseDto"}}}},"400":{"description":"Invalid request or workout not eligible for adaptation (only team workouts can be adapted)"},"401":{"description":"Unauthorized - Invalid API key"},"404":{"description":"Workout or organization not found"}},"tags":["ai-adaptation"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/workouts/<WORKOUT_ID>/adapt' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function adaptWorkout() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/workouts/<WORKOUT_ID>/adapt', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/workouts/<WORKOUT_ID>/adapt\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/content-autopilot":{"get":{"operationId":"OrganizationContentAutopilotApi_listTasks","summary":"List content autopilot tasks","description":"\n## Content Autopilot Tasks\n\nRetrieves a paginated list of content autopilot tasks for your organization. Autopilot tasks automate the creation, adaptation, and publishing of workouts and programs on a configurable schedule.\n\n---\n\n### Access and Auth\n\n- **Auth:** API key (X-Api-Key header)\n- **Scope:** Organization (organizationId)\n\n---\n\n### Use Cases\n\n- **Dashboard views** - List all scheduled content automation tasks\n- **Status monitoring** - Filter by active/draft to see running vs paused tasks\n- **Content type filtering** - Show only workout or program automation tasks\n- **Audit and review** - Browse task configurations for the organization\n\n---\n\n### Filtering and Pagination\n\n**Filters:**\n- `status` - active, draft\n- `scope` - ai_generate, create_similar, publish_existing\n- `contentType` - workout, program\n\n**Sort:** `sortBy` (updatedAt, createdAt) + `sortOrder` (ascend, descend)\n\n**Pagination:**\n- `limit` - Items per page (default: 20, max: 50)\n- `offset` - Pagination offset (default: 0)\n\n---\n\n### Related Endpoints\n\n- Get Task: `GET /v1/orgs/{orgId}/content-autopilot/{taskId}`\n- Create Task: `POST /v1/orgs/{orgId}/content-autopilot`\n- Task Events: `GET /v1/orgs/{orgId}/content-autopilot/{taskId}/events`\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Items per page. Defaults to 20, max 50.","example":20,"schema":{"minimum":1,"maximum":50,"default":20,"type":"number"}},{"name":"status","required":false,"in":"query","description":"Filter by task status","schema":{"enum":["active","draft"],"type":"string"}},{"name":"scope","required":false,"in":"query","description":"Filter by task scope","schema":{"enum":["ai_generate","create_similar","publish_existing"],"type":"string"}},{"name":"contentType","required":false,"in":"query","description":"Filter by content type","schema":{"enum":["workout","program"],"type":"string"}},{"name":"sortBy","required":false,"in":"query","description":"Sort by field","schema":{"enum":["updatedAt","createdAt"],"type":"string"}},{"name":"sortOrder","required":false,"in":"query","description":"Sort order","schema":{"enum":["ascend","descend"],"type":"string"}},{"name":"offset","required":false,"in":"query","description":"Pagination offset. Defaults to 0.","example":0,"schema":{"type":"number"}}],"responses":{"200":{"description":"Successfully retrieved paginated list of autopilot tasks.","content":{"application/json":{"examples":{"default":{"summary":"List of autopilot tasks","value":{"data":[{"id":"64f1a2b3c4d5e6f7a8b9c0d1","organizationId":"63415bf67a9c7000126616c1","ownerId":"507f1f77bcf86cd799439011","name":"Daily HIIT Generator","status":"active","scope":"ai_generate","contentType":"workout","difficultyOptions":["beginner","intermediate"],"includeFreeStock":true,"includePremiumStock":false,"includeTeamContent":false,"repeatMode":"daily","nextRunAt":"2026-04-06T10:00:00.000Z","createdAt":"2026-04-01T08:00:00.000Z","updatedAt":"2026-04-05T14:00:00.000Z"}],"links":{"next":null,"total":1},"explanation":"Showing 1 autopilot task for your organization."}}}}}},"400":{"description":"Invalid filter or pagination parameters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["content-autopilot"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function listTasks() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]},"post":{"operationId":"OrganizationContentAutopilotApi_createTask","summary":"Create content autopilot task","description":"\n## Create Autopilot Task\n\nCreates a new content autopilot task in `draft` status. Use the activate endpoint to start the scheduling.\n\n---\n\n### Access and Auth\n\n- **Auth:** API key (X-Api-Key header)\n- **Scope:** Organization (organizationId)\n\n---\n\n### Task Scopes\n\n| Scope | Description | Required Fields |\n|-------|-------------|-----------------|\n| `ai_generate` | Generate new content using AI | categoryIds/goalIds, difficultyOptions |\n| `create_similar` | Adapt an existing workout/program | `sourceContentId` |\n| `publish_existing` | Flip visibility to public on schedule | `existingContentId` |\n\n---\n\n### Prompt Guidance Modes\n\n| Mode | Description |\n|------|-------------|\n| `none` | No additional prompt context |\n| `custom` | User-written free text (`customPromptGuidance`) |\n| `ai_tuned` | 30-day analytics context appended to prompt |\n| `ai_driven` | Fully autonomous - AI decides category, difficulty, duration |\n\n---\n\n### Validation\n\n- `minutesLimit` entitlement must have remaining capacity\n- `premiumStock` entitlement required if `includePremiumStock` is true\n- `sourceContentId` / `existingContentId` must belong to the organization\n\n---\n\n### Related Endpoints\n\n- Activate: `POST /v1/orgs/{orgId}/content-autopilot/{taskId}/activate`\n- Update: `PATCH /v1/orgs/{orgId}/content-autopilot/{taskId}`\n- List: `GET /v1/orgs/{orgId}/content-autopilot`\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAutopilotTaskDto"},"examples":{"aiGenerate":{"summary":"AI-generated daily workout","value":{"name":"Daily HIIT Generator","scope":"ai_generate","contentType":"workout","categoryIds":["615aa3f0dbe7140012c59e94"],"difficultyOptions":["beginner","intermediate"],"durationMin":15,"durationMax":30,"includeFreeStock":true,"repeatMode":"daily","promptGuidanceMode":"ai_driven"}},"createSimilar":{"summary":"Weekly workout variation","value":{"name":"Monday Strength Variation","scope":"create_similar","contentType":"workout","sourceContentId":"507f1f77bcf86cd799439011","difficultyOptions":["intermediate"],"repeatMode":"weekly"}},"publishExisting":{"summary":"Scheduled publish","value":{"name":"Publish Friday Program","scope":"publish_existing","contentType":"program","existingContentId":"507f1f77bcf86cd799439012","difficultyOptions":["beginner"],"repeatMode":"once","nextRunAt":"2026-04-10T09:00:00.000Z"}}}}}},"responses":{"201":{"description":"Task created in draft status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutopilotTaskResponseDto"}}}},"400":{"description":"Invalid input or missing required fields for scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Entitlement limit exceeded or API key not authorized.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["content-autopilot"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function createTask() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/content-autopilot/events":{"get":{"operationId":"OrganizationContentAutopilotApi_listTeamEvents","summary":"List execution events across all tasks","description":"\n## Organization Autopilot Events\n\nRetrieves execution history across all content autopilot tasks for the organization. Each event records a task execution outcome: success, failure, or skip.\n\n---\n\n### Access and Auth\n\n- **Auth:** API key (X-Api-Key header)\n- **Scope:** Organization (organizationId)\n\n---\n\n### Use Cases\n\n- **Execution dashboard** - View recent automation activity across all tasks\n- **Failure monitoring** - Filter by `failed` to identify issues\n- **Audit trail** - Review content creation history with content IDs\n\n---\n\n### Filtering\n\n- `taskId` - Filter events to a specific task\n- `eventType` - success, failed, skipped_limit, skipped_premium_lost\n\n---\n\n### Related Endpoints\n\n- List Tasks: `GET /v1/orgs/{orgId}/content-autopilot`\n- Task Events: `GET /v1/orgs/{orgId}/content-autopilot/{taskId}/events`\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Items per page. Defaults to 20, max 50.","example":20,"schema":{"minimum":1,"maximum":50,"default":20,"type":"number"}},{"name":"eventType","required":false,"in":"query","description":"Filter by event type","schema":{"enum":["success","failed","skipped_limit","skipped_premium_lost"],"type":"string"}},{"name":"taskId","required":false,"in":"query","description":"Filter events to a specific task","schema":{"type":"string"}},{"name":"offset","required":false,"in":"query","description":"Pagination offset. Defaults to 0.","example":0,"schema":{"type":"number"}}],"responses":{"200":{"description":"Successfully retrieved execution events.","content":{"application/json":{"examples":{"default":{"summary":"Execution event list","value":{"data":[{"id":"64f1a2b3c4d5e6f7a8b9c0e1","taskId":"64f1a2b3c4d5e6f7a8b9c0d1","organizationId":"63415bf67a9c7000126616c1","ownerId":"507f1f77bcf86cd799439011","eventType":"success","resultContentId":"64f1a2b3c4d5e6f7a8b9c0f1","resultContentType":"workout","createdAt":"2026-04-05T10:00:00.000Z"}],"links":{"next":null,"total":1}}}}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["content-autopilot"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/events' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function listTeamEvents() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/events', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/events\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/content-autopilot/{taskId}":{"get":{"operationId":"OrganizationContentAutopilotApi_getTask","summary":"Get autopilot task by ID","description":"\n## Autopilot Task Detail\n\nReturns full configuration of a content autopilot task including schedule, content parameters, and prompt guidance settings.\n\n---\n\n### Access and Auth\n\n- **Auth:** API key (X-Api-Key header)\n- **Scope:** Organization (organizationId)\n\n---\n\n### Related Endpoints\n\n- List Tasks: `GET /v1/orgs/{orgId}/content-autopilot`\n- Update Task: `PATCH /v1/orgs/{orgId}/content-autopilot/{taskId}`\n- Task Events: `GET /v1/orgs/{orgId}/content-autopilot/{taskId}/events`\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"taskId","required":true,"in":"path","description":"The unique identifier of the autopilot task.","example":"64f1a2b3c4d5e6f7a8b9c0d1","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved autopilot task detail.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutopilotTaskResponseDto"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Task not found or deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["content-autopilot"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getTask() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]},"patch":{"operationId":"OrganizationContentAutopilotApi_updateTask","summary":"Update autopilot task configuration","description":"\n## Update Autopilot Task\n\nPartially updates an autopilot task's configuration. All fields are optional. Fields not included in the request body remain unchanged.\n\nNotable: update `nextRunAt` to reschedule an active task to a different day without affecting its repeat configuration.\n\n---\n\n### Access and Auth\n\n- **Auth:** API key (X-Api-Key header)\n- **Scope:** Organization (organizationId)\n\n---\n\n### Related Endpoints\n\n- Get Task: `GET /v1/orgs/{orgId}/content-autopilot/{taskId}`\n- Activate: `POST /v1/orgs/{orgId}/content-autopilot/{taskId}/activate`\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"taskId","required":true,"in":"path","description":"The unique identifier of the autopilot task.","example":"64f1a2b3c4d5e6f7a8b9c0d1","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAutopilotTaskDto"},"examples":{"reschedule":{"summary":"Reschedule to a different date","value":{"nextRunAt":"2026-04-12T09:00:00.000Z"}},"updateConfig":{"summary":"Update difficulty and duration","value":{"difficultyOptions":["intermediate","advanced"],"durationMin":20,"durationMax":40}}}}}},"responses":{"200":{"description":"Task updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutopilotTaskResponseDto"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Task not found or deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["content-autopilot"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X PATCH 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function updateTask() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>', {\n  method: 'PATCH',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.patch(\n    \"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]},"delete":{"operationId":"OrganizationContentAutopilotApi_deleteTask","summary":"Delete autopilot task (soft delete)","description":"\n## Delete Autopilot Task\n\nSoft-deletes a content autopilot task. The task will no longer execute and will not appear in list results.\n\n---\n\n### Access and Auth\n\n- **Auth:** API key (X-Api-Key header)\n- **Scope:** Organization (organizationId)\n\n---\n\n### Related Endpoints\n\n- List Tasks: `GET /v1/orgs/{orgId}/content-autopilot`\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"taskId","required":true,"in":"path","description":"The unique identifier of the autopilot task.","example":"64f1a2b3c4d5e6f7a8b9c0d1","schema":{"type":"string"}}],"responses":{"204":{"description":"Task deleted."},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Task not found or already deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["content-autopilot"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X DELETE 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function deleteTask() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>', {\n  method: 'DELETE',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.delete(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/content-autopilot/{taskId}/activate":{"post":{"operationId":"OrganizationContentAutopilotApi_activateTask","summary":"Activate autopilot task","description":"\n## Activate Task\n\nSets the task status to `active` and determines the next scheduled execution time.\n\n**Schedule resolution:**\n1. If the task already has a `nextRunAt` in the future, it is preserved.\n2. Otherwise, `nextRunAt` is computed from the task's `repeatMode`.\n3. For `once` mode, defaults to now.\n\n---\n\n### Access and Auth\n\n- **Auth:** API key (X-Api-Key header)\n- **Scope:** Organization (organizationId)\n\n---\n\n### Related Endpoints\n\n- Deactivate: `POST /v1/orgs/{orgId}/content-autopilot/{taskId}/deactivate`\n- Run Now: `POST /v1/orgs/{orgId}/content-autopilot/{taskId}/run-now`\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"taskId","required":true,"in":"path","description":"The unique identifier of the autopilot task.","example":"64f1a2b3c4d5e6f7a8b9c0d1","schema":{"type":"string"}}],"responses":{"200":{"description":"Task activated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutopilotTaskResponseDto"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Task not found or deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["content-autopilot"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>/activate' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function activateTask() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>/activate', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>/activate\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/content-autopilot/{taskId}/deactivate":{"post":{"operationId":"OrganizationContentAutopilotApi_deactivateTask","summary":"Deactivate autopilot task","description":"\n## Deactivate Task\n\nSets the task status to `draft` and clears the `nextRunAt` schedule. The task will stop executing until activated again.\n\n---\n\n### Access and Auth\n\n- **Auth:** API key (X-Api-Key header)\n- **Scope:** Organization (organizationId)\n\n---\n\n### Related Endpoints\n\n- Activate: `POST /v1/orgs/{orgId}/content-autopilot/{taskId}/activate`\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"taskId","required":true,"in":"path","description":"The unique identifier of the autopilot task.","example":"64f1a2b3c4d5e6f7a8b9c0d1","schema":{"type":"string"}}],"responses":{"200":{"description":"Task deactivated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutopilotTaskResponseDto"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Task not found or deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["content-autopilot"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>/deactivate' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function deactivateTask() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>/deactivate', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>/deactivate\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/content-autopilot/{taskId}/run-now":{"post":{"operationId":"OrganizationContentAutopilotApi_runNow","summary":"Manually trigger task execution","description":"\n## Run Now\n\nExecutes a content autopilot task immediately, bypassing the cron schedule. Respects all entitlement limits and daily execution caps (max 20 per user per day).\n\nThe task can be in any status (active or draft) -- this allows testing a task configuration before activating it on a schedule.\n\n---\n\n### Access and Auth\n\n- **Auth:** API key (X-Api-Key header)\n- **Scope:** Organization (organizationId)\n\n---\n\n### Rate Limit\n\nThis endpoint triggers AI content generation and counts as 10x API calls toward your hourly and daily limits.\n\n---\n\n### Related Endpoints\n\n- Activate: `POST /v1/orgs/{orgId}/content-autopilot/{taskId}/activate`\n- Task Events: `GET /v1/orgs/{orgId}/content-autopilot/{taskId}/events`\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"taskId","required":true,"in":"path","description":"The unique identifier of the autopilot task.","example":"64f1a2b3c4d5e6f7a8b9c0d1","schema":{"type":"string"}}],"responses":{"200":{"description":"Task executed successfully."},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Entitlement limit exceeded or API key not authorized.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Task not found or deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["content-autopilot"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>/run-now' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function runNow() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>/run-now', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>/run-now\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/content-autopilot/{taskId}/events":{"get":{"operationId":"OrganizationContentAutopilotApi_listTaskEvents","summary":"List execution events for a task","description":"\n## Task Execution History\n\nRetrieves the execution event log for a specific autopilot task. Each event records a task run outcome.\n\n**Event types:**\n- `success` - Content created and published successfully. `resultContentId` contains the new content ID.\n- `failed` - Execution failed. `errorMessage` contains the reason.\n- `skipped_limit` - Daily execution limit (20/day) reached. Task retries next day.\n- `skipped_premium_lost` - Premium stock entitlement lost. Schedule advanced.\n\n---\n\n### Access and Auth\n\n- **Auth:** API key (X-Api-Key header)\n- **Scope:** Organization (organizationId)\n\n---\n\n### Related Endpoints\n\n- Get Task: `GET /v1/orgs/{orgId}/content-autopilot/{taskId}`\n- Team Events: `GET /v1/orgs/{orgId}/content-autopilot/events`\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"taskId","required":true,"in":"path","description":"The unique identifier of the autopilot task.","example":"64f1a2b3c4d5e6f7a8b9c0d1","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Items per page. Defaults to 20, max 50.","example":20,"schema":{"minimum":1,"maximum":50,"default":20,"type":"number"}},{"name":"eventType","required":false,"in":"query","description":"Filter by event type","schema":{"enum":["success","failed","skipped_limit","skipped_premium_lost"],"type":"string"}},{"name":"offset","required":false,"in":"query","description":"Pagination offset. Defaults to 0.","example":0,"schema":{"type":"number"}}],"responses":{"200":{"description":"Successfully retrieved task execution events.","content":{"application/json":{"examples":{"default":{"summary":"Task execution history","value":{"data":[{"id":"64f1a2b3c4d5e6f7a8b9c0e1","taskId":"64f1a2b3c4d5e6f7a8b9c0d1","organizationId":"63415bf67a9c7000126616c1","ownerId":"507f1f77bcf86cd799439011","eventType":"success","resultContentId":"64f1a2b3c4d5e6f7a8b9c0f1","resultContentType":"workout","createdAt":"2026-04-05T10:00:00.000Z"},{"id":"64f1a2b3c4d5e6f7a8b9c0e2","taskId":"64f1a2b3c4d5e6f7a8b9c0d1","organizationId":"63415bf67a9c7000126616c1","ownerId":"507f1f77bcf86cd799439011","eventType":"failed","errorMessage":"Content minutes limit reached","createdAt":"2026-04-04T10:00:00.000Z"}],"links":{"next":null,"total":2}}}}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Task not found or deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["content-autopilot"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>/events' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function listTaskEvents() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>/events', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/content-autopilot/<TASKID>/events\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/drops":{"get":{"operationId":"OrganizationDropsApi_getOrganizationDrops","summary":"List organization social drops","description":"\n## Organization Social Drops\n\nRetrieves paginated list of ready social drops for your organization. A drop is a publish-ready package (video variants, covers, copy packs) linked to an Exercise, Collection (Micro Workout), Workout, or Program.\n\n**Note:** Only drops with status `ready` are returned. Draft, processing, and failed drops are excluded.\n\n---\n\n### Access and Auth\n\n- **Auth:** API key (X-Api-Key header)\n- **Scope:** Organization (organizationId)\n- **Capabilities:** List ready drops, get drop detail, export channel bundle (video, cover, copy pack)\n\n---\n\n### Use Cases\n\n- **Social scheduling tools** - List drops for content calendar\n- **Content management dashboards** - Browse and export ready assets\n- **Bulk export workflows** - Get video + cover + copy for channel publishing\n- **Channel-specific discovery** - Filter by aspect ratio and duration\n\n---\n\n### Filtering and Pagination\n\n**Filters:**\n- `sourceType` - exercise, exerciseCollection, workout, workoutCollection\n- `sourceId` - Filter by source entity ID (use with sourceType for entity-context views)\n- `aspectRatio` - 9:16, 1:1, 16:9 (drops that have this variant)\n- `duration` - 15, 30, 60 (seconds; drops that have this variant)\n- `q` - Search by drop title (min 3 characters)\n\n**Sort:** Use `sort` with +field (asc) or -field (desc), e.g. `-updatedAt`, `+createdAt`\n\n**Pagination:**\n- `limit` - Items per page (default: 20, max: 50)\n- `offset` - Pagination offset (default: 0)\n\n---\n\n### Best Practices\n\n- **Cache responses** - Drops change when new content is published\n- **Use sourceId** - Filter by source when showing drops in entity-context modals\n- **Handle empty results** - Graceful fallback when no ready drops exist\n\n---\n\n### Related Endpoints\n\n- Get Drop: `GET /v1/orgs/{orgId}/drops/{dropId}` - Full detail with variants and copy packs\n- Export Drop: `POST /v1/orgs/{orgId}/drops/{dropId}/export` - Channel bundle (video, cover, copy)\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Items per page. Defaults to 20, max 50.","example":20,"schema":{"minimum":1,"maximum":50,"default":20,"type":"number"}},{"name":"q","required":false,"in":"query","description":"Search by drop title (min 3 characters)","schema":{"type":"string"}},{"name":"sort","required":false,"in":"query","description":"Sort: +updatedAt, -createdAt","schema":{"type":"string"}},{"name":"sourceType","required":false,"in":"query","description":"Filter by source type","schema":{"enum":["exercise","exerciseCollection","workout","workoutCollection"],"type":"string"}},{"name":"sourceId","required":false,"in":"query","description":"Filter by source entity ID","schema":{"type":"string"}},{"name":"aspectRatio","required":false,"in":"query","description":"Filter by aspect ratio","schema":{"enum":["9:16","1:1","16:9"],"type":"string"}},{"name":"duration","required":false,"in":"query","description":"Filter by duration in seconds","schema":{"enum":[15,30,60],"type":"number"}},{"name":"offset","required":false,"in":"query","description":"Pagination offset. Defaults to 0.","example":0,"schema":{"type":"number"}}],"responses":{"200":{"description":"Successfully retrieved paginated list of ready drops for the organization.","content":{"application/json":{"examples":{"default":{"summary":"List of ready drops","value":{"data":[{"id":"64f1a2b3c4d5e6f7a8b9c0d1","organizationId":"63415bf67a9c7000126616c1","sourceType":"exercise","sourceId":"507f1f77bcf86cd799439011","sourceName":"Jumping Jacks","title":"Jumping Jacks","sourceThumbnailUrl":"https://hhcontent.s3.eu-central-1.amazonaws.com/...","sourceTypeLabel":"Exercise","locale":"en-US","channelPreset":"ig_reels","channelPresetLabel":"Instagram Reels","availableVariants":["9:16_30000","9:16_15000","1:1_30000"],"createdAt":"2025-09-15T10:30:00Z","updatedAt":"2025-09-16T14:20:00Z"},{"id":"64f1a2b3c4d5e6f7a8b9c0d2","organizationId":"63415bf67a9c7000126616c1","sourceType":"workout","sourceId":"12ab3efd45c67c1234566cd1","sourceName":"Morning Power HIIT","title":"Morning Power HIIT","sourceThumbnailUrl":"https://hhcontent.s3.eu-central-1.amazonaws.com/...","sourceTypeLabel":"Workout","locale":"en-US","channelPreset":"ig_reels","channelPresetLabel":"Instagram Reels","availableVariants":["9:16_60000","1:1_30000"],"createdAt":"2025-09-14T08:00:00Z","updatedAt":"2025-09-15T11:45:00Z"}],"links":{"next":"https://content.api.hyperhuman.cc/v1/orgs/63415bf67a9c7000126616c1/drops?limit=20&offset=20","total":42},"explanation":"Your ready social drops - video variants, covers, and copy packs for channel publishing."}}}}}},"400":{"description":"Invalid filter or pagination parameters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["social"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/drops' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getOrganizationDrops() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/drops', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/drops\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/drops/{dropId}":{"get":{"operationId":"OrganizationDropsApi_getOrganizationDropById","summary":"Get drop by ID","description":"\n## Drop Detail\n\nReturns full drop detail including video variants with presigned download and poster URLs, and copy packs per channel.\n\n**Response structure:**\n- `copyPack` - Copy pack for the default channel (channelPreset)\n- `copyPacks` - Copy packs per channel; use `copyPacks[viewChannel] ?? copyPack` for channel switching\n- `variants` - Video variants with aspectRatio, duration, downloadLink, posterLink, posterLinksByChannel, size\n\n**URL expiration:** Presigned URLs are valid for 7 days.\n\n---\n\n### Related Endpoints\n\n- List Drops: `GET /v1/orgs/{orgId}/drops` - Browse organization drops\n- Export Drop: `POST /v1/orgs/{orgId}/drops/{dropId}/export` - Get channel bundle\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"dropId","required":true,"in":"path","description":"The unique identifier of the drop.","example":"64f1a2b3c4d5e6f7a8b9c0d1","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved drop detail.","content":{"application/json":{"examples":{"default":{"summary":"Drop detail with variants and copy packs","value":{"id":"64f1a2b3c4d5e6f7a8b9c0d1","organizationId":"63415bf67a9c7000126616c1","sourceType":"exercise","sourceId":"507f1f77bcf86cd799439011","sourceName":"Jumping Jacks","title":"Jumping Jacks","sourceThumbnailUrl":"https://hhcontent.s3.eu-central-1.amazonaws.com/...","sourceTypeLabel":"Exercise","locale":"en-US","channelPreset":"ig_reels","channelPresetLabel":"Instagram Reels","availableVariants":["9:16_30000","9:16_15000","1:1_30000"],"copyPack":{"hook":"Get fit in 30 seconds!","caption":"30 seconds of Jumping Jacks to get your heart pumping. Perfect for a quick warm-up or standalone cardio burst. Try it now and feel the burn.","hashtags":"#fitness #workout #hiit #cardio","cta":"Link in bio","posterTagline":{"primaryLine":"30s HIIT","secondaryLine":"Jumping Jacks"}},"copyPacks":{"ig_reels":{"hook":"Get fit in 30 seconds!","caption":"30 seconds of Jumping Jacks to get your heart pumping. Perfect for a quick warm-up or standalone cardio burst. Try it now and feel the burn.","hashtags":"#fitness #workout #hiit #cardio","cta":"Link in bio","posterTagline":{"primaryLine":"30s HIIT","secondaryLine":"Jumping Jacks"}},"tiktok":{"hook":"30 sec cardio burst","caption":"Jumping Jacks - no equipment needed. Drop a heart if you finished it.","hashtags":"#fitness #workout #cardio #30secondchallenge","cta":"Full workout in bio","posterTagline":{"primaryLine":"30s HIIT","secondaryLine":"Jumping Jacks"}}},"variants":[{"aspectRatio":"9:16","duration":30000,"downloadLink":"https://hhcontent.s3.../drop_9x16_30.mp4?X-Amz-...","posterLink":"https://hhcontent.s3.../poster.png?X-Amz-...","posterLinksByChannel":{"tiktok":"https://hhcontent.s3.../poster_tiktok.png?X-Amz-..."},"size":1234567},{"aspectRatio":"9:16","duration":15000,"downloadLink":"https://hhcontent.s3.../drop_9x16_15.mp4?X-Amz-...","posterLink":"https://hhcontent.s3.../poster_15.png?X-Amz-...","size":654321},{"aspectRatio":"1:1","duration":30000,"downloadLink":"https://hhcontent.s3.../drop_1x1_30.mp4?X-Amz-...","posterLink":"https://hhcontent.s3.../poster_1x1.png?X-Amz-...","size":987654}],"createdAt":"2025-09-15T10:30:00Z","updatedAt":"2025-09-16T14:20:00Z"}}}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Drop not found or not ready.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["social"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/drops/<DROPID>' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getOrganizationDropById() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/drops/<DROPID>', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/drops/<DROPID>\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/drops/{dropId}/export":{"post":{"operationId":"OrganizationDropsApi_exportDrop","summary":"Export drop for channel bundle","description":"\n## Export for Channel Bundle\n\nReturns presigned video download URL, cover image URL, and copy pack for the specified channel. Use for one-click export to Reels, Shorts, TikTok, etc.\n\n**Response contents:**\n- `videoDownloadLink` - Presigned S3 URL for MP4 video (valid 7 days)\n- `coverLink` - Presigned S3 URL for cover/poster image\n- `copyPack` - Hook, caption, hashtags, CTA, poster tagline\n- `ctaUrl` - Optional CTA URL from team settings (when configured)\n\n**Channel presets:** ig_reels, ig_stories, ig_carousel, tiktok, yt_shorts, fb_reels, yt_longform. Each has default aspect ratio and duration; override via body.\n\n---\n\n### Integration Example\n\n```javascript\nconst res = await fetch(\n  `/v1/orgs/${orgId}/drops/${dropId}/export`,\n  {\n    method: 'POST',\n    headers: {\n      'X-Api-Key': apiKey,\n      'Content-Type': 'application/json',\n    },\n    body: JSON.stringify({ channelPreset: 'ig_reels' }),\n  }\n);\nconst { videoDownloadLink, coverLink, copyPack } = await res.json();\n// Download video, copy caption to clipboard\n```\n\n---\n\n### Best Practices\n\n- **Refresh URLs before expiry** - Presigned URLs valid for 7 days\n- **Use channel preset** - Platform-specific defaults (aspect ratio, duration)\n- **Handle 400** - Requested variant may not be available for this drop\n\n---\n\n### Related Endpoints\n\n- Get Drop: `GET /v1/orgs/{orgId}/drops/{dropId}` - Full detail before export\n- List Drops: `GET /v1/orgs/{orgId}/drops` - Browse organization drops\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"dropId","required":true,"in":"path","description":"The unique identifier of the drop.","example":"64f1a2b3c4d5e6f7a8b9c0d1","schema":{"type":"string"}}],"requestBody":{"required":false,"description":"Optional overrides. Omit to use drop defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportDropDto"},"examples":{"default":{"summary":"Use drop defaults","value":{}},"igReels":{"summary":"Instagram Reels","value":{"channelPreset":"ig_reels"}},"customVariant":{"summary":"Custom variant","value":{"channelPreset":"tiktok","aspectRatio":"9:16","duration":15}}}}}},"responses":{"200":{"description":"Channel bundle with presigned URLs and copy pack.","content":{"application/json":{"examples":{"default":{"summary":"Export bundle for Instagram Reels","value":{"videoDownloadLink":"https://hhcontent.s3.../drop_9x16_30.mp4?X-Amz-...","coverLink":"https://hhcontent.s3.../cover.png?X-Amz-...","ctaUrl":"https://mybrand.com/fitness","copyPack":{"hook":"Get fit in 30 seconds!","caption":"30 seconds of Jumping Jacks to get your heart pumping. Perfect for a quick warm-up or standalone cardio burst. Try it now and feel the burn.","hashtags":"#fitness #workout #hiit","cta":"Link in bio","posterTagline":{"primaryLine":"30s HIIT","secondaryLine":"Jumping Jacks"}}}}}}}},"400":{"description":"Requested variant not available for this drop.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Drop not found or not ready.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["social"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/drops/<DROPID>/export' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function exportDrop() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/drops/<DROPID>/export', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/drops/<DROPID>/export\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/social-publish/connected-platforms":{"get":{"operationId":"OrganizationSocialPublishApi_getConnectedPlatforms","summary":"List connected social platforms","description":"Returns which platforms (instagram, tiktok, youtube, facebook) have a stored account id for this organization. Account connection is managed in the Hyperhuman team app, not via this API.","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationConnectedPlatformsResponseDto"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["social-publish"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/social-publish/connected-platforms' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getConnectedPlatforms() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/social-publish/connected-platforms', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/social-publish/connected-platforms\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/social-publish":{"get":{"operationId":"OrganizationSocialPublishApi_listTasks","summary":"List scheduled social publish automations","description":"\n## List social publish tasks\n\nPaginated scheduled social-publish automations for this organization (`{ data, links }`).\n\n**Try it:** `GET /v1/orgs/{organizationId}/social-publish?limit=20` with `X-Api-Key`. Optional `status` (`active` | `draft`). Pagination: `limit` (default **20**, max **50**); advance via `links.next`.\n\n**Related:** `GET .../social-publish/connected-platforms`, `POST .../social-publish`, `PATCH .../social-publish/{taskId}`.\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Maximum number of items to return per page.","example":20,"schema":{"minimum":1,"maximum":50,"default":20,"type":"number"}},{"name":"offset","required":false,"in":"query","description":"Number of items to skip before collecting results (zero-based). Prefer the `links.next` cursor for pagination.","example":0,"schema":{"minimum":0,"default":0,"type":"number"}},{"name":"status","required":false,"in":"query","description":"Filter by task status","schema":{"enum":["active","draft"],"type":"string"}},{"name":"sourceMode","required":false,"in":"query","description":"Filter by source mode","schema":{"enum":["manual_fixed","random_ready","ai_insights","ai_pick"],"type":"string"}},{"name":"sortBy","required":false,"in":"query","description":"Sort by field","schema":{"enum":["updatedAt","createdAt"],"type":"string"}},{"name":"sortOrder","required":false,"in":"query","description":"Sort order","schema":{"enum":["ascend","descend"],"type":"string"}},{"name":"search","required":false,"in":"query","description":"Case-insensitive substring match on automation name (min 1 character after trim)","schema":{"maxLength":200,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationSocialPublishTaskListResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["social-publish"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/social-publish' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function listTasks() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/social-publish', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/social-publish\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]},"post":{"operationId":"OrganizationSocialPublishApi_createTask","summary":"Create a social publish automation (draft)","description":"\n## Create a social publish task\n\nCreates a social-publish automation as **draft** (**201**). Body matches the team internal create-social-publish task shape. OAuth connect, run-now, and per-run event listing are **not** on Content API — use the team app / internal routes.\n\n**Next:** `PATCH .../social-publish/{taskId}` with `{ \"status\": \"active\" }` to schedule (requires connected accounts for target platforms; otherwise **422**).\n\n**Related:** `GET .../social-publish/connected-platforms`, `GET .../social-publish`, `PATCH .../social-publish/{taskId}`.\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSocialDropPublishTaskDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationSocialPublishTaskResponseDto"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["social-publish"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/social-publish' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function createTask() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/social-publish', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/social-publish\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/social-publish/{taskId}":{"get":{"operationId":"OrganizationSocialPublishApi_getTask","summary":"Get one social publish automation","description":"\n## Get a social publish task\n\nReturns one automation by `taskId` for this organization (includes schedule fields and last-run outcome when present). **404** if missing or not owned by the org.\n\n**Related:** `GET .../social-publish`, `PATCH .../social-publish/{taskId}`, `DELETE .../social-publish/{taskId}`.\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"taskId","required":true,"in":"path","description":"The unique identifier of the scheduled social publish automation.","example":"64f1a2b3c4d5e6f7a8b9c0d1","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationSocialPublishTaskResponseDto"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["social-publish"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/social-publish/<TASKID>' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getTask() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/social-publish/<TASKID>', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/social-publish/<TASKID>\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]},"patch":{"operationId":"OrganizationSocialPublishApi_patchTask","summary":"Update a social publish automation","description":"\n## Update a social publish task\n\nPartial update. `status: active` schedules the task (requires connected accounts for all target platforms; missing accounts / posting base URL → **422**). `status: draft` pauses and clears `nextRunAt`. Other fields follow the same rules as the team internal API.\n\n**Related:** `GET .../social-publish/connected-platforms`, `GET .../social-publish/{taskId}`.\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"taskId","required":true,"in":"path","description":"The unique identifier of the scheduled social publish automation.","example":"64f1a2b3c4d5e6f7a8b9c0d1","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationPatchSocialPublishTaskDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationSocialPublishTaskResponseDto"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["social-publish"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X PATCH 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/social-publish/<TASKID>' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function patchTask() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/social-publish/<TASKID>', {\n  method: 'PATCH',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.patch(\n    \"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/social-publish/<TASKID>\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]},"delete":{"operationId":"OrganizationSocialPublishApi_deleteTask","summary":"Delete a social publish automation (soft delete)","description":"\n## Delete a social publish task\n\nSoft-deletes the automation (**204**). Cron will not pick it up afterward; an in-flight run may still finish.\n\n**Related:** `GET .../social-publish`, `PATCH .../social-publish/{taskId}`.\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"taskId","required":true,"in":"path","description":"The unique identifier of the scheduled social publish automation.","example":"64f1a2b3c4d5e6f7a8b9c0d1","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["social-publish"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X DELETE 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/social-publish/<TASKID>' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function deleteTask() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/social-publish/<TASKID>', {\n  method: 'DELETE',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.delete(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/social-publish/<TASKID>\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/workouts/{workoutId}/playlist":{"get":{"operationId":"WorkoutContentApi_getWorkoutPlaylist","summary":"Retrieve Detailed Workout Playlist Structure","description":"\n## Workout playlist\n\nOrdered playback segments for a **persisted** workout id. Response: `{ data, presentationStyle?, links? }` where `data` is an array of **single-key** objects keyed by segment kind (`intro`, `exercise`, `multiExercise`, `class`, `promo`, `educational`, `break`, `outro`). Not the AI-generate `instances[]` shape.\n\n**Try it:** `GET /v1/workouts/{workoutId}/playlist` with `X-Api-Key`. Optional `locale` (BCP-47) localizes segment names, equipment, muscle groups, and audio selection (unsupported → English fallback).\n\n**Segments:** `exercise` has timing/prescription + `main.video` / instruction audio (`url`, optional `type` / `locale` / `scriptText`). `class` may include optional `chapters[]` (`startTimeSec` / `endTimeSec` within `main.video`) when analysis ran; chapter text is not re-localized. `multiExercise` is the original-audio block kind (still emitted when present).\n\n**Media:** Video and audio `url` values are time-limited AWS S3 **presigned HTTPS** links to **progressive MP4** / M4A (typically ~**7 days**). Re-fetch the playlist before expiry; do not treat URLs as durable. Not HLS/DASH/ABR — play with HTML5 `<video>` / AVPlayer / ExoPlayer (no hls.js required).\n\n**Related:** `GET /v1/workouts/{id}`, `GET /v1/workouts/{id}/music`, `POST /v1/workouts/{id}/sessions/start`, custom-player guide.\n    ","parameters":[{"name":"workoutId","required":true,"in":"path","description":"The unique workout id (24-character hex DB id) whose playlist is required.","example":"a1b2c3d4e5f6a7b8c9d0e1f2","schema":{"type":"string"}},{"name":"locale","required":false,"in":"query","description":"Language locale for localized content (BCP-47 format). Affects exercise names, equipment names, muscle group names, and audio selection. Supported: en-US, en-GB, en-AU, fr-FR, de-DE, es-ES, it-IT, pt-PT, he-IL, ro-RO, cs-CZ, fi-FI, lt-LT, nl-NL, pl-PL, ar-XA. Falls back to English if unsupported.","example":"fr-FR","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved the detailed workout playlist structure. `data` is an ordered array; each item is an object with a single key indicating the segment kind (one of `intro`, `exercise`, `multiExercise`, `class`, `promo`, `educational`, `break`, `outro`). The value under that key is the segment payload (see schema for the per-kind shape).","schema":{"example":{"data":[{"intro":{"kind":"workout-intro","id":"intro","duration":5.2,"audio":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/audio/intro.m4a","type":"workoutIntro","locale":"en-US","scriptText":"Welcome to your workout."},"video":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/intro.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://images.hyperhuman.cc/intro-poster.jpg","thumbnail":"https://images.hyperhuman.cc/intro-thumb.jpg"}}},{"exercise":{"kind":"exercise","id":"exercise_squats_1","exerciseId":"507f1f77bcf86cd799439011","duration":45,"name":"Bodyweight Squats","reps":12,"pace":"medium","weightLevel":null,"rpe":7,"amrap":false,"equipment":[{"id":"60812e08606fc90011eb4408","name":"Mat"}],"muscleGroups":[{"id":"604b0177076fe2727354d743","name":"Legs"}],"intro":{"audio":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/audio/squat-cue.m4a","type":"exerciseCue","locale":"en-US","scriptText":"Next up, bodyweight squats."},"video":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/squat-intro.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://images.hyperhuman.cc/squat-poster.jpg","thumbnail":"https://images.hyperhuman.cc/squat-thumb.jpg","loop":-1}},"main":{"video":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/squat-main.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://images.hyperhuman.cc/squat-poster.jpg","thumbnail":"https://images.hyperhuman.cc/squat-thumb.jpg","loop":-1},"instructionAudio":[{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/audio/squat-instruction-1.m4a","type":"exerciseInstruction","locale":"en-US","scriptText":"Stand tall with your feet shoulder-width apart. Lower into a squat, keeping your chest up."}]}}},{"class":{"kind":"class","id":"64f1a2b3c4d5e6f7a8b9c0d1","exerciseId":"507f1f77bcf86cd799439013","duration":1200,"name":"Morning Strength Class","equipment":[{"id":"60812e08606fc90011eb4408","name":"Kettlebell"}],"muscleGroups":[{"id":"604b0177076fe2727354d743","name":"Full Body"}],"intro":{"audio":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/audio/class-intro.m4a"},"video":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/class-intro.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://images.hyperhuman.cc/class-poster.jpg","thumbnail":"https://images.hyperhuman.cc/class-thumb.jpg","loop":-1}},"skipIntro":false,"main":{"video":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/class-main.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://images.hyperhuman.cc/class-poster.jpg","thumbnail":"https://images.hyperhuman.cc/class-thumb.jpg"}},"chapters":[{"name":"Goblet Squat","startTimeSec":180.5,"endTimeSec":420,"equipment":[{"id":"60812e08606fc90011eb4408","name":"Kettlebell"}],"muscleGroups":[{"id":"604b0177076fe2727354d743","name":"Quadriceps"}]},{"name":"Push Press","startTimeSec":420,"endTimeSec":720,"equipment":[{"id":"60812e08606fc90011eb4408","name":"Kettlebell"}],"muscleGroups":[{"id":"604b0177076fe2727354d744","name":"Shoulders"}]}]}},{"break":{"kind":"break","id":"break_1","duration":30,"video":null}},{"outro":{"kind":"workout-outro","id":"outro","duration":45.5,"audio":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/audio/outro-cooldown.m4a","type":"workoutOutro","locale":"en-US","scriptText":"Great work. See you next time."},"video":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/outro.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://images.hyperhuman.cc/outro-poster.jpg","thumbnail":"https://images.hyperhuman.cc/outro-thumb.jpg"}}}],"presentationStyle":"full","links":{}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutPlaylistResponse"}}}},"401":{"description":"Authentication failed. API key or Bearer token is missing, invalid, or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The specified workout ID does not exist or a playlist could not be generated for it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["workouts"],"security":[{"X-Api-Key":["X-Api-Key"]},{"AccessToken":[]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/playlist' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getWorkoutPlaylist() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/playlist', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/playlist\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/workouts/{workoutId}/music":{"get":{"operationId":"WorkoutContentApi_getWorkoutMusic","summary":"Get workout music playlist","description":"\n## Workout music playlist\n\nReturns the shuffled PulseMix track pool for a **persisted** workout id (`GET /v1/workouts/{workoutId}/music`). Bare response: `{ tracks, totalDuration, workoutDuration }`.\n\n**Requires a real workout id** from your library (or another persisted workout). The embedded **JSON receiver** path (AI-generated / host-built `{ name, instances }` without a saved id) does **not** call this endpoint and has **no** automatic background music.\n\n**Selection:** trainer music preferences and workout categories; stock fallback when unset. `totalDuration` is the summed pool length (not trimmed to the workout). Empty pool → `200` with `tracks: []` and `totalDuration: 0` (not 404). Pre-signed URLs expire in about 7 days.\n\nGate playback with the workout's `videoAudioMode` / `mixBgMusic` (see audio policy in the API overview).\n\n**Related:** `GET /v1/workouts/{id}`, `GET /v1/workouts/{id}/playlist`.\n    ","parameters":[{"name":"workoutId","required":true,"in":"path","description":"The unique identifier of the workout","example":"a1b2c3d4e5f6a7b8c9d0e1f2","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved workout music playlist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutMusicPlaylistResponse"}}}},"401":{"description":"Authentication failed. API key or Bearer token is missing, invalid, or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The specified workout ID does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["workouts"],"security":[{"X-Api-Key":["X-Api-Key"]},{"AccessToken":[]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/music' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getWorkoutMusic() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/music', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/music\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/workouts/{workoutId}/sessions/start":{"post":{"operationId":"WorkoutsSessionsApi_startWorkoutSession","summary":"Start workout session","description":"\n## Start a workout session\n\nCreates a session for a **persisted** workout id (**201**). Key-only calls are **anonymous** (`traineeId: null`) unless you attribute with `endUserId` / `externalUserId` (+ `organizationId` for standard/club keys). A Bearer token, when present, wins. Previous incomplete sessions for the same workout may be closed automatically for attributed/authenticated users.\n\n**Lifecycle:** start → PATCH `progressSeconds` every 10–30s → `sessions/end` (keep last progress) or `sessions/complete` (force 100%) → optional feedback. The **pre-built** embed (`/embed/workout/{id}`) calls this lifecycle; the **JSON-receiver** embed does not (no persisted workout id).\n\n**Related:** `PATCH /v1/workouts/{id}/sessions/{sessionId}`, `POST .../sessions/end`, `POST .../sessions/complete`, `POST .../feedback`, API overview **Embedded Player**.\n    ","parameters":[{"name":"workoutId","required":true,"in":"path","description":"The unique identifier (24-character hex string) of the workout to start a session for.","example":"12ab3efd45c67c1234566cd1","schema":{"type":"string"}}],"requestBody":{"required":false,"description":"Optional session start body. Omit it (or send `{}`) for an authenticated/anonymous session. To attribute the session to a specific end user with only an API key, send `endUserId` (or `externalUserId`) and, for standard/club keys, `organizationId`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartWorkoutSessionBody"},"examples":{"authenticated-user":{"summary":"Authenticated User Session","description":"Standard session start for logged-in user with automatic session management","value":{}},"anonymous-user":{"summary":"Anonymous User Session","description":"Session start without authentication - limited tracking capabilities","value":{}},"attributed-end-user":{"summary":"Attributed End-User Session (API key)","description":"Attribute the session to a specific end user without a member token. Resolved against the API key team.","value":{"endUserId":"64f1a2b3c4d5e6f7a8b9c0d1","organizationId":"a1b2c3d4e5f6a7b8c9d0e1f2"}}}}}},"responses":{"201":{"description":"Workout session successfully started. Any previous incomplete sessions for this workout are automatically closed.","schema":{"example":{"data":{"id":"67d1a2b3c4e5f6789abc0d1","createdAt":"2025-01-10T08:30:00.000Z","updatedAt":"2025-01-10T08:30:00.000Z","workoutId":"12ab3efd45c67c1234566cd1","workoutSegmentId":"intro","status":"started","duration":0,"progress":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutSessionResponse"}}}},"401":{"description":"Authentication failed (API key invalid or Bearer token invalid).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["workouts"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/sessions/start' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function startWorkoutSession() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/sessions/start', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/sessions/start\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/workouts/{workoutId}/sessions/{sessionId}":{"patch":{"operationId":"WorkoutsSessionsApi_patchWorkoutSession","summary":"Update a workout session","description":"\n## Update session progress\n\nPATCH an active session with `progressSeconds` (actual playback time, pauses excluded) and/or `workoutSegmentId`. Duration is capped at 2× expected workout length. Prefer PATCH every 10–30s and on segment changes; final PATCH before end/complete.\n\n**Related:** `POST .../sessions/start`, `POST .../sessions/end`, `POST .../sessions/complete`.\n    ","parameters":[{"name":"workoutId","required":true,"in":"path","description":"The unique identifier (24-character hex string) of the workout associated with the session.","example":"12ab3efd45c67c1234566cd1","schema":{"type":"string"}},{"name":"sessionId","required":true,"in":"path","description":"The unique identifier (24-character hex string) of the workout session to update.","example":"12ab3efd45c67c1234566cd1","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Update session progress. Send progressSeconds to track actual playback time. For a key-only attributed session, re-send the same end-user fields used on start (`endUserId` or `externalUserId`, plus `organizationId` for standard/club keys) so the lookup stays scoped to that end user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchWorkoutSessionBody"},"examples":{"updateProgress":{"summary":"Update playback progress (recommended)","description":"Track actual playback time. This is the primary method for accurate duration tracking.","value":{"workoutSegmentId":"seg-exercise-2","progressSeconds":125.5}},"updateSegmentOnly":{"summary":"Update segment only","description":"Track which segment user is on without updating playback time.","value":{"workoutSegmentId":"seg-exercise-3"}},"attributed-end-user":{"summary":"Attributed progress update (API key)","description":"Re-send the end-user attribution alongside progress for a key-only attributed session.","value":{"workoutSegmentId":"seg-exercise-2","progressSeconds":125.5,"endUserId":"64f1a2b3c4d5e6f7a8b9c0d1","organizationId":"a1b2c3d4e5f6a7b8c9d0e1f2"}}}}}},"responses":{"200":{"description":"Workout session updated successfully.","schema":{"example":{"data":{"id":"67d1a2b3c4e5f6789abc0d1","createdAt":"2025-01-10T08:30:00.000Z","updatedAt":"2025-01-10T08:32:45.500Z","workoutId":"12ab3efd45c67c1234566cd1","workoutSegmentId":"seg-exercise-2","status":"started","duration":125.5,"progress":0.15}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutSessionResponse"}}}},"400":{"description":"Invalid data provided in the request body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed (API key invalid or Bearer token invalid).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The specified workout ID or session ID does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Session is already completed and cannot be updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["workouts"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X PATCH 'https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/sessions/<SESSION_ID>' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function patchWorkoutSession() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/sessions/<SESSION_ID>', {\n  method: 'PATCH',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.patch(\n    \"https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/sessions/<SESSION_ID>\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]},"get":{"operationId":"WorkoutsSessionsApi_getWorkoutSession","summary":"Get specific workout session details","description":"\n## Get session by id\n\nReturns one session (`status`, `duration`, `progress`, timestamps). Scoped to caller identity: Bearer wins; for key-only attributed sessions pass `endUserId` / `externalUserId` query fields (+ `organizationId` for standard/club keys).\n\n**Related:** `GET .../sessions/recent`, `PATCH .../sessions/{sessionId}`, `POST .../sessions/end`.\n    ","parameters":[{"name":"workoutId","required":true,"in":"path","description":"The unique identifier (24-character hex string) of the workout associated with the session.","example":"12ab3efd45c67c1234566cd1","schema":{"type":"string"}},{"name":"sessionId","required":true,"in":"path","description":"The unique identifier (24-character hex string) of the workout session to retrieve.","example":"12ab3efd45c67c1234566cd1","schema":{"type":"string"}},{"name":"endUserId","required":false,"in":"query","description":"Attribute the session to a specific end user, by internal Hyperhuman user id or email. Resolved against the API key team. Ignored when a member Bearer token is present.","example":"64f1a2b3c4d5e6f7a8b9c0d1","schema":{"type":"string"}},{"name":"externalUserId","required":false,"in":"query","description":"Attribute the session to a specific end user by their external UUID (the externalUUID stored on the team membership). Alternative to endUserId.","example":"ext-user-12345","schema":{"type":"string"}},{"name":"organizationId","required":false,"in":"query","description":"Organization (team) id the end user belongs to. Required for standard/club keys that span organizations; defaults to the API key team for team-scoped keys.","example":"a1b2c3d4e5f6a7b8c9d0e1f2","schema":{"type":"string"}}],"responses":{"200":{"description":"Workout session details retrieved successfully.","schema":{"example":{"data":{"id":"67d1a2b3c4e5f6789abc0d1","createdAt":"2025-01-10T08:30:00.000Z","updatedAt":"2025-01-10T08:45:30.500Z","workoutId":"12ab3efd45c67c1234566cd1","workoutSegmentId":"seg-exercise-3","status":"started","duration":930,"progress":0.52}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutSessionResponse"}}}},"401":{"description":"Authentication failed (API key invalid or Bearer token invalid).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The specified workout ID or session ID does not exist (or the session does not belong to the authenticated caller).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["workouts"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/sessions/<SESSION_ID>' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getWorkoutSession() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/sessions/<SESSION_ID>', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/sessions/<SESSION_ID>\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/workouts/{workoutId}/sessions/end":{"post":{"operationId":"WorkoutsSessionsApi_endWorkoutSession","summary":"End a workout session","description":"\n## End session (keep last progress)\n\nMarks the session completed using duration from the last PATCH (`progressSeconds`). Does **not** force 100% — use `POST .../sessions/complete` for that. If no PATCH ran, duration is `0`.\n\n**Related:** `PATCH .../sessions/{sessionId}`, `POST .../sessions/complete`, `POST .../feedback`.\n    ","parameters":[{"name":"workoutId","required":true,"in":"path","description":"The unique identifier (24-character hex string) of the workout associated with the session.","example":"12ab3efd45c67c1234566cd1","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Data required to end the session. For a key-only attributed session, re-send the same end-user fields used on start (`endUserId` or `externalUserId`, plus `organizationId` for standard/club keys) so the lookup stays scoped to that end user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EndWorkoutSessionBody"},"examples":{"endSession":{"summary":"End a session","description":"Ends the session with duration from last PATCH.","value":{"sessionId":"12ab3efd45c67c1234566cd1"}},"attributed-end-user":{"summary":"End an attributed session (API key)","description":"Re-send the end-user attribution for a key-only attributed session.","value":{"sessionId":"12ab3efd45c67c1234566cd1","endUserId":"64f1a2b3c4d5e6f7a8b9c0d1","organizationId":"a1b2c3d4e5f6a7b8c9d0e1f2"}}}}}},"responses":{"200":{"description":"Workout session successfully marked as completed.","schema":{"example":{"data":{"id":"67d1a2b3c4e5f6789abc0d1","createdAt":"2025-01-10T08:30:00.000Z","updatedAt":"2025-01-10T09:15:30.000Z","workoutId":"12ab3efd45c67c1234566cd1","workoutSegmentId":"seg-outro","status":"completed","duration":2730,"progress":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutSessionResponse"}}}},"400":{"description":"Invalid request data (e.g., missing sessionId).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed (API key invalid or Bearer token invalid).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The specified workout ID or session ID does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Session is already completed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["workouts"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/sessions/end' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function endWorkoutSession() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/sessions/end', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/sessions/end\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/workouts/{workoutId}/sessions/complete":{"post":{"operationId":"WorkoutsSessionsApi_completeWorkoutSession","summary":"Complete workout session with 100% progress","description":"\n## Complete a session (force 100%)\n\nMarks the session completed at **100%** progress (full workout duration). Use for \"mark as done\" / offline finish. Prefer `POST .../sessions/end` when you want to keep the last PATCHed `progressSeconds` (abandon or natural stop).\n\nBody requires `sessionId`; re-send attribution fields for key-only attributed sessions.\n\n**Related:** `POST .../sessions/start`, `POST .../sessions/end`, `PATCH .../sessions/{sessionId}`, `POST .../feedback`.\n    ","parameters":[{"name":"workoutId","required":true,"in":"path","description":"The unique identifier (24-character hex string) of the workout associated with the session.","example":"12ab3efd45c67c1234566cd1","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Data required to complete the session. For a key-only attributed session, re-send the same end-user fields used on start (`endUserId` or `externalUserId`, plus `organizationId` for standard/club keys) so the lookup stays scoped to that end user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteWorkoutSessionBody"},"examples":{"completeSession":{"summary":"Mark a specific session as 100% completed","description":"Force complete a session for user's workout history","value":{"sessionId":"12ab3efd45c67c1234566cd1"}},"attributed-end-user":{"summary":"Complete an attributed session (API key)","description":"Re-send the end-user attribution for a key-only attributed session.","value":{"sessionId":"12ab3efd45c67c1234566cd1","endUserId":"64f1a2b3c4d5e6f7a8b9c0d1","organizationId":"a1b2c3d4e5f6a7b8c9d0e1f2"}}}}}},"responses":{"200":{"description":"Workout session successfully marked as 100% completed.","schema":{"example":{"data":{"id":"67d1a2b3c4e5f6789abc0d1","createdAt":"2025-01-10T08:30:00.000Z","updatedAt":"2025-01-10T09:00:00.000Z","workoutId":"12ab3efd45c67c1234566cd1","workoutSegmentId":"seg-outro","status":"completed","duration":1800,"progress":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutSessionResponse"}}}},"400":{"description":"Invalid request data (e.g., missing sessionId).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed (API key invalid or Bearer token invalid).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The specified workout ID or session ID does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The workout session is already marked as completed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["workouts"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/sessions/complete' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function completeWorkoutSession() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/sessions/complete', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/sessions/complete\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/workouts/{workoutId}/sessions/recent":{"get":{"operationId":"WorkoutsSessionsApi_getRecentWorkoutSession","summary":"Get most recent workout session","description":"\n## Most recent in-progress session\n\nReturns the most recent **started** (not completed) session for this workout — resume-first UX.\n\n**Identity required:** Bearer token **or** `endUserId` / `externalUserId` query fields (+ `organizationId` for standard/club keys). Fully anonymous key-only → **404**.\n\n**Related:** `POST .../sessions/start`, `GET .../sessions/{sessionId}`, `PATCH .../sessions/{sessionId}`.\n    ","parameters":[{"name":"workoutId","required":true,"in":"path","description":"The unique identifier (24-character hex string) of the workout for which to find the recent session.","example":"12ab3efd45c67c1234566cd1","schema":{"type":"string"}},{"name":"endUserId","required":false,"in":"query","description":"Attribute the session to a specific end user, by internal Hyperhuman user id or email. Resolved against the API key team. Ignored when a member Bearer token is present.","example":"64f1a2b3c4d5e6f7a8b9c0d1","schema":{"type":"string"}},{"name":"externalUserId","required":false,"in":"query","description":"Attribute the session to a specific end user by their external UUID (the externalUUID stored on the team membership). Alternative to endUserId.","example":"ext-user-12345","schema":{"type":"string"}},{"name":"organizationId","required":false,"in":"query","description":"Organization (team) id the end user belongs to. Required for standard/club keys that span organizations; defaults to the API key team for team-scoped keys.","example":"a1b2c3d4e5f6a7b8c9d0e1f2","schema":{"type":"string"}}],"responses":{"200":{"description":"Most recent workout session details retrieved successfully.","schema":{"example":{"data":{"id":"67d1a2b3c4e5f6789abc0d1","createdAt":"2025-01-10T08:30:00.000Z","updatedAt":"2025-01-10T08:45:30.500Z","workoutId":"12ab3efd45c67c1234566cd1","workoutSegmentId":"seg-exercise-3","status":"started","duration":930,"progress":0.52}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutSessionResponse"}}}},"401":{"description":"Authentication failed (API key invalid or Bearer token invalid).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No in-progress workout session found for this workout and the resolved end user. Also returned when the call is anonymous (no Bearer token and no endUserId/externalUserId to resolve an identity).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["workouts"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/sessions/recent' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getRecentWorkoutSession() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/sessions/recent', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/sessions/recent\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/workouts/feedback/options":{"get":{"operationId":"WorkoutsFeedbackApi_getWorkoutFeedbackOptions","summary":"Get workout feedback options","description":"\n## Feedback options\n\nReturns the rating and difficulty scales for workout feedback. Use the option **ids** (not numeric values) when submitting `POST /v1/workouts/{id}/feedback`.\n\n**Response shape:** `{ \"data\": { \"rating\": [{ id, label, value }], \"difficulty\": [{ id, label, value }] } }`.\n\n**Related:** `POST /v1/workouts/{id}/feedback`, `POST /v1/workouts/{id}/sessions/complete`.\n    ","parameters":[],"responses":{"200":{"description":"Successfully retrieved feedback options with all available rating scales.","schema":{"example":{"data":{"rating":[{"id":"60af7f618ded6000114c92c0","label":"Awful","value":1},{"id":"60af7f828ded6000114c92c1","label":"Meh","value":2},{"id":"60af7f8a8ded6000114c92c2","label":"So-so","value":3},{"id":"60af7f958ded6000114c92c3","label":"Good","value":4},{"id":"60af7f9d8ded6000114c92c4","label":"Awesome","value":5}],"difficulty":[{"id":"60af7faa8ded6000114c92c5","label":"Very easy","value":1},{"id":"60af7fb28ded6000114c92c6","label":"Easy","value":2},{"id":"60af7fb98ded6000114c92c7","label":"Just right","value":3},{"id":"60af7fc48ded6000114c92c8","label":"Hard","value":4},{"id":"60af7fcb8ded6000114c92c9","label":"Very hard","value":5}]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutFeedbackOptionsResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["workouts"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/workouts/feedback/options' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getWorkoutFeedbackOptions() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/workouts/feedback/options', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/workouts/feedback/options\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/workouts/{workoutId}/feedback":{"post":{"operationId":"WorkoutsFeedbackApi_submitWorkoutFeedback","summary":"Submit workout feedback","description":"\n## Submit workout feedback\n\nSubmit feedback for a completed (or abandoned) session on a **persisted** workout id.\n\n**Body:** `workoutSessionId` (required) plus optional `ratingId` / `difficultyId` (option **ids** from `GET /v1/workouts/feedback/options`, not raw numbers), `comment`, `weightUnit`, `exerciseData[]` (`instanceId` + optional `weight` / `reps`; keep playlist order; omit rest segments). Optional attribution fields (`endUserId` / `externalUserId`, plus `organizationId` for standard/club keys) for key-only attributed sessions.\n\n**Try it:** end a session, fetch feedback options, then POST with `workoutSessionId` + a `ratingId`.\n\n**Related:** `GET /v1/workouts/feedback/options`, `POST /v1/workouts/{id}/sessions/end`, `POST /v1/workouts/{id}/sessions/complete`.\n    ","parameters":[{"name":"workoutId","required":true,"in":"path","description":"The unique identifier (24-character hex string) of the workout receiving feedback.","example":"12ab3efd45c67c1234566cd1","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Workout feedback with ratings, optional comments, and exercise performance data. Use `ratingId` / `difficultyId` option ids from `GET /v1/workouts/feedback/options` (not raw numbers). For a key-only attributed session, send the same end-user fields used on the session (`endUserId` or `externalUserId`, plus `organizationId` for standard/club keys) so the feedback is scoped to that end user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitWorkoutFeedbackBody"},"examples":{"full-feedback":{"summary":"Complete Feedback","description":"Full feedback with rating, difficulty, and comments. Use option ids from GET /v1/workouts/feedback/options.","value":{"workoutSessionId":"64f1a2b3c4d5e6f7a8b9c0d1","ratingId":"60af7f9d8ded6000114c92c4","difficultyId":"60af7fb98ded6000114c92c7","comment":"Great workout! The exercises were challenging but doable. Would love more variety in the warm-up."}},"rating-only":{"summary":"Rating Only","description":"Quick rating without difficulty or comments","value":{"workoutSessionId":"64f1a2b3c4d5e6f7a8b9c0d1","ratingId":"60af7f958ded6000114c92c3"}},"attributed-end-user":{"summary":"Attributed Feedback (API key)","description":"Attribute feedback to a specific end user without a member token. Resolved against the API key team.","value":{"workoutSessionId":"64f1a2b3c4d5e6f7a8b9c0d1","ratingId":"60af7f9d8ded6000114c92c4","difficultyId":"60af7fb98ded6000114c92c7","endUserId":"64f1a2b3c4d5e6f7a8b9c0d1","organizationId":"a1b2c3d4e5f6a7b8c9d0e1f2"}},"anonymous-feedback":{"summary":"Anonymous Feedback","description":"Feedback from non-authenticated user session","value":{"workoutSessionId":"64f1a2b3c4d5e6f7a8b9c0d1","ratingId":"60af7f9d8ded6000114c92c4","difficultyId":"60af7fb98ded6000114c92c7","comment":"Perfect for beginners!"}},"with-exercise-data":{"summary":"Feedback with Exercise Performance Data","description":"Feedback including weights and reps tracking","value":{"workoutSessionId":"64f1a2b3c4d5e6f7a8b9c0d1","ratingId":"60af7f9d8ded6000114c92c4","difficultyId":"60af7fb98ded6000114c92c7","weightUnit":"metric","exerciseData":[{"instanceId":"64f1a2b3c4d5e6f7a8b9c0d2","weight":25.5},{"instanceId":"64f1a2b3c4d5e6f7a8b9c0d3","reps":15},{"instanceId":"64f1a2b3c4d5e6f7a8b9c0d4","weight":20,"reps":12}],"comment":"Great workout!"}}}}}},"responses":{"201":{"description":"Feedback submitted successfully.","schema":{"example":{"data":{"id":"67d1a2b3c4e5f6789abc0d2","createdAt":"2025-01-10T09:30:00.000Z","updatedAt":"2025-01-10T09:30:00.000Z","workoutId":"12ab3efd45c67c1234566cd1","workoutSessionId":"67d1a2b3c4e5f6789abc0d1","rating":{"id":"rating-4-stars","label":"Very Good","value":4},"difficulty":{"id":"difficulty-challenging","label":"Challenging","value":4},"comment":"Great workout! Felt appropriately challenging.","weightUnit":"metric","exerciseData":[{"instanceId":"64f1a2b3c4d5e6f7a8b9c0d2","reps":15},{"instanceId":"64f1a2b3c4d5e6f7a8b9c0d3","weight":25,"reps":12}]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutFeedbackResponse"}}}},"400":{"description":"Invalid feedback data provided (e.g., missing required rating, invalid rating value, missing weightUnit when weights provided, invalid instanceIds). Check feedback options endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed (API key invalid or Bearer token invalid if provided).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The specified workout ID does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["workouts"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/feedback' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function submitWorkoutFeedback() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/feedback', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/workouts/<WORKOUT_ID>/feedback\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/plans/metadata":{"get":{"operationId":"PlansApi_getPlanMetadata","summary":"Get available plan goals and difficulties","description":"\n## Plan metadata\n\nReturns `goals` (`{ id, name }[]`) and `difficulties` for plan filters / `POST .../plans/generate`.\n\n**Try it:** `GET /v1/plans/metadata?locale=en-US` with `X-Api-Key`. Optional `locale` localizes goal names.\n\n**Related:** `POST /v1/orgs/{orgId}/plans/generate`, `POST /v1/orgs/{orgId}/plans/recommend`, `GET /v1/orgs/{orgId}/plans`, `GET /v1/workouts/metadata`, `GET /v1/workouts/equipment/metadata`.\n    ","parameters":[{"name":"locale","required":false,"in":"query","description":"Preferred language locale (e.g., fr-FR)","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved plan goals and difficulty lists.","content":{"application/json":{"schema":{"type":"object","properties":{"goals":{"type":"array","description":"List of all available plan goals.","items":{"type":"object","properties":{"id":{"type":"string","description":"Goal ID","example":"63c92926f920a9005c4e619c"},"name":{"type":"string","description":"Goal display name","example":"Lose weight"}},"required":["id","name"]}},"difficulties":{"type":"array","description":"List of all available plan difficulty levels.","items":{"type":"string","example":"intermediate"}}},"example":{"goals":[{"id":"63c92926f920a9005c4e619c","name":"Lose weight"},{"id":"63c92926f920a9005c4e619d","name":"Build strength"},{"id":"63c92926f920a9005c4e619e","name":"Improve endurance"}],"difficulties":["beginner","intermediate","advanced"]}}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["plans"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/plans/metadata' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getPlanMetadata() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/plans/metadata', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/plans/metadata\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/plans/{planId}":{"get":{"operationId":"PlansApi_getPlan","summary":"Get training plan details","description":"\n## Training plan details\n\nReturns one plan: name, description, difficulty, visibility, `durationInWeeks`, `workoutsPerWeek`, goals, trainer, preview, share link, organization (when applicable).\n\n**Try it:** `GET /v1/plans/{planId}?locale=en-US` with `X-Api-Key`. For the workout list, call `GET /v1/plans/{planId}/workouts`.\n\n**Localization:** optional `locale` affects name, description, goal names (unsupported → English fallback).\n\n**Related:** `GET /v1/orgs/{orgId}/plans`, `GET /v1/plans/{id}/workouts`, `GET /v1/plans/metadata`, `POST /v1/orgs/{orgId}/plans/generate`.\n    ","parameters":[{"name":"planId","required":true,"in":"path","description":"The unique identifier (24-character hex string) of the workout plan to retrieve.","example":"12ab3efd45c67c1234566cd1","schema":{"type":"string"}},{"name":"locale","required":false,"in":"query","description":"Preferred language locale for localized content (e.g., en-US, fr-FR, de-DE). Affects plan name, description, and goal names.","example":"en-US","schema":{"type":"string","enum":["en-US","en-GB","en-AU","fr-FR","de-DE","es-ES","it-IT","pt-PT","he-IL","ro-RO","cs-CZ","fi-FI","lt-LT","nl-NL","pl-PL","ar-XA"]}}],"responses":{"200":{"description":"Workout plan details retrieved successfully with duration information.","content":{"application/json":{"examples":{"8-week-program":{"summary":"8-Week Strength Program","description":"Example of an 8-week program with 3 workouts per week","value":{"data":{"id":"64f1a2b3c4d5e6f7a8b9c0d2","name":"8-Week Strength Program","description":"A comprehensive strength building program designed for intermediate fitness levels","difficulty":"intermediate","visibility":"public","durationInWeeks":8,"workoutsPerWeek":3,"goals":[{"id":"64f1a2b3c4d5e6f7a8b9c0d3","name":"Build Strength","nameTranslations":{}}],"trainer":{"id":"64f1a2b3c4d5e6f7a8b9c0d4","name":"Sarah Johnson"},"preview":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/plan-preview.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://images.hyperhuman.cc/plan-poster.jpg","thumbnail":"https://images.hyperhuman.cc/plan-thumb.jpg"},"shareLink":{"url":"https://app.hyperhuman.cc/plans/64f1a2b3c4d5e6f7a8b9c0d2"},"organization":{"id":"org-hyperhuman-llc","name":"Hyperhuman LLC","logo":{"url":"https://images.hyperhuman.cc/logo.png"}}}}},"12-week-program":{"summary":"12-Week Transformation Program","description":"Example of a longer 12-week program with 4 workouts per week","value":{"data":{"id":"64f1a2b3c4d5e6f7a8b9c0d5","name":"12-Week Transformation Program","description":"An intensive 12-week program for advanced fitness levels","difficulty":"advanced","visibility":"public","durationInWeeks":12,"workoutsPerWeek":4,"goals":[{"id":"64f1a2b3c4d5e6f7a8b9c0d6","name":"Weight Loss","nameTranslations":{}},{"id":"64f1a2b3c4d5e6f7a8b9c0d7","name":"Build Muscle","nameTranslations":{}}],"trainer":{"id":"64f1a2b3c4d5e6f7a8b9c0d8","name":"Mike Chen"},"preview":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/transformation-preview.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://images.hyperhuman.cc/transformation-poster.jpg","thumbnail":"https://images.hyperhuman.cc/transformation-thumb.jpg"},"shareLink":{"url":"https://app.hyperhuman.cc/plans/64f1a2b3c4d5e6f7a8b9c0d5"},"organization":null}}}}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The specified plan ID does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["plans"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/plans/<PLAN_ID>' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getPlan() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/plans/<PLAN_ID>', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/plans/<PLAN_ID>\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/plans/{planId}/workouts":{"get":{"operationId":"PlansApi_getPlanWorkouts","summary":"Get workouts in training plan","description":"\n## Plan workouts\n\nReturns **all** workouts in the plan as `{ data, links }`, ordered in program sequence. **No** server-side paging of the array — paginate in the client if the UI needs it.\n\n**Try it:** `GET /v1/plans/{planId}/workouts?locale=en-US` with `X-Api-Key`. Optional `locale` localizes workout display fields.\n\n**Related:** `GET /v1/plans/{id}`, `GET /v1/workouts/{id}`, `GET /v1/orgs/{orgId}/plans`, `POST /v1/workouts/{id}/sessions/start`.\n    ","parameters":[{"name":"planId","required":true,"in":"path","description":"The unique identifier (24-character hex string) of the workout plan.","example":"12ab3efd45c67c1234566cd1","schema":{"type":"string"}},{"name":"locale","required":false,"in":"query","description":"Preferred language locale (e.g., fr-FR)","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved complete list of workouts for the plan.","schema":{"example":{"data":[{"id":"64f1a2b3c4d5e6f7a8b9c0d1","trainer":{"id":"64f1a2b3c4d5e6f7a8b9c0d4","name":"Sarah Johnson"},"createdAt":"2023-10-26T10:00:00.000Z","updatedAt":"2023-10-27T11:30:00.000Z","name":"Upper Body Strength","description":"Focus on chest, shoulders, and arms","duration":2700,"difficulty":"intermediate","visibility":"public","categories":[{"id":"615aa3dadbe7140012c59e90","name":"Strength"}],"preview":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/workout-preview.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://images.hyperhuman.cc/workout-poster.jpg","thumbnail":"https://images.hyperhuman.cc/workout-poster.jpg"},"rating":4.5,"locked":false,"mixBgMusic":true,"presentationStyle":"full","skipWorkoutPreview":false,"skipWorkoutCompletionScreen":false,"videoAudioMode":"full","allowAssessment":false,"assessmentType":null},{"id":"64f1a2b3c4d5e6f7a8b9c0d2","trainer":{"id":"64f1a2b3c4d5e6f7a8b9c0d4","name":"Sarah Johnson"},"createdAt":"2023-10-26T10:00:00.000Z","updatedAt":"2023-10-27T11:30:00.000Z","name":"Lower Body Power","description":"Intense leg and glute workout","duration":2400,"difficulty":"intermediate","visibility":"public","categories":[{"id":"615aa3dadbe7140012c59e90","name":"Strength"}],"preview":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/workout-preview-2.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://images.hyperhuman.cc/workout-poster-2.jpg","thumbnail":"https://images.hyperhuman.cc/workout-poster-2.jpg"},"rating":4.7,"locked":false,"mixBgMusic":true,"presentationStyle":"full","skipWorkoutPreview":false,"skipWorkoutCompletionScreen":false,"videoAudioMode":"full","allowAssessment":false,"assessmentType":null}],"links":{}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutListResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The specified plan ID does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["plans"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/plans/<PLAN_ID>/workouts' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getPlanWorkouts() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/plans/<PLAN_ID>/workouts', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/plans/<PLAN_ID>/workouts\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/video-assets":{"get":{"operationId":"OrganizationExercisesApi_getOrganizationExercises","summary":"List workspace exercise videos for an organization","description":"\n## Workspace exercise library\n\nPaginated **published workspace-only** exercise videos for catalogs/builders/players (`{ data, links, explanation? }`). Stock / pay-as-you-go are not included. No `visibility` filter.\n\n**Try it:** `GET /v1/orgs/{organizationId}/video-assets?limit=10` with `X-Api-Key`. Pagination: `limit` default **10** (max **50**); advance via `links.next`.\n\n**Filters (AND):** `q` (substring; locale-aware with `?locale=`), `equipmentIds`, `muscleGroupIds`, `kinds`, `skillLevels`, `executionSides`, `coach`, `collectionNames` (CSV plain strings — see DTO). Sort: `date`/`name`/`kind` with `+`/`-` (default `-date`).\n\n**Video type guide (`kinds` CSV):** product **Exercise** → `single-exercise`; **Multi-exercise** → `multi-exercise`; **Class** → `class`; **Promo** → `promo`; **Educational** → `educational`. Allowed values only — unknown tokens → `400`.\n\n**Audio:** `audioInstructions[]` only on `kind: single-exercise` (presigned `assetUri`, optional `scriptText`). Other kinds return `[]`.\n\n**Related:** `GET /v1/orgs/{orgId}/groups`, `GET /v1/workouts/metadata`, `GET /v1/orgs/{orgId}/stock-exercises`.\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"Unique organization (workspace) resource id for Hyperhuman Teams - opaque 24-character hex string.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Maximum number of items to return per page.","example":10,"schema":{"minimum":1,"maximum":50,"default":10,"type":"number"}},{"name":"q","required":false,"in":"query","description":"Search text","schema":{"type":"string"}},{"name":"sort","required":false,"in":"query","description":"Sortable fields (use `+` / `-` prefix, comma-separated for multi-key). Allowed: `date` (alias of `createdAt`), `name`, `kind`. Default: `-date` (newest first). Examples: `-date`, `+name`, `-kind,+name`.","example":"-date","schema":{"type":"string"}},{"name":"locale","required":false,"in":"query","description":"BCP-47 locale (e.g. en-US). Localizes text and locale-aware media when supported; falls back to English.","example":"en-US","schema":{"type":"string"}},{"name":"equipmentIds","required":false,"in":"query","description":"Comma-separated equipment ids (24-character hex). Returns assets whose `equipment[]` includes ANY of these.","example":"60d21b4667d0d8992e610c90,60d21b4667d0d8992e610c91","schema":{"type":"string"}},{"name":"muscleGroupIds","required":false,"in":"query","description":"Comma-separated muscle-group ids (24-character hex). Returns assets whose `muscleGroups[]` includes ANY of these.","example":"60d21b4667d0d8992e610c85","schema":{"type":"string"}},{"name":"kinds","required":false,"in":"query","description":"Comma-separated video kinds. Allowed: `single-exercise`, `multi-exercise`, `class`, `promo`, `educational`. See the **Video type guide** in the endpoint description for product-name-to-`kind` mapping.","example":"single-exercise,educational","schema":{"type":"string"}},{"name":"skillLevels","required":false,"in":"query","description":"Comma-separated skill levels. Allowed: `beginner`, `intermediate`, `advanced`.","example":"beginner,intermediate","schema":{"type":"string"}},{"name":"executionSides","required":false,"in":"query","description":"Comma-separated execution sides. Allowed: `both`, `left`, `right`, `alternating`.","example":"both,alternating","schema":{"type":"string"}},{"name":"coach","required":false,"in":"query","description":"Coach gender as recorded on the asset.","example":"female","schema":{"enum":["male","female"],"type":"string"}},{"name":"collectionNames","required":false,"in":"query","description":"Comma-separated collection names (exact match, case-sensitive). Rows with empty `collectionName` are excluded when this filter is set.","example":"Morning cardio,Yoga flow","schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated workspace exercise videos with previews and metadata.","schema":{"example":{"data":[{"id":"60812dea606fc90011eb4405","createdAt":"2025-09-15T10:30:00Z","name":"Jumping Jacks","kind":"single-exercise","trainer":{"id":"63a1c2b4f0e1a200126616a1","name":"Sarah Johnson"},"muscleGroups":[{"id":"60d21b4667d0d8992e610c85","name":"Full Body"}],"equipment":[{"id":"60d21b4667d0d8992e610c90","name":"Bodyweight"}],"preview":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/ex-60812dea.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://hhcontent.s3.eu-central-1.amazonaws.com/thumbnails/ex-60812dea.jpg","thumbnail":"https://hhcontent.s3.eu-central-1.amazonaws.com/thumbnails/ex-60812dea.jpg"},"playsInLoop":true,"organization":{"id":"63415bf67a9c7000126616c1","name":"My Gym","logo":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/logos/org-63415bf67a9c7000126616c1.png"}},"audioInstructions":[{"id":"65a1b2c3d4e5f600126616a1","createdAt":"2025-09-15T10:31:00Z","assetUri":"https://hhcontent.s3.eu-central-1.amazonaws.com/audio/inst-60812dea-en-US.m4a?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","type":"exerciseInstruction","locale":"en-US","scriptText":"Stand tall with your feet shoulder-width apart. Jump up while raising your arms overhead and spreading your legs out to the sides."},{"id":"65a1b2c3d4e5f600126616a2","createdAt":"2025-09-15T10:31:00Z","assetUri":"https://hhcontent.s3.eu-central-1.amazonaws.com/audio/inst-60812dea-fr-FR.m4a?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","type":"exerciseInstruction","locale":"fr-FR","scriptText":"Tenez-vous droit, pieds écartés à la largeur des épaules. Sautez en levant les bras au-dessus de la tête et en écartant les jambes sur les côtés."}],"skillLevel":"beginner","tags":["warmup"],"collectionName":"Morning cardio"}],"links":{"next":"https://content.api.hyperhuman.cc/v1/orgs/63415bf67a9c7000126616c1/video-assets?limit=10&offset=10","total":142},"explanation":"Published exercise videos from your workspace."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VideoAssetsListResponse"}}}},"400":{"description":"Request validation failed. `error.code` is `ValidationError`; `error.target` is the DTO class name; `error.details[]` lists the offending fields.","schema":{"example":{"error":{"code":"ValidationError","message":"ValidationError","target":"GetVideoAssetsByOrganizationIdParams","details":[{"code":"ConstraintError","message":"organizationId must be a mongodb id","target":"organizationId"}]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, malformed, or unknown `X-Api-Key` header.","schema":{"example":{"error":{"code":"Unauthorized","message":"Unauthorized"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is valid but is not authorized for this `organizationId` (the key belongs to a different workspace, or no API key was sent on a guarded route).","schema":{"example":{"error":{"code":"Forbidden","message":"API key not authorized for this organization"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No workspace exists for the supplied `organizationId`.","schema":{"example":{"error":{"code":"NotFound","message":"Organization not found"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["library-exercises"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/video-assets' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getOrganizationExercises() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/video-assets', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/video-assets\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/stock-exercises":{"get":{"operationId":"OrganizationStockExercisesApi_getStockExercises","summary":"List browsable stock exercise catalog","description":"\n## Stock exercise catalog\n\nPaginated **published public single-exercise** stock clips (free + premium) for browse/playback. Not AI-generation fuel. Requires Content API access plus stock-catalog entitlement (or active Ultra yearly). Response omits `trainer` / `bundle` / `organization`.\n\n**Try it:** `GET /v1/orgs/{organizationId}/stock-exercises?limit=10` with `X-Api-Key`. Pagination: `limit` default **10** (max **50**); advance via `links.next`. Each call counts as **10x**.\n\n**Filters:** `q` (substring), `equipmentIds`, `muscleGroupIds`, `skillLevels`, `executionSides`, `coach`, `collectionNames`, plus `availability` (`free-stock` | `premium-stock` | `all-stock`). No `kinds` filter (catalog is hard-scoped to `single-exercise` — sending `kinds` → `400`).\n\n**Related:** `GET /v1/orgs/{orgId}/video-assets`, `GET /v1/workouts/exercises/metadata`.\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"Unique organization (workspace) resource id for Hyperhuman Teams - opaque 24-character hex string.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Maximum number of items to return per page.","example":10,"schema":{"minimum":1,"maximum":50,"default":10,"type":"number"}},{"name":"q","required":false,"in":"query","description":"Search text","schema":{"type":"string"}},{"name":"sort","required":false,"in":"query","description":"Sortable fields (use `+` / `-` prefix, comma-separated for multi-key). Allowed: `date` (alias of `createdAt`), `name`, `kind`. Default: `-date` (newest first). Examples: `-date`, `+name`.","example":"-date","schema":{"type":"string"}},{"name":"locale","required":false,"in":"query","description":"BCP-47 locale (e.g. en-US). Localizes text and locale-aware media when supported; falls back to English.","example":"en-US","schema":{"type":"string"}},{"name":"equipmentIds","required":false,"in":"query","description":"Comma-separated equipment ids (24-character hex). Returns assets whose `equipment[]` includes ANY of these.","example":"60d21b4667d0d8992e610c90,60d21b4667d0d8992e610c91","schema":{"type":"string"}},{"name":"muscleGroupIds","required":false,"in":"query","description":"Comma-separated muscle-group ids (24-character hex). Returns assets whose `muscleGroups[]` includes ANY of these.","example":"60d21b4667d0d8992e610c85","schema":{"type":"string"}},{"name":"skillLevels","required":false,"in":"query","description":"Comma-separated skill levels. Allowed: `beginner`, `intermediate`, `advanced`.","example":"beginner,intermediate","schema":{"type":"string"}},{"name":"executionSides","required":false,"in":"query","description":"Comma-separated execution sides. Allowed: `both`, `left`, `right`, `alternating`.","example":"both,alternating","schema":{"type":"string"}},{"name":"coach","required":false,"in":"query","description":"Coach gender as recorded on the asset.","example":"female","schema":{"enum":["male","female"],"type":"string"}},{"name":"collectionNames","required":false,"in":"query","description":"Comma-separated collection names (exact match, case-sensitive). Rows with empty `collectionName` are excluded when this filter is set.","example":"Premium - Neutral,Free - Eclectic Home","schema":{"type":"string"}},{"name":"availability","required":false,"in":"query","description":"Stock tier to return. Allowed: `free-stock`, `premium-stock`, `all-stock`. Default: `all-stock` (free and premium).","example":"all-stock","schema":{"enum":["free-stock","premium-stock","all-stock"],"type":"string"}}],"responses":{"200":{"description":"Paginated stock single-exercise videos with previews and metadata.","schema":{"example":{"data":[{"id":"60812dea606fc90011eb4405","createdAt":"2025-09-15T10:30:00Z","name":"Jumping Jacks","kind":"single-exercise","playsInLoop":true,"muscleGroups":[{"id":"60d21b4667d0d8992e610c85","name":"Full Body"}],"equipment":[{"id":"60d21b4667d0d8992e610c90","name":"Bodyweight"}],"preview":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/ex-60812dea.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://hhcontent.s3.eu-central-1.amazonaws.com/thumbnails/ex-60812dea.jpg","thumbnail":"https://hhcontent.s3.eu-central-1.amazonaws.com/thumbnails/ex-60812dea.jpg"},"collectionName":"Free - Eclectic Home","coach":"female","skillLevel":"beginner","categories":["cardio"],"executionSide":"both","audioInstructions":[{"id":"65a1b2c3d4e5f600126616a1","createdAt":"2025-09-15T10:31:00Z","assetUri":"https://hhcontent.s3.eu-central-1.amazonaws.com/audio/inst-60812dea-en-US.m4a?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","type":"exerciseInstruction","locale":"en-US","scriptText":"Stand tall with your feet shoulder-width apart. Jump up while raising your arms overhead and spreading your legs out to the sides."}]}],"links":{"next":"https://content.api.hyperhuman.cc/v1/orgs/63415bf67a9c7000126616c1/stock-exercises?limit=10&offset=10","total":2030},"explanation":"Showing 2030 published stock exercise videos."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StockVideoAssetsListResponse"}}}},"400":{"description":"Request validation failed. `error.code` is `ValidationError`; `error.target` is the DTO class name; `error.details[]` lists the offending fields.","schema":{"example":{"error":{"code":"ValidationError","message":"ValidationError","target":"GetStockExercisesByOrganizationIdParams","details":[{"code":"ConstraintError","message":"organizationId must be a mongodb id","target":"organizationId"}]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, malformed, or unknown `X-Api-Key` header.","schema":{"example":{"error":{"code":"Unauthorized","message":"Unauthorized"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this `organizationId`, OR the plan lacks Content API access, OR the plan lacks stock catalog access (requires Ultra annual or a custom plan with `stockVideoCatalogApi`).","schema":{"example":{"error":{"code":"Forbidden","message":"Stock exercise catalog API requires Ultra (annual) or a custom plan with catalog access. Contact sales for a custom plan."}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No workspace exists for the supplied `organizationId`.","schema":{"example":{"error":{"code":"NotFound","message":"Organization not found"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded. Each call to this endpoint counts as 10x against your Content API limits.","schema":{"example":{"error":{"code":"TooManyRequests","message":"Hourly rate limit exceeded"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["library-stock-exercises"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/stock-exercises' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getStockExercises() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/stock-exercises', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/stock-exercises\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/groups":{"get":{"operationId":"OrganizationExerciseGroupsApi_getOrganizationExerciseGroups","summary":"List organization micro workouts (exercise groups)","description":"\n## Micro Workouts (Exercise Groups)\n\n**Micro workouts** are short, focused exercise collections designed for quick sessions. Use these endpoints to surface them in your app.\n\nRetrieves paginated list of exercise collections (micro workouts) for your organization. Each collection has simple execution details: circuit or sets format, rounds, rest periods, and per-exercise config (time-based or reps-based).\n\n---\n\n### Use Cases\n\n- **White-label Apps** - Show organization micro workouts\n- **Quick Workout Browsing** - Circuit and sets-based collections\n- **Integration with Workouts** - Collections can be used in workout generation (excludeExerciseCollections)\n\n---\n\n### Execution Details (per collection)\n\n- **kind**: circuit | sets\n- **rounds**: Number of rounds\n- **roundBreakDuration**: Rest between rounds (ms)\n- **exerciseBreakDuration**: Rest between exercises (ms)\n- **exerciseConfig**: timeBasedConfig (duration, pace, rpe, amrap) or repsBasedConfig (reps, weightLevel, pace, rpe)\n\n---\n\n### Filtering and Pagination\n\n**Visibility:**\n- `public` - Publicly accessible collections (default)\n- `private` - Organization-only (requires API key for same org)\n- `all` - Both (requires API key for same org)\n\n**Pagination:**\n- `offset` - Pagination offset (default: 0)\n- `limit` - Items per page (default: 10, max: 50)\n\n---\n\n### Related Endpoints\n\n- Get Group Detail: `GET /v1/orgs/{orgId}/groups/{groupId}` - Full detail with execution config\n- Get Group Exercises: `GET /v1/orgs/{orgId}/groups/{groupId}/exercises` - Exercises in collection\n- List Workouts: `GET /v1/orgs/{orgId}/workouts` - Organization workouts\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Items per page. Defaults to 10, max 50.","example":10,"schema":{"minimum":1,"maximum":50,"default":20,"type":"number"}},{"name":"locale","required":false,"in":"query","description":"BCP-47 locale (e.g. en-US, fr-FR). Localizes text and locale-aware media when this operation supports it. Falls back to English when unsupported.","example":"en-US","schema":{"type":"string"}},{"name":"visibility","required":false,"in":"query","description":"Filter groups by their visibility status.","example":"public","schema":{"enum":["private","public","all"],"type":"string"}},{"name":"offset","required":false,"in":"query","description":"Pagination offset. Defaults to 0.","example":0,"schema":{"type":"number"}}],"responses":{"200":{"description":"Successfully retrieved paginated list of micro workouts (exercise collections).","schema":{"example":{"data":[{"id":"507f1f77bcf86cd799439011","createdAt":"2025-09-15T10:30:00Z","updatedAt":"2025-09-16T14:20:00Z","name":"Quick HIIT Circuit","kind":"circuit","preview":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/group-507f1f77.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://hhcontent.s3.eu-central-1.amazonaws.com/thumbnails/group-507f1f77.jpg","thumbnail":"https://hhcontent.s3.eu-central-1.amazonaws.com/thumbnails/group-507f1f77.jpg"},"rounds":3,"roundBreakDuration":10000,"exerciseBreakDuration":0,"exerciseConfig":{"timeBasedConfig":{"kind":"timeBased","duration":30000,"pace":"medium","rpe":7,"amrap":false}},"trainer":{"id":"trainer123","name":"Sarah Johnson"}},{"id":"507f1f77bcf86cd799439012","createdAt":"2025-09-10T08:00:00Z","updatedAt":"2025-09-12T11:15:00Z","name":"Upper Body Sets","kind":"sets","preview":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/group-507f1f78.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://hhcontent.s3.eu-central-1.amazonaws.com/thumbnails/group-507f1f78.jpg","thumbnail":"https://hhcontent.s3.eu-central-1.amazonaws.com/thumbnails/group-507f1f78.jpg"},"rounds":2,"roundBreakDuration":60000,"exerciseBreakDuration":15000,"exerciseConfig":{"repsBasedConfig":{"kind":"repsBased","reps":12,"weightLevel":"medium","pace":"medium","rpe":8}},"trainer":{"id":"trainer456","name":"Mike Chen"}}],"links":{"next":"https://content.api.hyperhuman.cc/v1/orgs/63415bf67a9c7000126616c1/groups?limit=10&offset=10","total":24},"explanation":"Your organization micro workouts - circuit and sets-based collections for quick sessions."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupListResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key not authorized for this organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["exercise-groups"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/groups' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getOrganizationExerciseGroups() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/groups', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/groups\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/groups/{groupId}":{"get":{"operationId":"OrganizationExerciseGroupsApi_getOrganizationExerciseGroupById","summary":"Get micro workout (exercise group) by ID","description":"\n## Micro Workout Detail\n\nReturns full detail for a micro workout (exercise collection) belonging to your organization. Includes execution config (circuit/sets, rounds, rest, time-based or reps-based per exercise).\n\n**Response structure:**\n- `kind` - circuit | sets\n- `rounds`, `roundBreakDuration`, `exerciseBreakDuration`\n- `exerciseConfig` - timeBasedConfig (duration, pace, rpe, amrap) or repsBasedConfig (reps, weightLevel, pace, rpe)\n- `preview` - Video preview URLs\n- `trainer`, `organization`\n\n**Access:** Only collections created by organization trainers. Private collections require API key for the same organization.\n\n---\n\n### Related Endpoints\n\n- List Collections: `GET /v1/orgs/{orgId}/groups` - Browse organization collections\n- Get Exercises: `GET /v1/orgs/{orgId}/groups/{groupId}/exercises` - Exercises in this collection\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"groupId","required":true,"in":"path","description":"The unique identifier of the exercise collection (group).","example":"507f1f77bcf86cd799439011","schema":{"type":"string"}},{"name":"locale","required":false,"in":"query","description":"BCP-47 locale (e.g. en-US, fr-FR). Localizes text and locale-aware media when this operation supports it. Falls back to English when unsupported.","example":"en-US","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved micro workout (exercise collection) detail.","schema":{"example":{"data":{"id":"507f1f77bcf86cd799439011","createdAt":"2025-09-15T10:30:00Z","updatedAt":"2025-09-16T14:20:00Z","name":"Quick HIIT Circuit","kind":"circuit","preview":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/group-507f1f77.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://hhcontent.s3.eu-central-1.amazonaws.com/thumbnails/group-507f1f77.jpg","thumbnail":"https://hhcontent.s3.eu-central-1.amazonaws.com/thumbnails/group-507f1f77.jpg"},"rounds":3,"roundBreakDuration":10000,"exerciseBreakDuration":0,"exerciseConfig":{"timeBasedConfig":{"kind":"timeBased","duration":30000,"pace":"medium","rpe":7,"amrap":false}},"trainer":{"id":"trainer123","name":"Sarah Johnson"},"organization":{"id":"63415bf67a9c7000126616c1","name":"My Gym","logo":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/logos/org-63415bf67a9c7000126616c1.png"}}}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key not authorized for this organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Group not found or not accessible","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["exercise-groups"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/groups/<GROUPID>' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getOrganizationExerciseGroupById() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/groups/<GROUPID>', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/groups/<GROUPID>\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/groups/{groupId}/exercises":{"get":{"operationId":"OrganizationExerciseGroupsApi_getOrganizationGroupExercises","summary":"Get exercises in micro workout","description":"\n## Get Micro Workout Exercises\n\nReturns the list of exercises in a micro workout (exercise collection). Each exercise includes video preview, metadata (muscle groups, equipment), and trainer info.\n\n**Use this endpoint to:**\n- Display the exercise sequence for a micro workout\n- Build a preview or playback UI for the collection\n- Get exercise details before starting a session\n\n---\n\n### Related Endpoints\n\n- Get Collection: `GET /v1/orgs/{orgId}/groups/{groupId}` - Collection detail with execution config\n- List Collections: `GET /v1/orgs/{orgId}/groups` - Browse organization collections\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"groupId","required":true,"in":"path","description":"The unique identifier of the exercise collection (group) whose exercises are requested.","example":"507f1f77bcf86cd799439011","schema":{"type":"string"}},{"name":"locale","required":false,"in":"query","description":"BCP-47 locale (e.g. en-US, fr-FR). Localizes text and locale-aware media when this operation supports it. Falls back to English when unsupported.","example":"en-US","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved list of exercises in the micro workout with instance config (reps, duration, pace, rpe).","schema":{"example":{"data":[{"id":"60812dea606fc90011eb4405","createdAt":"2025-09-15T10:30:00Z","name":"Jumping Jacks","kind":"single-exercise","muscleGroups":[{"id":"mg_full_body","name":"Full Body"}],"equipment":[{"id":"eq_bodyweight","name":"Bodyweight"}],"trainer":{"id":"trainer123","name":"Sarah Johnson"},"preview":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/ex-60812dea.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://hhcontent.s3.eu-central-1.amazonaws.com/thumbnails/ex-60812dea.jpg","thumbnail":"https://hhcontent.s3.eu-central-1.amazonaws.com/thumbnails/ex-60812dea.jpg"},"duration":30,"reps":null,"pace":"medium","weightLevel":null,"rpe":7,"amrap":false},{"id":"60812dea606fc90011eb4406","createdAt":"2025-09-15T10:30:00Z","name":"Push-ups","kind":"single-exercise","muscleGroups":[{"id":"mg_chest","name":"Chest"}],"equipment":[{"id":"eq_bodyweight","name":"Bodyweight"}],"trainer":{"id":"trainer123","name":"Sarah Johnson"},"preview":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/ex-60812dea6.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://hhcontent.s3.eu-central-1.amazonaws.com/thumbnails/ex-60812dea6.jpg","thumbnail":"https://hhcontent.s3.eu-central-1.amazonaws.com/thumbnails/ex-60812dea6.jpg"},"duration":24,"reps":12,"pace":"medium","weightLevel":"medium","rpe":8}],"links":{"next":null,"total":5}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupExercisesListResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key not authorized for this organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Group not found or not accessible","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["exercise-groups"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/groups/<GROUPID>/exercises' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getOrganizationGroupExercises() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/groups/<GROUPID>/exercises', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/groups/<GROUPID>/exercises\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/plans":{"get":{"operationId":"OrganizationPlansApi_getOrganizationPlans","summary":"List organization-specific training plans","description":"\n## Organization plan library\n\nPaginated **published** plans for your organization (`public` / `private` only). Persisted AI plans with visibility `end-user-ai-generated` are **not listed** here (even with `visibility=all`) — fetch those via `GET /v1/plans/{id}` using the stored plan id from generate/adapt.\n\n**Try it:** `GET /v1/orgs/{organizationId}/plans?limit=20` with `X-Api-Key`. Pagination: `limit` default **20** (max **50**); advance via `links.next`.\n\n**Optional filters:** `visibility`, `difficulties` (CSV), `goalIds` (CSV hex), `durationInWeeks`, `workoutsPerWeek`, `q` (fuzzy; `sort` ignored while set), `sort`, `locale`.\n\n**Related:** `POST /v1/orgs/{orgId}/plans/recommend`, `POST /v1/orgs/{orgId}/plans/generate`, `GET /v1/plans/{id}`, `GET /v1/plans/metadata`.\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"64f1a2b3c4d5e6f7a8b9c0d1","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Maximum number of items to return per page.","example":20,"schema":{"minimum":1,"maximum":50,"default":20,"type":"number"}},{"name":"q","required":false,"in":"query","description":"Search text","schema":{"type":"string"}},{"name":"sort","required":false,"in":"query","description":"Fields to sort. Prefix them with - (descending) or + (ascending): +someField,-otherField","schema":{"type":"string"}},{"name":"locale","required":false,"in":"query","description":"BCP-47 locale (e.g. en-US, fr-FR). Localizes text and locale-aware media when this operation supports it. Falls back to English when unsupported.","example":"en-US","schema":{"type":"string"}},{"name":"visibility","required":false,"in":"query","description":"Filter plans by their visibility status.","example":"public","schema":{"enum":["private","public","all"],"type":"string"}},{"name":"difficulty","required":false,"in":"query","description":"Filter plans by difficulty level (single value). DEPRECATED: Use 'difficulties' for multiple values.","example":"intermediate","deprecated":true,"schema":{"enum":["beginner","intermediate","advanced"],"type":"string"}},{"name":"difficulties","required":false,"in":"query","description":"Filter plans by one or more difficulty levels (comma-separated). Preferred over 'difficulty'.","example":"beginner,intermediate","schema":{"type":"string"}},{"name":"goalIds","required":false,"in":"query","description":"Filter plans by one or more goal IDs (provide comma-separated values if multiple).","example":"64f1a2b3c4d5e6f7a8b9c0d3,64f1a2b3c4d5e6f7a8b9c0d7","schema":{"type":"string"}},{"name":"durationInWeeks","required":false,"in":"query","description":"Filter plans by duration in weeks (1-24)","example":8,"schema":{"minimum":1,"maximum":24,"type":"number"}},{"name":"workoutsPerWeek","required":false,"in":"query","description":"Filter plans by workouts per week (1-7)","example":3,"schema":{"minimum":1,"maximum":7,"type":"number"}}],"responses":{"200":{"description":"Successfully retrieved paginated list of plans for the organization.","schema":{"example":{"data":[{"id":"64f1a2b3c4d5e6f7a8b9c0d2","name":"8-Week Strength Program","description":"A comprehensive strength building program designed for intermediate fitness levels","difficulty":"intermediate","visibility":"public","durationInWeeks":8,"workoutsPerWeek":3,"createdAt":"2023-10-26T10:00:00.000Z","updatedAt":"2023-10-27T11:30:00.000Z","trainer":{"id":"64f1a2b3c4d5e6f7a8b9c0d4","name":"Sarah Johnson"},"goals":[{"id":"64f1a2b3c4d5e6f7a8b9c0d3","name":"Build Strength","nameTranslations":{}}],"preview":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/plan-preview.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://images.hyperhuman.cc/plan-poster.jpg","thumbnail":"https://images.hyperhuman.cc/plan-thumb.jpg"}},{"id":"64f1a2b3c4d5e6f7a8b9c0d5","name":"12-Week Transformation Program","description":"An intensive 12-week program for advanced fitness levels","difficulty":"advanced","visibility":"public","durationInWeeks":12,"workoutsPerWeek":4,"createdAt":"2023-10-26T10:00:00.000Z","updatedAt":"2023-10-27T11:30:00.000Z","trainer":{"id":"64f1a2b3c4d5e6f7a8b9c0d8","name":"Mike Chen"},"goals":[{"id":"64f1a2b3c4d5e6f7a8b9c0d6","name":"Weight Loss","nameTranslations":{}},{"id":"64f1a2b3c4d5e6f7a8b9c0d7","name":"Build Muscle","nameTranslations":{}}],"preview":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/transformation-preview.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://images.hyperhuman.cc/transformation-poster.jpg","thumbnail":"https://images.hyperhuman.cc/transformation-thumb.jpg"}}],"links":{"next":"https://content.api.hyperhuman.cc/v1/orgs/63415bf67a9c7000126616c1/plans?offset=20&limit=20","total":45}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanListResponse"}}}},"400":{"description":"Invalid pagination or filter parameters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The specified organization ID does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["plans"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/plans' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getOrganizationPlans() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/plans', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/plans\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/plans/recommend":{"post":{"operationId":"OrganizationPlanRecommendation_getPlanRecommendations","summary":"Get training plan recommendations from existing library","description":"\n## Recommend plans from your library\n\nRanks **existing multi-week plans** in your organization library for a user profile. Prefer this over `POST .../plans/generate` when your team already publishes programs and you want the best library match.\n\n**Try it (minimal):** body `{ \"endUserProfileDetails\": { \"age\": 30, \"fitnessLevels\": [\"beginner\"] } }`. Response is a bare object `{ plans, reasoning }` (not wrapped in `data`). Up to **12** plans; each item includes a `recommendation` text reason (not a numeric score).\n\n**Body:** `endUserProfileDetails`, optional root `goalIds`, optional `locale` — unknown keys return `400 ValidationError`.\n\n**Rate limit:** counts as **10x** toward hourly/daily limits.\n\n**Related:** `POST /v1/orgs/{orgId}/plans/generate`, `GET /v1/orgs/{orgId}/plans`, `GET /v1/plans/metadata`, `GET /v1/plans/{id}`.\n        ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"Organization/Team unique identifier","example":"67e2e9d0e23f010013e19dec","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanRecommendationRequestDto"},"examples":{"minimal":{"summary":"Minimal profile","value":{"endUserProfileDetails":{"age":30,"fitnessLevels":["beginner"]}}}}}}},"responses":{"200":{"description":"Ranked list of recommended training plans with per-item recommendation text and overall reasoning","schema":{"example":{"plans":[{"id":"507f1f77bcf86cd799439017","name":"8-Week Strength Building Program","description":"Progressive strength program with balanced muscle group distribution","difficulty":"intermediate","thumbnailUrl":"https://hhcontent.s3.eu-central-1.amazonaws.com/plans/507f1f77bcf86cd799439017/thumbnail.jpg","recommendation":"Perfect match for your strength goals and intermediate fitness level","goals":[{"id":"63c92926f920a9005c4e619d","name":"Build Strength"}],"preview":{"url":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/plan-preview.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=...","poster":"https://hhcontent.s3.eu-central-1.amazonaws.com/plans/507f1f77bcf86cd799439017/thumbnail.jpg","thumbnail":"https://hhcontent.s3.eu-central-1.amazonaws.com/plans/507f1f77bcf86cd799439017/thumbnail.jpg"}},{"id":"507f1f77bcf86cd799439018","name":"12-Week Transformation Program","description":"Comprehensive program combining strength and cardio for complete transformation","difficulty":"intermediate","thumbnailUrl":"https://hhcontent.s3.eu-central-1.amazonaws.com/plans/507f1f77bcf86cd799439018/thumbnail.jpg","recommendation":"Matches your goals and training frequency preferences","goals":[{"id":"63c92926f920a9005c4e619c","name":"Lose Weight"},{"id":"63c92926f920a9005c4e61a0","name":"Get Toned"}]},{"id":"507f1f77bcf86cd799439019","name":"6-Week Beginner Foundation","description":"Structured program for building fitness fundamentals","difficulty":"beginner","thumbnailUrl":"https://hhcontent.s3.eu-central-1.amazonaws.com/plans/507f1f77bcf86cd799439019/thumbnail.jpg","recommendation":"Ideal starting point for building a consistent training habit","goals":[{"id":"63c92926f920a9005c4e619e","name":"Improve Endurance"}]}],"reasoning":"Plans recommended based on your profile and preferences. Top matches align with your fitness goals, current fitness level, and training frequency. The recommendations prioritize programs that match your objectives while considering your training schedule and capabilities."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanRecommendationResponseDto"}}}},"400":{"description":"Bad Request - Invalid input data"},"401":{"description":"Unauthorized - Invalid API key"},"404":{"description":"Organization/Team not found"}},"tags":["ai-recommendation"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/plans/recommend' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getPlanRecommendations() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/plans/recommend', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/plans/recommend\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/plans/generate":{"post":{"operationId":"OrganizationPlanGeneration_generatePlan","summary":"Generate personalized training programs based on user profile details, duration preferences, and workout collection sources.","description":"\n## Generate a training plan\n\nCreates an AI multi-week program (typically 4–52 weeks, 1–7 workouts/week) from profile, goals, duration options, and workout collection sources. Prefer `POST .../plans/recommend` for a fast library match, or `GET /v1/orgs/{orgId}/plans` to browse.\n\n**Persistence:** Top-level plan `id` is returned **only** when `endUserProfileDetails.endUserId` is set (active org member). Then **store** that `id` and retrieve with `GET /v1/plans/{id}` / `.../workouts`. Without `endUserId`, the response is program JSON **without** a top-level `id` (cannot call `GET /v1/plans/{id}`). Generated plans are **not** listed by `GET /v1/orgs/{orgId}/plans`.\n\n**Try it:** `GET /v1/plans/metadata` for goal/difficulty ids, optionally `GET /v1/workouts/equipment/metadata`, then POST. For a persisted `id`, include `endUserProfileDetails.endUserId` (see `persisted-with-endUserId` example). Duration: both min/max → AI picks in range; one value → target; omit → defaults to 8 weeks.\n\n**Sources:** body field `workoutCollectionSources` — `template` (platform collections), `team` (your collections). Omit → both. Do **not** send `workoutSources` (that name is only for plan **adapt**).\n\n**Optional body:** `userRequirements` (max 2000 chars), `locale` (BCP-47).\n\n**Localization:** optional `locale`. Unsupported → `400`. Omitted → English legacy fields; translation maps = `{ \"en-US\": \"...\" }`. Non-English → AI fills `nameTranslations` / `descriptionTranslations`; nested workouts get `nameLocalized` / `descriptionLocalized`; `difficultyLabel` localized. When a plan `id` is returned, maps are **persisted** — `GET /v1/plans/{id}?locale=...` resolves `name` / `description`. On this generate response, top-level `name` / `description` stay English base. Nested legacy workout fields stay English. `userRequirements` language does not drive output locale.\n\n**Rate limit:** counts as **10x**.\n\n**Related:** `POST /v1/orgs/{orgId}/plans/recommend`, `GET /v1/orgs/{orgId}/plans`, `GET /v1/plans/metadata`, `GET /v1/plans/{id}`, `GET /v1/workouts/equipment/metadata`.\n        ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"67e2e9d0e23f010013e19dec","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Plan generation request with user profile and preferences.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanGenerationRequestDto"},"examples":{"beginner-weight-loss-4weeks":{"summary":"Beginner Weight Loss - 4 Weeks","description":"Beginner program focused on weight loss with 3 workouts per week","value":{"endUserProfileDetails":{"age":28,"gender":"female","fitnessLevels":["beginner"],"goalIds":["63c92926f920a9005c4e619c"],"trainingDaysPerWeek":3},"workoutCollectionSources":["template"],"durationOptions":{"minWeeks":4,"maxWeeks":4},"workoutsPerWeek":3,"difficulty":"beginner"}},"advanced-strength-8weeks":{"summary":"Advanced Strength Building - 8 Weeks","description":"Advanced strength program with 5 workouts per week and equipment preferences","value":{"endUserProfileDetails":{"age":35,"gender":"male","fitnessLevels":["advanced"],"goalIds":["63c92926f920a9005c4e619d","63c92926f920a9005c4e61a0"],"trainingDaysPerWeek":5,"preferredEquipmentCategoryIds":["67deb3696a5e49797c122f55","67deb36a6a5e49797c122f56"]},"workoutCollectionSources":["template","team"],"durationOptions":{"minWeeks":6,"maxWeeks":8},"workoutsPerWeek":5,"difficulty":"advanced","userRequirements":"Progressive overload with 3-week cycles. Include deload weeks every 4th week. Focus on compound movements and strength progression."}},"intermediate-endurance-flexible":{"summary":"Intermediate Endurance - Flexible Duration","description":"Endurance-focused program with AI-selected optimal duration","value":{"endUserProfileDetails":{"age":42,"gender":"female","fitnessLevels":["intermediate"],"goalIds":["63c92926f920a9005c4e619e"],"trainingDaysPerWeek":4},"workoutCollectionSources":["template"],"durationOptions":{"minWeeks":8,"maxWeeks":12},"workoutsPerWeek":4,"difficulty":"intermediate"}},"custom-team-plan":{"summary":"Custom Team Workout Plan","description":"Use organization's workout collections for brand consistency","value":{"endUserProfileDetails":{"age":30,"fitnessLevels":["intermediate"],"trainingDaysPerWeek":4},"workoutCollectionSources":["team"],"durationOptions":{"minWeeks":8,"maxWeeks":12},"workoutsPerWeek":4}},"ephemeral-no-endUserId":{"summary":"Ephemeral plan (no endUserId)","description":"Omits endUserProfileDetails.endUserId — response has no top-level plan id (preview / one-shot).","value":{"endUserProfileDetails":{"age":30,"fitnessLevels":["beginner"],"gender":"female","trainingDaysPerWeek":3},"workoutCollectionSources":["template"],"durationOptions":{"minWeeks":4,"maxWeeks":4},"goalIds":["63c92926f920a9005c4e619c"]}},"persisted-with-endUserId":{"summary":"Persisted plan (with endUserId)","description":"Includes endUserProfileDetails.endUserId so the response returns a top-level plan id to store.","value":{"endUserProfileDetails":{"age":30,"fitnessLevels":["beginner"],"gender":"female","trainingDaysPerWeek":3,"endUserId":"64e3bca9d1b7e600141a9712"},"workoutCollectionSources":["template"],"durationOptions":{"minWeeks":4,"maxWeeks":4},"goalIds":["63c92926f920a9005c4e619c"]}},"complete-all-parameters":{"summary":"Complete Example - All Parameters","description":"Real-world example with ALL available parameters filled out","value":{"endUserProfileDetails":{"age":32,"gender":"male","fitnessLevels":["intermediate"],"goalIds":["63c92926f920a9005c4e619c"],"trainingDaysPerWeek":4,"preferredEquipmentCategoryIds":["67deb36a6a5e49797c122f56","67deb3696a5e49797c122f55"],"endUserId":"64e3bca9d1b7e600141a9712"},"goalIds":["63c92926f920a9005c4e619d"],"difficulty":"intermediate","workoutsPerWeek":4,"workoutCollectionSources":["template","team"],"durationOptions":{"minWeeks":6,"maxWeeks":10},"userRequirements":"Progressive overload with 3-week cycles. Include deload weeks every 4th week. Focus on unilateral movements for balance. Critical: select and use only workouts that are named and contain the word \"minimal\".","locale":"fr-FR"}},"localized-fr-FR":{"summary":"Localized Program (French)","description":"Minimal request with locale — returns French AI name/description and localized nested workout fields.","value":{"goalIds":["63c92926f920a9005c4e619c"],"durationOptions":{"minWeeks":4,"maxWeeks":4},"workoutsPerWeek":2,"workoutCollectionSources":["template"],"difficulty":"intermediate","locale":"fr-FR"}}}}}},"responses":{"200":{"description":"Successfully generated training program with progressive workout structure.","schema":{"example":{"id":"507f1f77bcf86cd799439017","name":"4-Week Intermediate General Fitness","nameTranslations":{"en-US":"4-Week Intermediate General Fitness","fr-FR":"Forme Générale Intermédiaire 4 Semaines"},"description":"Improve your endurance, mobility, and core strength through a balanced 4-week progression.","descriptionTranslations":{"en-US":"Improve your endurance, mobility, and core strength through a balanced 4-week progression.","fr-FR":"Améliorez votre endurance, votre mobilité et votre gainage grâce à une progression équilibrée sur 4 semaines."},"difficulty":"intermediate","difficultyLabel":"Intermédiaire","goalIds":["63c92926f920a9005c4e619c"],"durationInWeeks":4,"workoutsPerWeek":2,"workouts":[{"id":"641da9c2c4c9c000132f2038","name":"Endurance 15 min beginner","nameLocalized":"Endurance 15 min débutant","duration":900000,"difficulty":"beginner"},{"id":"641daa9bc4c9c000132f2b1d","name":"Endurance 30 min intermediate","nameLocalized":"Endurance 30 min intermédiaire","duration":1800000,"difficulty":"intermediate"}]}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanGenerationResponseDto"}}}},"400":{"description":"Bad Request - Invalid input parameters (e.g. unsupported locale returns `Unsupported locale: xx-XX`)."},"401":{"description":"Unauthorized - Invalid API key."},"403":{"description":"Forbidden - API key required or insufficient permissions."},"404":{"description":"Not Found - Organization or other resources not found."},"500":{"description":"Internal Server Error - Failed to generate program."}},"tags":["ai-generation"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/plans/generate' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function generatePlan() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/plans/generate', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/plans/generate\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/plans/{planId}/adapt":{"post":{"operationId":"OrganizationPlanAdaptation_adaptPlan","summary":"Adapt an existing program based on user profile and data","description":"\n## Adapt a training plan\n\nPersonalizes an existing organization plan (add/remove/replace/reorder future workouts) from profile signals, session/feedback history, optional wearable context, and `userGuidance`. Completed workouts are not modified. The source `{planId}` must belong to `{organizationId}` (otherwise `404`).\n\n**Required:** `endUserProfileId` (org member hex id). Content API persists the adapted program under that user — omitting it returns `400` (`Provide endUserProfileId`).\n\n**Persistence:** Unlike workout adapt, the response includes a persisted adapted program `id` — **store it** and retrieve with `GET /v1/plans/{id}` / `.../workouts`. Team-owned sources may be copied (`wasDuplicated`, `originalProgramId`). If that user has this plan **active**, only the **next workout slot** is adapted; otherwise the full future schedule is adapted.\n\n**Sources:** body field `workoutSources` (`template` | `team`) — not `workoutCollectionSources` (that name is only for plan **generate**).\n\n**Rate limit:** counts as **10x**.\n\n**Related:** `POST /v1/orgs/{orgId}/plans/generate`, `POST /v1/orgs/{orgId}/plans/recommend`, `GET /v1/plans/{id}`, `GET /v1/orgs/{orgId}/plans`.\n        ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"Organization/Team ID","example":"67e2e9d0e23f010013e19dec","schema":{"type":"string"}},{"name":"planId","required":true,"in":"path","description":"Plan ID to adapt","example":"67e2e9d0e23f010013e19def","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Program adaptation request with user profile and preferences","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanAdaptationRequestDto"},"examples":{"basic-adaptation":{"summary":"Basic Adaptation - Intermediate User","description":"Adapt a program for an intermediate fitness level user (endUserProfileId required)","value":{"endUserProfileId":"64e3bca9d1b7e600141a9712","endUserProfileDetails":{"age":32,"gender":"female","fitnessLevels":["intermediate"],"trainingDaysPerWeek":4},"workoutSources":["template","team"]}},"injury-adaptation":{"summary":"Adaptation with Injury Guidance","description":"Adapt a program considering user injury","value":{"endUserProfileId":"64e3bca9d1b7e600141a9712","endUserProfileDetails":{"age":45,"gender":"male","fitnessLevels":["beginner"],"trainingDaysPerWeek":3},"workoutSources":["template"],"userGuidance":"I have a knee injury. Please remove high-impact workouts and focus on low-impact alternatives."}},"full-personalization":{"summary":"Full Personalization with User Data","description":"Adapt using 60-day wearable data and full user profile","value":{"endUserProfileId":"64e3bca9d1b7e600141a9712","endUserProfileDetails":{"age":28,"gender":"female","fitnessLevels":["advanced"],"goalIds":["63c92926f920a9005c4e619c"],"trainingDaysPerWeek":5,"preferredEquipmentCategoryIds":["67deb36a6a5e49797c122f56"]},"workoutSources":["template","team"],"userGuidance":"My sleep has been poor lately. Please reduce intensity and add more recovery-focused workouts."}},"shorten-program":{"summary":"Shorten Program","description":"User wants a shorter version of their program","value":{"endUserProfileId":"64e3bca9d1b7e600141a9712","endUserProfileDetails":{"age":35,"gender":"male","fitnessLevels":["intermediate"],"trainingDaysPerWeek":3},"workoutSources":["team"],"userGuidance":"I only have time for 3 workouts per week now instead of 5. Please remove workouts to fit my schedule."}}}}}},"responses":{"200":{"description":"Adapted program with personalized workout modifications","schema":{"example":{"id":"507f1f77bcf86cd799439020","name":"Adapted: 8-Week Strength Building Program","description":"Personalized strength program adapted for your fitness level and schedule","difficulty":"intermediate","durationInWeeks":8,"workoutsPerWeek":3,"totalWorkouts":24,"wasDuplicated":true,"originalProgramId":"507f1f77bcf86cd799439017","adaptationReasoning":"Program adapted to match your intermediate fitness level and 3-day training schedule. Removed 2 high-intensity workouts per week to accommodate recovery needs based on your sleep data. Replaced 3 advanced workouts with intermediate alternatives. Added 2 recovery-focused sessions to support your training progression.","workouts":[{"id":"64f1a2b3c4d5e6f7a8b9c0d1","name":"Upper Body Strength","duration":2700,"difficulty":"intermediate","description":"Focus on chest, back, and arms","position":0,"action":"kept"},{"id":"64f1a2b3c4d5e6f7a8b9c0d2","name":"Lower Body Power","duration":2400,"difficulty":"intermediate","description":"Legs, glutes, and core emphasis","position":1,"action":"kept"},{"id":"64f1a2b3c4d5e6f7a8b9c0d3","name":"Full Body Conditioning - Adapted","duration":3000,"difficulty":"intermediate","description":"Complete body workout with reduced intensity","position":2,"action":"replaced"},{"id":"64f1a2b3c4d5e6f7a8b9c0d4","name":"Recovery & Mobility","duration":1800,"difficulty":"beginner","description":"Gentle recovery session for active rest","position":3,"action":"added"}]}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanAdaptationResponseDto"}}}},"400":{"description":"Invalid request or program not found"},"401":{"description":"Unauthorized - Invalid API key"},"403":{"description":"Forbidden - Cannot adapt programs from other organizations"},"404":{"description":"Program or organization not found"}},"tags":["ai-adaptation"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/plans/<PLAN_ID>/adapt' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function adaptPlan() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/plans/<PLAN_ID>/adapt', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/plans/<PLAN_ID>/adapt\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/metadata":{"get":{"operationId":"OrganizationMetadataApi_getOrganizationMetadata","summary":"Get organization metadata","description":"\n## Organization metadata\n\nPublic org branding and config: `name`, `handle`, `description`, `website`, `logoUrl` / `watermarkUrl` (320×320 CDN PNGs), brand colors, `clientsJoinSetting` (`OPEN` | `INVITE_ONLY` | `SUBSCRIPTION_REQUIRED`).\n\n**Module / AI flags:** `aiGenerationEnabled`, `aiAdaptationEnabled`, `aiRecommendationEnabled`, `aiChatEnabled`, `insightsEnabled` (and module toggles like `hasAssenseiModuleActive`) are **member-app visibility** — they do **not** alone gate Content API recommend/generate/adapt/chat/insights (those use separate API capability checks).\n\n**Try it:** `GET /v1/orgs/{organizationId}` with `X-Api-Key`.\n\n**Related:** `GET /v1/orgs/{orgId}/join-options`, `GET /v1/orgs/{orgId}/workouts`, `GET /v1/orgs/{orgId}/plans`.\n        ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved organization metadata with complete branding information.","schema":{"example":{"id":"63415bf67a9c7000126616c1","name":"DEMO - Brave Fitness Team","handle":"bravefitnessdemo","logoUrl":"https://hhcontent.s3.eu-central-1.amazonaws.com/t/63415bf67a9c7000126616c1/logo/i/logo-320x320.png","watermarkUrl":"https://hhcontent.s3.eu-central-1.amazonaws.com/t/63415bf67a9c7000126616c1/watermark/i/watermark-320x320.png","description":"This is a demo account for showcasing Hyperhuman's AI-powered video production platform made for the health & fitness industry.","website":"https://bogdanpred.wixsite.com/bravefitnessdemo","brandMainColor":"#eeeb3c","brandSecondaryColor":"#F3F8F8","brandTextColor":"#ffffff","clientsJoinSetting":"OPEN","hasAssenseiModuleActive":false,"hasWearableModuleActive":true,"hasWhiteLabelAppActive":false}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationMetadataResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The specified organization ID does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["organization"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/metadata' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getOrganizationMetadata() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/metadata', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/metadata\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/branding/news":{"get":{"operationId":"OrganizationBrandingNewsApi_getOrganizationBrandingNews","summary":"Get organization branding news feed","description":"Returns configured team news items for the branding/news section. If no sources are configured, returns an empty list.","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"forceRefresh","required":false,"in":"query","description":"Force refresh and bypass cache.","example":false,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"Successfully retrieved organization branding news feed.","schema":{"example":{"items":[{"id":"rss-1829321","title":"How to Build Consistency in Training","description":"Practical strategies to maintain progress week over week.","url":"https://example.com/training-consistency","imageUrl":"https://cdn.example.com/images/training-consistency.jpg","source":"Example","channelTitle":"Example Fitness Journal","categories":["Training","Mindset"],"publishedAt":"2026-05-11T17:30:00.000Z"}]}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationBrandingNewsResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The specified organization ID does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["organization"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/branding/news' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getOrganizationBrandingNews() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/branding/news', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/branding/news\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/join-options":{"get":{"operationId":"OrganizationJoinOptionsApi_getOrganizationJoinOptions","summary":"Get organization join options","description":"\n## User Onboarding Configuration\n\nRetrieves information about how users can join your organization, including join settings, subscription requirements, and available plans.\n\n---\n\n### 📋 What's Included\n\n**Join Settings:**\n- `clientsJoinSetting`: OPEN, INVITE_ONLY, or SUBSCRIPTION_REQUIRED\n- `canJoinDirectly`: Boolean flag for self-signup\n- `inviteOnlyMode`: Requires invitation to join\n- `requiresSubscription`: Payment required to access\n\n**Free Plans:**\n- `hasFreePlanWithAutoJoin`: Free access available\n- `freeJoinOptions`: List of free plans with auto-enrollment\n- `totalProductsAvailable`: Count of subscription products\n\n---\n\n### 🎯 Join Settings Explained\n\n| Setting | Description | User Flow |\n|---------|-------------|-----------|\n| **OPEN** | Anyone can join | Self-signup enabled |\n| **INVITE_ONLY** | Requires invitation | Admin must invite |\n| **SUBSCRIPTION_REQUIRED** | Payment required to join | User subscribes for access |\n\n---\n\n### 💡 Integration Patterns\n\n**Self-Signup Flow (OPEN):**\n```\n1. GET /v1/orgs/{orgId}/join-options → Check if open\n2. POST /v1/orgs/{orgId}/endusers/invite → Create user\n3. User receives email/access\n```\n\n**Invitation Flow (INVITE_ONLY):**\n```\n1. Admin invites via dashboard or API\n2. User receives invitation\n3. User accepts and creates account\n```\n\n**Subscription Required:**\n```\n1. GET /v1/orgs/{orgId}/join-options → Check products\n2. Display subscription options to user\n3. User subscribes → Access granted\n```\n\n---\n\n### 🔗 Related Endpoints\n\n- Organization Metadata: `GET /v1/orgs/{orgId}/metadata`\n- Invite Users: `POST /v1/orgs/{orgId}/endusers/invite`\n        ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved organization join options and configuration.","schema":{"example":{"clientsJoinSetting":"OPEN","canJoinDirectly":true,"requiresSubscription":false,"inviteOnlyMode":false,"hasFreePlanWithAutoJoin":false,"freeJoinOptions":[],"totalProductsAvailable":0}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationJoinOptionsResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The specified organization ID does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["organization"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/join-options' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getOrganizationJoinOptions() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/join-options', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/join-options\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/endusers/{endUserId}/plans/active/progress":{"get":{"operationId":"OrganizationEndUserPlansApi_getActivePlanProgress","summary":"Get plan progress for an end user","description":"\n## Plan progress\n\nReturns per-workout progress for the end user's active plan. Keys are position indices (as strings); values include completed, latestCompletionDate, workoutName, difficulty, duration, categories, workoutId, positionInPlan.\n\nOnly workout sessions completed on or after the active plan's `startDate` are credited toward `completed` and `latestCompletionDate`. Sessions visible elsewhere in the app may predate that window.\n\nWhen the end user has no active plan, the endpoint responds with `200 OK` and `{ \"data\": null }` (rather than 404), so callers can render a \"no active plan\" state without treating it as an error.\n\n---\n\n### Related endpoints\n\n- `GET .../plans/active` - Get active plan details\n- `POST .../plans/start` - Start a plan\n- `POST .../plans/{planId}/end` - End active plan\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The organization id (24-character hex string).","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"endUserId","required":true,"in":"path","description":"The user identifier. Can be email, externalUUID, or internal user ID.","example":"john.doe@acme.com","schema":{"type":"string"}}],"responses":{"200":{"description":"Plan progress for the end user, or `data: null` when there is no active plan.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanProgressResponseDto"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The end user could not be resolved (not found or not a member of this organization).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-plans"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/plans/active/progress' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getActivePlanProgress() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/plans/active/progress', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/plans/active/progress\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/endusers/{endUserId}/plans/active":{"get":{"operationId":"OrganizationEndUserPlansApi_getActivePlan","summary":"Get active plan for an end user","description":"\n## Active plan\n\nReturns the end user's active workout plan if any, with schedule (workoutsPerWeek, durationInWeeks, currentWeekNumber, daysSinceStart, completedWorkouts, totalWorkouts, completionPercentage).\n\n---\n\n### Related endpoints\n\n- `GET .../plans/active/progress` - Get per-workout progress\n- `POST .../plans/start` - Start a plan\n- `POST .../plans/{planId}/end` - End active plan\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The organization id (24-character hex string).","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"endUserId","required":true,"in":"path","description":"The user identifier. Can be email, externalUUID, or internal user ID.","example":"john.doe@acme.com","schema":{"type":"string"}}],"responses":{"200":{"description":"Active plan or null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivePlanResponseDto"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The end user could not be resolved (not found or not a member of this organization).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-plans"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/plans/active' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getActivePlan() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/plans/active', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/plans/active\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/endusers/{endUserId}/plans/start":{"post":{"operationId":"OrganizationEndUserPlansApi_startPlan","summary":"Start a plan for an end user","description":"\n## Start plan\n\nStarts the given plan as the end user's active plan. Any existing active plan is deactivated.\n\nCall this once when the user begins a program (for example at enrollment). If the same plan is already active and `restart` is not `true`, the existing access record is returned without changing `startDate` — safe for idempotent \"ensure enrolled\" calls.\n\nPlan progress (`GET .../plans/active/progress`) only credits workout sessions completed on or after the plan's `startDate`. Set `restart: true` to reset that progress window intentionally (for example when the user starts the program over).\n\nOptional `autoAdapt: true` enables automatic next-workout adaptation for this active enrollment. Toggle later via `PATCH .../plans/active/settings`.\n\n---\n\n### Related endpoints\n\n- `GET .../plans/active` - Get active plan details\n- `GET .../plans/active/progress` - Get plan progress\n- `PATCH .../plans/active/settings` - Update active plan settings (`autoAdapt`)\n- `POST .../plans/{planId}/end` - End active plan\n- `GET /v1/plans/{id}` - Plan catalog details\n- `GET /v1/plans/{id}/workouts` - Workouts in plan\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The organization id (24-character hex string).","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"endUserId","required":true,"in":"path","description":"The user identifier. Can be email, externalUUID, or internal user ID.","example":"john.doe@acme.com","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Plan ID to start as the active plan.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartPlanBody"}}}},"responses":{"201":{"description":"Plan access record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanResponseDto"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The end user could not be resolved (not found or not a member of this organization).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-plans"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/plans/start' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function startPlan() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/plans/start', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/plans/start\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/endusers/{endUserId}/plans/active/settings":{"patch":{"operationId":"OrganizationEndUserPlansApi_updateActivePlanSettings","summary":"Update active plan settings for an end user","description":"## Active plan settings\n\nUpdates per-enrollment settings on the user's active plan access record.\n\n| Field | Description |\n|-------|-------------|\n| `autoAdapt` | When `true`, the next scheduled workout may be adapted automatically after sessions, feedback, digest refresh, or profile changes. When `false`, disables auto-adapt until re-enabled. |\n\nReturns the updated plan access record (same shape as `GET .../plans/active`).","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The organization id (24-character hex string).","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"endUserId","required":true,"in":"path","description":"The user identifier. Can be email, externalUUID, or internal user ID.","example":"john.doe@acme.com","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Active plan settings to update.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateActivePlanSettingsBody"}}}},"responses":{"200":{"description":"Updated plan access record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanResponseDto"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-plans"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X PATCH 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/plans/active/settings' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function updateActivePlanSettings() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/plans/active/settings', {\n  method: 'PATCH',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.patch(\n    \"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/plans/active/settings\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/endusers/{endUserId}/plans/{planId}/end":{"post":{"operationId":"OrganizationEndUserPlansApi_endPlan","summary":"End an active plan for an end user","description":"\n## End plan\n\nEnds the specified plan for the end user. The plan must be the user's current active plan. Returns 404 if no active plan matches the given planId.\n\n---\n\n### Related endpoints\n\n- `GET .../plans/active` - Get active plan details\n- `GET .../plans/active/progress` - Get plan progress\n- `POST .../plans/start` - Start a plan\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The organization id (24-character hex string).","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"endUserId","required":true,"in":"path","description":"The user identifier. Can be email, externalUUID, or internal user ID.","example":"john.doe@acme.com","schema":{"type":"string"}},{"name":"planId","required":true,"in":"path","description":"The plan ID to end.","example":"60f1b3b3b3b3b3b3b3b3b3b3","schema":{"type":"string"}}],"responses":{"200":{"description":"Updated plan access record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanResponseDto"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-plans"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/plans/<PLAN_ID>/end' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function endPlan() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/plans/<PLAN_ID>/end', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/plans/<PLAN_ID>/end\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/endusers":{"get":{"operationId":"OrganizationEndUsersApi_getOrganizationEndUsers","summary":"Get organization end users","description":"Retrieves a paginated list of end users associated with the organization.\n\n`endUserId` is present only when the API key is for this organization and the end user has an active (non-suspended) team membership.\n\n### Pagination\nUse the standard `offset`/`limit` cursors. The response contains the canonical `links` envelope:\n- `links.next` — fully qualified URL for the next page (omitted on the last page)\n- `links.total` — total number of matching end users\n\nThe top-level `total` field is **deprecated** and kept only for backwards compatibility; new integrations should read `links.total` instead.","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier (24-character hex string) of the organization.","example":"12ab3efd45c67c1234566cd1","schema":{"type":"string"}},{"name":"offset","required":false,"in":"query","description":"Offset for pagination. Defaults to 0.","schema":{"default":0,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page. Defaults to 20, Max 100.","schema":{"default":20,"type":"number"}},{"name":"status","required":false,"in":"query","description":"Filter clients by status: \"active\", \"suspended\", or \"all\"","schema":{"enum":["active","suspended","all"],"type":"string"}},{"name":"sortBy","required":false,"in":"query","description":"Sort clients by \"name\", \"status\", or \"joined\" (default)","schema":{"enum":["name","status","joined"],"type":"string"}},{"name":"sortDirection","required":false,"in":"query","description":"Sort direction: \"asc\" (default) or \"desc\"","schema":{"enum":["asc","desc"],"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved list of end users for the organization.","schema":{"example":{"data":[{"email":"john.doe@acme.com","externalUUID":"ext-user-12345","firstName":"John","lastName":"Doe","status":"active","joinedDate":"2025-09-15T10:30:00Z","endUserId":"507f1f77bcf86cd799439011"},{"email":"jane.smith@acme.com","externalUUID":"ext-user-67890","firstName":"Jane","lastName":"Smith","status":"suspended","joinedDate":"2025-09-20T14:20:00Z"}],"links":{"next":"https://api.hyperhuman.club/v1/orgs/12ab3efd45c67c1234566cd1/endusers?limit=20&offset=20","total":142},"total":142}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EndUserProfileListResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The API key is not associated with the requested organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The specified organization ID does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-management"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getOrganizationEndUsers() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]},"delete":{"operationId":"OrganizationEndUsersApi_removeEndUser","summary":"Remove end user from organization","description":"\n## Permanently Remove User\n\nCompletely removes a user from your organization. This action is **irreversible** and will:\n\n- Delete all user data and progress\n- Remove access to organization content\n- Clear workout history and sessions\n- Cannot be undone\n\n---\n\n### ⚠️ Important Considerations\n\n**Before Removing:**\n- User will lose all progress and data\n- Consider suspending instead for temporary access removal\n- Backup any important user data first\n- Notify user if required by your policies\n\n**Use Cases:**\n- GDPR compliance (right to be forgotten)\n- Account closure requests\n- Data cleanup and maintenance\n- User requested permanent deletion\n\n---\n\n### 🔄 Alternative Actions\n\n**Temporary Removal:**\n- `PUT /v1/orgs/{orgId}/endusers/suspend` - Temporarily disable access\n- User data preserved, can be reactivated later\n- Better for temporary access issues\n\n**Permanent Removal:**\n- `DELETE /v1/orgs/{orgId}/endusers` - This endpoint\n- Complete data deletion, cannot be undone\n- Use for final account closure\n\n---\n\n### 💡 Best Practices\n\n✅ **Verify user identity** - Double-check email/UUID before deletion  \n✅ **Consider suspension first** - Try suspend before permanent removal  \n✅ **Log deletion events** - Track for audit and compliance  \n✅ **Handle gracefully** - 404 is expected if user already removed  \n❌ **Don't delete active users** - Consider suspending instead\n\n---\n\n### 🔗 Related Endpoints\n\n- Find User: `GET /v1/orgs/{orgId}/endusers/find` - Locate user first\n- Suspend User: `PUT /v1/orgs/{orgId}/endusers/suspend` - Temporary removal\n- Reactivate User: `PUT /v1/orgs/{orgId}/endusers/reactivate` - Restore suspended user\n        ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier (24-character hex string) of the organization.","example":"12ab3efd45c67c1234566cd1","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentifierDto"}}}},"responses":{"200":{"description":"Successfully removed end user from organization.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The API key is not associated with the requested organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"End user not found in the organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-management"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X DELETE 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function removeEndUser() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers', {\n  method: 'DELETE',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.delete(\n    \"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/endusers/invite":{"post":{"operationId":"OrganizationEndUsersApi_inviteEndUsers","summary":"Invite end users to organization","description":"\n## Add Users to Your Organization\n\nSend invitations to one or more end users. Creates **pending** invites; each user accepts in the member experience (or via your branded Redirect URL) to gain access to your organization's content and features.\n\n---\n\n### Identifier Options\n\n**Email Only:**\n- User invited via email address\n- Hyperhuman creates account on first login\n- Email must be valid and unique\n\n**Email + External UUID:**\n- Map to your existing user system\n- Track users across platforms\n- Sync user data between systems\n- **Recommended for integrations**\n\n---\n\n### Invite email (`sendInviteEmail`)\n\nBy default Hyperhuman sends a **transactional invite email** when a new pending invite is created.\n\n| Request `sendInviteEmail` | Organization Invite emails setting | Hyperhuman invite email |\n|-----------------------------|------------------------------------|-------------------------|\n| omitted | on (default) | sent for new invites |\n| omitted | off | not sent |\n| `false` | any | not sent for this batch |\n| `true` | any | sent for this batch (overrides org off) |\n\n- **Pending invites are always created** whether email is sent or not.\n- Response **`inviteEmailSent`** is the effective send **policy** for *new* invites in this request — not a per-user delivery receipt.\n- Updating an existing pending invite **never re-sends** email, even when policy is on.\n- When you send your own invite email, set `sendInviteEmail: false` (or turn off **Invite emails** in the Hyperhuman team app) and point users at your organization **Redirect URL**.\n\n---\n\n### Typical User Lifecycle\n\n1. **Invite**: `POST /v1/orgs/{orgId}/endusers/invite` → Add users\n2. **Verify**: `GET /v1/orgs/{orgId}/endusers/find?email=...` → Check status\n3. **List**: `GET /v1/orgs/{orgId}/endusers` → View all users\n4. **Manage**: Suspend/reactivate as needed\n5. **Remove**: `DELETE /v1/orgs/{orgId}/endusers` → Permanent deletion\n\n---\n\n### Best Practices\n\n- **Batch invitations** — up to 100 users per request\n- **Use externalUUID** — map to your user IDs for sync\n- **Validate emails** — check format before sending\n- **Handle failures** — review the `failed` array\n- **Custom invite email** — `sendInviteEmail: false` when you email clients yourself; use your Redirect URL\n- **Don't re-invite blindly** — check if the user exists first; pending updates do not re-send email\n\n---\n\n### Error Handling\n\nCommon failure reasons:\n- `User already exists` - Email already in organization\n- `Invalid email format` - Email validation failed\n- `Duplicate in batch` - Same email appears twice\n- `Organization quota exceeded` - User limit reached\n\n---\n\n### Related Endpoints\n\n- Find User: `GET /v1/orgs/{orgId}/endusers/find`\n- List Users: `GET /v1/orgs/{orgId}/endusers`\n- Suspend User: `PUT /v1/orgs/{orgId}/endusers/suspend`\n- Remove User: `DELETE /v1/orgs/{orgId}/endusers`\n        ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Users to invite (required), with optional external UUID mapping. Optional sendInviteEmail overrides whether Hyperhuman sends a transactional invite email for this batch.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteEndUsersDto"},"examples":{"single-email-only":{"summary":"Single User - Email Only","description":"Invite one user with just an email address (uses organization Invite emails setting)","value":{"users":[{"email":"john.doe@acme.com"}]}},"batch-with-external-ids":{"summary":"Batch Invite - With External UUIDs","description":"Invite multiple users and map to your system IDs for synchronization","value":{"users":[{"email":"john.doe@acme.com","externalUUID":"user-12345"},{"email":"jane.smith@acme.com","externalUUID":"user-67890"},{"email":"bob.jones@acme.com","externalUUID":"user-11111"}]}},"large-batch":{"summary":"Large Batch - 10+ Users","description":"Efficiently invite many users at once (up to 100 per request)","value":{"users":[{"email":"user1@acme.com","externalUUID":"ext-user-1001"},{"email":"user2@acme.com","externalUUID":"ext-user-1002"},{"email":"user3@acme.com","externalUUID":"ext-user-1003"},{"email":"user4@acme.com","externalUUID":"ext-user-1004"},{"email":"user5@acme.com","externalUUID":"ext-user-1005"},{"email":"user6@acme.com","externalUUID":"ext-user-1006"},{"email":"user7@acme.com","externalUUID":"ext-user-1007"},{"email":"user8@acme.com","externalUUID":"ext-user-1008"},{"email":"user9@acme.com","externalUUID":"ext-user-1009"},{"email":"user10@acme.com","externalUUID":"ext-user-1010"}]}},"custom-invite-email":{"summary":"Skip Hyperhuman invite email","description":"Create pending invites without Hyperhuman transactional invite email when you send your own. Response inviteEmailSent is false. Point users at your organization Redirect URL.","value":{"sendInviteEmail":false,"users":[{"email":"john.doe@acme.com","externalUUID":"emp-001"},{"email":"jane.smith@acme.com","externalUUID":"emp-002"}]}},"force-invite-email":{"summary":"Force Hyperhuman invite email","description":"Send Hyperhuman transactional invite email for this batch even if organization Invite emails is off.","value":{"sendInviteEmail":true,"users":[{"email":"john.doe@acme.com","externalUUID":"emp-001"}]}}}}}},"responses":{"201":{"description":"Invitation processing complete. Returns success count, any failures, optionally invited with endUserId when the user already has an active membership, and inviteEmailSent (effective transactional invite-email policy for new invites in this request).","content":{"application/json":{"schema":{"type":"object","properties":{"successful":{"type":"number","description":"Number of successful invitations (pending invite created or updated)","example":12},"failed":{"type":"array","description":"List of failed invitations with error reasons","items":{"type":"object","properties":{"email":{"type":"string","example":"invalid@email"},"reason":{"type":"string","example":"Invalid email format"}}},"example":[{"email":"duplicate@acme.com","reason":"User already exists"},{"email":"bad-email","reason":"Invalid email format"}]},"invited":{"type":"array","description":"Successful invites; endUserId present only when the user already has an active team membership.","items":{"type":"object","properties":{"email":{"type":"string"},"endUserId":{"type":"string","description":"User ID; present only for active members."}}}},"inviteEmailSent":{"type":"boolean","description":"Whether Hyperhuman will send a transactional invite email for *new* invites in this request. Resolved from the optional body field sendInviteEmail (wins when set) and the organization Invite emails setting (on by default). When false, pending invite records are still created; Hyperhuman does not send the invite email. This is batch send policy — not a per-user delivery receipt. Updating an existing pending invite never re-sends email even when this is true.","example":true}},"example":{"successful":12,"failed":[{"email":"duplicate@acme.com","reason":"User already exists"}],"invited":[{"email":"user1@acme.com","endUserId":"507f1f77bcf86cd799439011"},{"email":"user2@acme.com"}],"inviteEmailSent":true}}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The API key is not associated with the requested organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-management"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/invite' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function inviteEndUsers() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/invite', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/invite\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/endusers/suspend":{"put":{"operationId":"OrganizationEndUsersApi_suspendEndUser","summary":"Suspend end user in organization","description":"\n## Temporarily Suspend User Access\n\nSuspends a user's access to your organization content while preserving their data and progress. This is a **reversible action** that:\n\n- Blocks access to workouts and plans\n- Preserves user data and progress\n- Can be reactivated later\n- User cannot log in during suspension\n\n---\n\n### 🎯 When to Suspend\n\n**Temporary Access Issues:**\n- Payment/billing problems\n- Policy violations (temporary)\n- Account security concerns\n- User requested break\n\n**vs. Permanent Removal:**\n- Suspension: Temporary, data preserved\n- Deletion: Permanent, data lost\n- Choose suspension for reversible actions\n\n---\n\n### 🔄 User Experience During Suspension\n\n**What Users See:**\n- Cannot access organization content\n- Login blocked with suspension message\n- All data and progress preserved\n- Can be reactivated by admin\n\n**What Admins Can Do:**\n- View suspended users in user list\n- Reactivate anytime with reactivate endpoint\n- See suspension status in user details\n- Track suspension history\n\n---\n\n### 💡 Best Practices\n\n✅ **Communicate with user** - Explain why and duration  \n✅ **Set clear policies** - Define suspension criteria  \n✅ **Monitor suspension duration** - Don't leave users suspended indefinitely  \n✅ **Use for temporary issues** - Permanent problems may need deletion  \n✅ **Document reasons** - Track why users were suspended\n\n---\n\n### 🔗 Related Endpoints\n\n- Find User: `GET /v1/orgs/{orgId}/endusers/find` - Locate user first\n- Reactivate User: `PUT /v1/orgs/{orgId}/endusers/reactivate` - Restore access\n- Remove User: `DELETE /v1/orgs/{orgId}/endusers` - Permanent deletion\n- List Users: `GET /v1/orgs/{orgId}/endusers` - View all users (including suspended)\n        ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier (24-character hex string) of the organization.","example":"12ab3efd45c67c1234566cd1","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentifierDto"}}}},"responses":{"200":{"description":"Successfully suspended end user in organization.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The API key is not associated with the requested organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"End user not found in the organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-management"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X PUT 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/suspend' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function suspendEndUser() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/suspend', {\n  method: 'PUT',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.put(\n    \"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/suspend\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/endusers/reactivate":{"put":{"operationId":"OrganizationEndUsersApi_reactivateEndUser","summary":"Reactivate end user in organization","description":"\n## Restore Suspended User Access\n\nReactivates a previously suspended user, restoring full access to your organization content. This action:\n\n- Restores login access immediately\n- Preserves all user data and progress\n- Returns user to active status\n- Can be done anytime after suspension\n\n---\n\n### 🎯 When to Reactivate\n\n**Common Scenarios:**\n- Payment issues resolved\n- Policy violations addressed\n- Security concerns cleared\n- User requested restoration\n- Administrative error correction\n\n**Prerequisites:**\n- User must be currently suspended\n- Cannot reactivate already active users\n- Cannot reactivate permanently deleted users\n\n---\n\n### 🔄 User Experience After Reactivation\n\n**Immediate Access:**\n- User can log in immediately\n- Full access to organization content\n- All previous data and progress intact\n- No data loss from suspension period\n\n**Status Changes:**\n- User status changes from \"suspended\" to \"active\"\n- Appears in active user lists\n- Can participate in workouts and plans\n- Normal user functionality restored\n\n---\n\n### 💡 Best Practices\n\n✅ **Verify suspension reason resolved** - Ensure original issue is fixed  \n✅ **Communicate with user** - Notify them of reactivation  \n✅ **Monitor user activity** - Ensure they can access content  \n✅ **Update user records** - Track reactivation for audit  \n✅ **Test user access** - Verify login and content access works\n\n---\n\n### 🔗 Related Endpoints\n\n- Find User: `GET /v1/orgs/{orgId}/endusers/find` - Check current status\n- Suspend User: `PUT /v1/orgs/{orgId}/endusers/suspend` - Suspend if needed again\n- List Users: `GET /v1/orgs/{orgId}/endusers` - View all users\n- Remove User: `DELETE /v1/orgs/{orgId}/endusers` - Permanent deletion (if needed)\n        ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier (24-character hex string) of the organization.","example":"12ab3efd45c67c1234566cd1","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdentifierDto"}}}},"responses":{"200":{"description":"Successfully reactivated end user in organization.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The API key is not associated with the requested organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"End user not found in the organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-management"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X PUT 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/reactivate' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function reactivateEndUser() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/reactivate', {\n  method: 'PUT',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.put(\n    \"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/reactivate\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/endusers/find":{"get":{"operationId":"OrganizationEndUsersApi_getEndUserById","summary":"Find end user by email or external UUID","description":"\n## Find Specific User\n\nRetrieve a single user from your organization by email or external UUID. Useful for checking if a user exists before inviting.\n\n---\n\n### 📋 Identifier Options\n\n**By Email:**\n```bash\nGET /v1/orgs/{orgId}/endusers/find?email=john.doe@acme.com\n```\n\n**By External UUID:**\n```bash\nGET /v1/orgs/{orgId}/endusers/find?externalUUID=ext-user-12345\n```\n\n**Required:** Must provide either `email` OR `externalUUID` (not both)\n\n---\n\n### 🎯 Use Cases\n\n✅ **Pre-invite Check** - Verify user doesn't exist before inviting  \n✅ **User Lookup** - Find user details for support queries  \n✅ **Sync Validation** - Confirm external UUID mapping is correct  \n✅ **Duplicate Prevention** - Check before creating user in your system\n\n---\n\n### 💡 Best Practices\n\n✅ **Email is case-insensitive** - john@acme.com = John@acme.com  \n✅ **Use external UUID for integrations** - More reliable than email  \n✅ **Handle 404 gracefully** - User not found is an expected case  \n✅ **Cache lookups** - Reduce API calls for frequently accessed users\n\n---\n\n### 🔗 Related Endpoints\n\n- Invite Users: `POST /v1/orgs/{orgId}/endusers/invite` - Add new users\n- List Users: `GET /v1/orgs/{orgId}/endusers` - Browse all users\n- Suspend User: `PUT /v1/orgs/{orgId}/endusers/suspend` - Deactivate user\n- Remove User: `DELETE /v1/orgs/{orgId}/endusers` - Permanently delete\n    ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"email","required":false,"in":"query","description":"Email address of the user to find (case-insensitive)","example":"john.doe@acme.com","schema":{"type":"string"}},{"name":"externalUUID","required":false,"in":"query","description":"External UUID of the user to find","example":"ext-user-12345","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved end user profile. endUserId is present only when the end user has an active (non-suspended) team membership.","schema":{"example":{"email":"john.doe@acme.com","externalUUID":"ext-user-12345","firstName":"John","lastName":"Doe","status":"active","joinedDate":"2025-09-15T10:30:00Z","endUserId":"507f1f77bcf86cd799439011"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EndUserProfileDto"}}}},"400":{"description":"Missing required identifier (email or externalUUID).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The API key is not associated with the requested organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"End user not found in the organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-management"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/find' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getEndUserById() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/find', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/find\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/endusers/{endUserId}/insights/digest":{"get":{"operationId":"UserInsightsApi_getUserDailyDigest","summary":"Get daily AI-powered user insights digest","description":"\n## Daily Health & Fitness Digest\n\nReturns a personalized daily digest of insight pillars selected from: `health_pulse`, `training`, `recovery`, `movement`, `nutrition`, `body`. The exact set returned depends on which data sources the user has connected and on the current data completeness — typically 3-5 pillars per day.\n\nEach pillar in the digest is intentionally **summary-only**. Coaching signals such as readiness band, recommended intensity, risk triggers, form cue, why-explanations, and alternative actions are surfaced inside the `headline` and `action` strings, but **are not exposed as separate fields on `InsightPillarDto`**. To get the full coaching context for a single pillar, drill into `GET /v1/orgs/{organizationId}/endusers/{endUserId}/insights/pillars/{pillarType}`.\n\n---\n\n### Pillars Overview\n\n| Pillar | Description | Primary Data Source |\n|--------|-------------|---------------------|\n| **Health Pulse** | Overall health status and main driver | Rook wearables / workout adherence |\n| **Training** | Workout progress and next session | Workout sessions, AI assessments |\n| **Recovery** | Sleep and recovery readiness | Rook sleep score / workout intensity |\n| **Movement** | Daily activity and cardio | Rook activity / workout frequency |\n| **Nutrition** | Nutrition quality (when available) | Manual logs, chat logging, photo logs (`POST .../nutrition/photo-log`) |\n| **Body** | Body metrics and momentum | Rook body score / workout streak |\n\n---\n\n### Status Indicators\n\n- **Green** (75-100): On track\n- **Yellow** (55-74): Watch it\n- **Red** (0-54): Priority action needed\n\n---\n\n### Data Completeness\n\nThe `dataCompleteness` field (0-1) indicates how much user data is available:\n- **0.8+**: Full wearable + workout data\n- **0.5-0.8**: Partial data (some wearables or workout history)\n- **<0.5**: Limited data (fallback insights provided)\n\n---\n\n### Fallback Behavior\n\nWhen data is missing:\n- Health Pulse calculates a \"Hyperhuman Pulse\" from workout adherence\n- Recovery uses workout intensity to estimate readiness\n- Nutrition shows a CTA to start tracking\n\n---\n\n### Enhanced Coaching Signals\n\nThe digest includes intelligent coaching signals embedded in pillar headlines:\n\n| Signal | Description | Pillars |\n|--------|-------------|---------|\n| **Readiness** | Push/Maintain/Recover recommendation based on recovery data | Health Pulse, Recovery |\n| **Risk Detection** | Fatigue warning when multiple triggers present | Training |\n| **Form Focus** | Primary technique cue from AI assessments | Training |\n| **Program Pacing** | On track/behind status for weekly goals | Training |\n\nThese signals adjust the `action` field to provide intensity-appropriate recommendations based on current readiness state.\n\n---\n\n### Use Cases\n\n- Daily digest screen in mobile app\n- Coach dashboard for client overview\n- Notification content generation\n- Personalized workout recommendations\n\n---\n\n### Rate Limit\n\nThis endpoint counts as 10x API calls toward your hourly and daily limits.\n\n---\n\n### Related Endpoints\n\n- Workout Sessions: `GET /v1/me/workouts/sessions`\n- Workout Feedback: `POST /v1/workouts/{id}/feedback`\n- AI Assessments: `GET /v1/me/workouts/measured-metrics`\n        ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier (24-character hex string) of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"endUserId","required":true,"in":"path","description":"User identifier: email, externalUUID, or internal user ID.","example":"john.doe@acme.com","schema":{"type":"string"}},{"name":"date","required":false,"in":"query","description":"Date for the digest as an ISO 8601 date-time string (e.g. 2026-01-10T00:00:00.000Z). Past dates within last 7 days and today supported; future or older dates return 400. Defaults to today.","example":"2026-01-10T00:00:00.000Z","schema":{"type":"string"}},{"name":"forceRefresh","required":false,"in":"query","description":"Force refresh, bypassing cache.","example":false,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"Successfully retrieved daily digest.","schema":{"example":{"userId":"63415bf67a9c7000126616c1","organizationId":"63415bf67a9c7000126616c1","date":"2026-01-10T00:00:00.000Z","pillars":[{"type":"health_pulse","status":"green","headline":"82 (+5 vs 7-day). Readiness: Push window today.","action":"Maintain your sleep routine","confidence":0.85,"score":82,"delta":5,"deltaDirection":"up","driver":"sleep"},{"type":"training","status":"green","headline":"4 workouts this week. Form: 78% (improving). On pace.","action":"Next: Full Body Strength at high intensity","confidence":0.8,"weeklyCompletions":4,"streak":5,"formScore":78,"formTrend":"improving"},{"type":"movement","status":"yellow","headline":"Activity below target the last 2 days.","action":"Add a 20-min walk this afternoon","confidence":0.7},{"type":"nutrition","status":"yellow","headline":"No meals logged today.","action":"Log your next meal to keep your streak","confidence":0.5,"isFallback":true}],"todaysFocus":"Complete: Full Body Strength at high intensity","dataCompleteness":0.75,"generatedAt":"2026-01-10T08:30:00.000Z"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDigestResponse"}}}},"400":{"description":"Invalid date (e.g., future date, more than 7 days in past, or invalid format).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"User or organization not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-ai-insights"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/insights/digest' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getUserDailyDigest() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/insights/digest', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/insights/digest\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/endusers/{endUserId}/insights/pillars/{pillarType}":{"get":{"operationId":"UserInsightsApi_getPillarDetail","summary":"Get detailed view of a specific insight pillar","description":"\n## Pillar Detail\n\nReturns expanded information for a specific insight pillar, including all available metrics and recommendations.\n\n---\n\n### Available Pillar Types\n\n| Type | Details Included |\n|------|------------------|\n| `health_pulse` | Score, delta, driver, readiness band, recommended intensity |\n| `training` | Last workout, next session, form score, form cue, pacing status, risk level, why explanations, alternative actions |\n| `recovery` | Sleep score, main issue, intensity, readiness band, HRV band, why explanations |\n| `movement` | Activity level, suggested minutes, cardio trend |\n| `nutrition` | Nutrition score (when available), wins/watches |\n| `body` | Body score, weekly trend, streak, biggest lever |\n\n---\n\n### Enhanced Coaching Details\n\nWhen drilling into pillar details, you get actionable coaching context:\n\n**Readiness (Health Pulse and Recovery pillars):**\n- `readinessBand`: Training capacity recommendation (`push` | `maintain` | `recover`)\n- `readinessMessage`: Explanation of the recommendation\n- `recommendedIntensity`: Target workout intensity (`light` | `moderate` | `high`)\n- `hrvBand`: HRV relative to personal baseline (`low` | `normal` | `high`)\n\n**Risk Detection (Training pillar):**\n- `riskLevel`: Fatigue risk severity (`low` | `moderate` | `high`)\n- `riskTriggers`: Array of up to 3 contributing factors\n- `alternativeActions`: Safe workout alternatives when risk detected\n\n**Form Coaching (Training pillar):**\n- `formCue`: Primary technique focus for today\n- `formSuggestion`: Adjustment if form is declining\n- `repAccuracy`: Rep accuracy percentage from AI assessment\n\n**Program Pacing (Training pillar):**\n- `pacingStatus`: Weekly pacing status (`on_track` | `behind` | `ahead`)\n- `pacingMessage`: Weekly progress summary\n- `workoutsPlannedThisWeek` / `workoutsCompletedThisWeek`\n\n**Explanations:**\n- `why`: Array of up to 3 reasons explaining the recommendation\n\n---\n\n### Use Cases\n\n- Drill-down from digest view\n- Detailed pillar cards in UI\n- Coach insights for specific areas\n\n---\n\n### Rate Limit\n\nThis endpoint counts as 10x API calls toward your hourly and daily limits.\n        ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier (24-character hex string) of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"endUserId","required":true,"in":"path","description":"User identifier: email, externalUUID, or internal user ID.","example":"john.doe@acme.com","schema":{"type":"string"}},{"name":"pillarType","required":true,"in":"path","description":"Type of pillar to get details for.","example":"training","schema":{"type":"string","enum":["health_pulse","training","recovery","movement","nutrition","body"]}}],"responses":{"200":{"description":"Successfully retrieved pillar details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PillarDetailResponse"}}}},"400":{"description":"Invalid pillar type.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"User, organization, or pillar not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-ai-insights"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/insights/pillars/<PILLARTYPE>' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getPillarDetail() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/insights/pillars/<PILLARTYPE>', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/insights/pillars/<PILLARTYPE>\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/endusers/{endUserId}/nutrition/photo-log":{"post":{"operationId":"OrganizationEndUserNutritionApi_analyzeNutritionPhoto","summary":"Analyze a meal photo for nutrition logging","description":"\n## Photo Food Logging - Analyze\n\nUploads a meal photo and runs vision AI analysis. Returns a pending estimate (per-item food breakdown + macro totals) with a `pendingLogId`.\n\nNothing is logged at this step. Show the estimate to the user, then call the **Confirm** endpoint. The pending estimate expires after **1 hour** and is single-use. The photo is processed in memory and **never stored**.\n\nConfirmed entries feed the same nutrition data as `POST /v1/me/nutrition/log` and chat logging: day totals, nutrition score, daily digest, and the nutrition insight pillar.\n\n**Rate limit:** Counts as 10x API calls toward your hourly and daily limits.","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"endUserId","required":true,"in":"path","description":"The user identifier. Can be email, externalUUID, or internal user ID.","example":"john.doe@acme.com","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["photo"],"properties":{"photo":{"type":"string","format":"binary","description":"Meal photo (JPEG, PNG, or WebP; max 10 MB)"},"date":{"type":"string","example":"2026-06-12","description":"Log date (YYYY-MM-DD); today or up to 7 days in the past; defaults to today"},"hint":{"type":"string","example":"half portion, no dressing","description":"Optional context about the meal (max 200 chars)"}}}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzeNutritionPhotoResponse"}}}},"400":{"description":"Missing/invalid photo, invalid date, or the photo does not contain food","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"User or organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"Vision analysis unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-nutrition"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/nutrition/photo-log' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function analyzeNutritionPhoto() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/nutrition/photo-log', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/nutrition/photo-log\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/endusers/{endUserId}/nutrition/photo-log/{pendingLogId}/confirm":{"post":{"operationId":"OrganizationEndUserNutritionApi_confirmNutritionPhotoLog","summary":"Confirm a pending photo nutrition log","description":"\n## Photo Food Logging - Confirm\n\nConfirms a pending estimate created by the analyze endpoint and writes the nutrition entry through the same pipeline as manual and chat logging (day totals summed, nutrition score recomputed, meal description and item breakdown persisted).\n\nOptionally accepts corrected `totals` if the user adjusted the estimate. Single-use: a pending log cannot be confirmed twice; expired pending logs return 400.","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"endUserId","required":true,"in":"path","description":"The user identifier. Can be email, externalUUID, or internal user ID.","example":"john.doe@acme.com","schema":{"type":"string"}},{"name":"pendingLogId","required":true,"in":"path","description":"The pending photo log id returned by the analyze endpoint.","example":"665f1b2a9c7000126616c1aa","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmNutritionPhotoLogBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmNutritionPhotoLogResponse"}}}},"400":{"description":"Pending photo log has expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Pending photo log not found or already used","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-nutrition"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/nutrition/photo-log/<PENDINGLOGID>/confirm' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function confirmNutritionPhotoLog() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/nutrition/photo-log/<PENDINGLOGID>/confirm', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/nutrition/photo-log/<PENDINGLOGID>/confirm\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/endusers/{endUserId}/nutrition/log":{"post":{"operationId":"OrganizationEndUserNutritionApi_logNutrition","summary":"Log nutrition for an end user","description":"\n## Direct Nutrition Logging\n\nLogs a nutrition entry (calories and/or macros) for the user through the same pipeline as `POST /v1/me/nutrition/log`, photo logging, and chat logging: values are added to the day's running totals, the nutrition score is recomputed, and the data feeds the daily digest and the nutrition insight pillar.\n\nAt least one of `caloriesKcal`, `proteinG`, `carbsG`, `fatG` is required.\n\n**Idempotency / corrections:** pass a stable `externalId` per meal. Re-posting the same `externalId` replaces the previous contribution instead of adding a duplicate (safe to retry, also handles date corrections), and enables `DELETE .../nutrition/log/{externalId}`. Without an `externalId` every call is additive.","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"endUserId","required":true,"in":"path","description":"The user identifier. Can be email, externalUUID, or internal user ID.","example":"john.doe@acme.com","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationLogNutritionBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationLogNutritionResponse"}}}},"400":{"description":"No nutrition values provided or invalid date","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"User or organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-nutrition"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/nutrition/log' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function logNutrition() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/nutrition/log', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/nutrition/log\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/endusers/{endUserId}/nutrition/log/{externalId}":{"delete":{"operationId":"OrganizationEndUserNutritionApi_deleteNutritionLog","summary":"Delete a logged nutrition entry","description":"\n## Nutrition Log Correction\n\nDeletes a nutrition entry previously logged with an `externalId`, subtracting its values from the day's totals (floored at 0) and recomputing the nutrition score.\n\nOnly entries created with an `externalId` can be deleted this way.","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"endUserId","required":true,"in":"path","description":"The user identifier. Can be email, externalUUID, or internal user ID.","example":"john.doe@acme.com","schema":{"type":"string"}},{"name":"externalId","required":true,"in":"path","description":"The externalId the nutrition log entry was created with.","example":"partner-meal-5521","schema":{"type":"string"}}],"responses":{"204":{"description":"Entry deleted and day totals recomputed"},"401":{"description":"Authentication failed - API key is missing or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"User, organization, or nutrition entry not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-nutrition"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X DELETE 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/nutrition/log/<EXTERNALID>' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function deleteNutritionLog() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/nutrition/log/<EXTERNALID>', {\n  method: 'DELETE',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.delete(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/nutrition/log/<EXTERNALID>\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/endusers/{endUserId}/insights/health-data":{"post":{"operationId":"OrganizationEndUserHealthDataApi_logHealthData","summary":"Push health data for an end user (batch)","description":"\n## Health Data Ingestion\n\nPushes health data for an end user into the same pipeline that powers wearable (ROOK) syncing - the data feeds daily metrics, AI insights (digest and pillars), and chat context.\n\nSupported `dataType`s per entry:\n\n| dataType | What it feeds | Key fields |\n|---|---|---|\n| `activity` | Discrete activity sessions (workout-overlap reconciliation + daily activity rollup) | `externalId` (required), `startAt` (required), `activityType`, duration/distance/HR/pace/speed/cadence/elevation/swim fields |\n| `sleep` | Sleep score and sleep HR/HRV fields | `sleepScore` or `sleepEfficiency`, `hrvRmssd`, `hrvSdnn`, `hrAvg`, `hrResting`, `hrMax`, `hrMin` |\n| `steps` | Stored per-entry (ledger) | `steps` (required) |\n| `body_metrics` | Body score (derived from BMI or weight/height) | `weightKg`, `heightCm`, `bmi` |\n| `heart_rate` | Day HR/HRV fields | `hrvRmssd`, `hrvSdnn`, `hrAvg`, `hrResting`, `hrMax`, `hrMin` |\n| `hydration` | Stored per-entry (ledger) | `waterIntakeMl` (required) |\n| `oxygenation` | Stored per-entry (ledger) | `spo2AvgPct` (required) |\n| `scores` | Partner-computed 0-100 scores (overall/physical/sleep/body/nutrition) | at least one score field |\n\n`activityType` is a free-form label. Common values: Running, Cycling, Walking, Swimming, Hiking, Yoga, Strength Training, HIIT, Rowing. Include swim fields only for swimming sessions.\n\n**Try it:** pick an Example from the request body dropdown (full day, mixed activities, day vitals, etc.).\n\n**Idempotency:** each entry carries an `externalId` (required for `activity`, defaults to a per-day key for the other types). Re-posting the same `(dataType, externalId)` updates the existing record instead of duplicating it - safe to retry.\n\n**Batch semantics:** up to 50 entries per request, processed independently and in order. The response always returns 200 with a per-entry `results` array (`created` / `updated` / `rejected` + reason) and a summary - check it instead of relying on the HTTP status.\n\n**Merge semantics:** an explicit write wins - fields claimed by your entries overwrite the stored day value (including wearable-synced values); deleting an entry releases the claim. Backfill window: up to 90 days in the past, never in the future.\n\n**Rate limit:** the request counts as 1 API call regardless of batch size.\n\n**Related:** `DELETE .../insights/health-data/{dataType}/{externalId}`, `POST .../nutrition/log`, `GET .../insights/digest`, `GET .../insights/pillars/{pillarType}`.","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"endUserId","required":true,"in":"path","description":"The user identifier. Can be email, externalUUID, or internal user ID.","example":"john.doe@acme.com","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Batch of health data entries (max 50). Use the examples dropdown for a full day, activity variants, day vitals, scores, or an idempotent correction.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogHealthDataBody"},"examples":{"full-day-batch":{"summary":"Full day - all dataTypes","description":"One entry per supported dataType for a typical day. Day-scoped types omit externalId (defaults to day-YYYY-MM-DD). Activity requires externalId.","value":{"entries":[{"dataType":"activity","externalId":"run-8842","source":"AcmeHealthApp","activityType":"Running","startAt":"2026-08-05T07:30:00.000Z","endAt":"2026-08-05T08:15:00.000Z","durationSeconds":2700,"distanceMeters":8200,"steps":7900,"activeCaloriesKcal":512,"hrAvg":148,"hrMax":176,"paceAvgMinPerKm":5.5},{"dataType":"sleep","recordedAt":"2026-08-05T08:00:00.000Z","source":"AcmeHealthApp","sleepScore":82,"sleepEfficiency":91,"hrvRmssd":46,"hrvSdnn":52,"hrAvg":54,"hrResting":52,"hrMax":74,"hrMin":47},{"dataType":"steps","recordedAt":"2026-08-05T21:00:00.000Z","source":"AcmeHealthApp","steps":10412},{"dataType":"body_metrics","recordedAt":"2026-08-05T07:00:00.000Z","source":"AcmeHealthApp","weightKg":78.4,"heightCm":181},{"dataType":"heart_rate","recordedAt":"2026-08-05T21:00:00.000Z","source":"AcmeHealthApp","hrvRmssd":44,"hrvSdnn":49,"hrAvg":64,"hrResting":55,"hrMax":132,"hrMin":48},{"dataType":"hydration","recordedAt":"2026-08-05T21:00:00.000Z","source":"AcmeHealthApp","waterIntakeMl":2100},{"dataType":"oxygenation","recordedAt":"2026-08-05T21:00:00.000Z","source":"AcmeHealthApp","spo2AvgPct":97},{"dataType":"scores","recordedAt":"2026-08-05T22:00:00.000Z","source":"AcmeHealthApp","overallHealthScore":79,"physicalScore":74,"sleepScore":85,"bodyScore":81,"nutritionScore":68}]}},"activities-mixed":{"summary":"Activities - run, ride, swim","description":"Three activity sessions showing field families: pace/distance for running, speed/cadence/elevation for cycling, swim-* fields for pool swimming.","value":{"entries":[{"dataType":"activity","externalId":"run-8842","source":"AcmeHealthApp","activityType":"Running","startAt":"2026-08-05T07:30:00.000Z","endAt":"2026-08-05T08:15:00.000Z","durationSeconds":2700,"distanceMeters":8200,"steps":7900,"activeCaloriesKcal":512,"hrAvg":148,"hrMax":176,"paceAvgMinPerKm":5.5,"paceMaxMinPerKm":4.9},{"dataType":"activity","externalId":"ride-3310","source":"AcmeHealthApp","activityType":"Cycling","startAt":"2026-08-05T17:00:00.000Z","endAt":"2026-08-05T18:10:00.000Z","durationSeconds":4200,"distanceMeters":28500,"activeCaloriesKcal":640,"hrAvg":136,"hrMax":168,"speedAvgMps":6.8,"speedMaxMps":12.1,"cadenceAvgRpm":86,"cadenceMaxRpm":102,"elevationGainMeters":220,"elevationLossMeters":195},{"dataType":"activity","externalId":"swim-2201","source":"AcmeHealthApp","activityType":"Swimming","startAt":"2026-08-05T18:30:00.000Z","endAt":"2026-08-05T19:15:00.000Z","durationSeconds":2700,"activeCaloriesKcal":380,"hrAvg":132,"hrMax":158,"swimDistanceMeters":1500,"swimLaps":30,"swimStrokes":620,"poolLengthMeters":25}]}},"activity-strength":{"summary":"Activity - strength / HIIT","description":"Indoor strength or HIIT session: duration, calories, HR, and intensity seconds. No distance, pace, or swim fields.","value":{"entries":[{"dataType":"activity","externalId":"strength-1104","source":"AcmeHealthApp","activityType":"Strength Training","startAt":"2026-08-05T12:00:00.000Z","endAt":"2026-08-05T12:45:00.000Z","durationSeconds":2700,"activeCaloriesKcal":290,"hrAvg":118,"hrMax":162,"hrMin":88,"lowIntensitySeconds":600,"moderateIntensitySeconds":1200,"vigorousIntensitySeconds":900}]}},"day-vitals":{"summary":"Day vitals - sleep, HR, steps, hydration, SpO2","description":"Day-scoped vitals without activities or partner scores.","value":{"entries":[{"dataType":"sleep","recordedAt":"2026-08-05T08:00:00.000Z","source":"AcmeHealthApp","sleepScore":82,"sleepEfficiency":91,"hrvRmssd":46,"hrvSdnn":52,"hrAvg":54,"hrResting":52,"hrMax":74,"hrMin":47},{"dataType":"heart_rate","recordedAt":"2026-08-05T21:00:00.000Z","source":"AcmeHealthApp","hrvRmssd":44,"hrvSdnn":49,"hrAvg":64,"hrResting":55,"hrMax":132,"hrMin":48},{"dataType":"steps","recordedAt":"2026-08-05T21:00:00.000Z","source":"AcmeHealthApp","steps":10412},{"dataType":"hydration","recordedAt":"2026-08-05T21:00:00.000Z","source":"AcmeHealthApp","waterIntakeMl":2100},{"dataType":"oxygenation","recordedAt":"2026-08-05T21:00:00.000Z","source":"AcmeHealthApp","spo2AvgPct":97}]}},"body-and-scores":{"summary":"Body metrics and partner scores","description":"Body metrics derive bodyScore from BMI/weight/height. Scores entry pushes partner-computed 0-100 pillar scores.","value":{"entries":[{"dataType":"body_metrics","recordedAt":"2026-08-05T07:00:00.000Z","source":"AcmeHealthApp","weightKg":78.4,"heightCm":181,"bmi":23.9},{"dataType":"scores","recordedAt":"2026-08-05T22:00:00.000Z","source":"AcmeHealthApp","overallHealthScore":79,"physicalScore":74,"sleepScore":85,"bodyScore":81,"nutritionScore":68}]}},"idempotent-correction":{"summary":"Idempotent correction (re-POST)","description":"Re-posting the same (dataType, externalId) updates the existing record (status: updated). Safe for retries and corrections.","value":{"entries":[{"dataType":"activity","externalId":"run-8842","source":"AcmeHealthApp","activityType":"Running","startAt":"2026-08-05T07:30:00.000Z","endAt":"2026-08-05T08:20:00.000Z","durationSeconds":3000,"distanceMeters":8500,"steps":8200,"activeCaloriesKcal":540,"hrAvg":150,"hrMax":178,"paceAvgMinPerKm":5.4},{"dataType":"sleep","externalId":"day-2026-08-05","recordedAt":"2026-08-05T08:00:00.000Z","source":"AcmeHealthApp","sleepScore":88,"hrvRmssd":50,"hrResting":50}]}}}}}},"responses":{"200":{"description":"Batch processed; check per-entry results for partial failures","schema":{"example":{"data":{"results":[{"index":0,"dataType":"activity","externalId":"run-8842","status":"created"},{"index":1,"dataType":"sleep","externalId":"day-2026-08-05","status":"created"},{"index":2,"dataType":"steps","externalId":"day-2026-08-05","status":"updated"},{"index":3,"dataType":"hydration","externalId":null,"status":"rejected","reason":"Entry timestamp cannot be in the future"}],"summary":{"total":4,"succeeded":3,"failed":1}}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogHealthDataResponse"}}}},"400":{"description":"Malformed request body (invalid entry shape, unknown dataType, batch size exceeded)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"User or organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-ai-insights"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/insights/health-data' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function logHealthData() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/insights/health-data', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/insights/health-data\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/endusers/{endUserId}/insights/health-data/{dataType}/{externalId}":{"delete":{"operationId":"OrganizationEndUserHealthDataApi_deleteHealthDataEntry","summary":"Delete a pushed health data entry","description":"\n## Health Data Correction\n\nDeletes a previously pushed entry by `(dataType, externalId)` and recomputes the affected day from the remaining entries.\n\n- `activity`: removes the activity session and recomputes the day's activity rollup. Only API-pushed activities can be deleted (wearable-synced sessions are protected).\n- Day-scoped types: releases the entry's field claims - fields are recomputed from your remaining entries for that day, or reset when nothing claims them anymore (a later wearable sync restores wearable-sourced values).\n\nFor entries posted without an `externalId`, use the day-derived default key `day-YYYY-MM-DD`.\n\nTo correct a value instead of removing it, simply re-POST the entry with the same `externalId` - the write is an idempotent upsert.","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}},{"name":"endUserId","required":true,"in":"path","description":"The user identifier. Can be email, externalUUID, or internal user ID.","example":"john.doe@acme.com","schema":{"type":"string"}},{"name":"dataType","required":true,"in":"path","description":"Data type of the entry to delete.","example":"activity","schema":{"enum":["activity","sleep","steps","body_metrics","heart_rate","hydration","oxygenation","scores"],"type":"string"}},{"name":"externalId","required":true,"in":"path","description":"The externalId the entry was created with (or the day-derived default \"day-YYYY-MM-DD\").","example":"partner-activity-8842","schema":{"type":"string"}}],"responses":{"204":{"description":"Entry deleted and day recomputed"},"400":{"description":"Invalid dataType, or the entry is not API-pushed (wearable-synced activities cannot be deleted)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"User, organization, or health data entry not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-ai-insights"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X DELETE 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/insights/health-data/<DATATYPE>/<EXTERNALID>' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function deleteHealthDataEntry() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/insights/health-data/<DATATYPE>/<EXTERNALID>', {\n  method: 'DELETE',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.delete(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/endusers/<END_USER_ID>/insights/health-data/<DATATYPE>/<EXTERNALID>\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/orgs/{organizationId}/stats":{"get":{"operationId":"OrganizationStatsApi_getOrganizationStats","summary":"Get organization API usage statistics","description":"\n## Organization API usage statistics\n\nReturns current-hour and daily request counts plus your subscription hourly/daily rate limits for this organization.\n\nAI and heavy-video endpoints (recommend, generate, adapt, insights, chat, full video export, etc.) count as **10x** toward those limits. Prefer caching generated plan/workout ids rather than regenerating on every page load. Plan quotas and packs: [hyperhuman.cc/pricing](https://hyperhuman.cc/pricing).\n\n**Related:** `GET /v1/orgs/{orgId}/metadata`, `GET /v1/orgs/{orgId}/workouts`, `GET /v1/orgs/{orgId}/plans`.\n        ","parameters":[{"name":"organizationId","required":true,"in":"path","description":"The unique identifier of the organization.","example":"63415bf67a9c7000126616c1","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved organization API usage statistics.","schema":{"example":{"organizationId":"63415bf67a9c7000126616c1","organizationName":"My Fitness Company","currentStats":{"currentHour":"2023-11-06T14:00:00Z","currentHourRequests":45,"totalDayRequests":234,"currentDate":"2023-11-06"},"rateLimits":{"hourly":1000,"daily":15000},"timestamp":"2023-11-06T14:30:00Z"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationStatsResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["organization"],"security":[{"AccessToken":[]},{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/stats' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getOrganizationStats() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/stats', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/orgs/<ORGANIZATION_ID>/stats\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/chat/conversations":{"post":{"operationId":"ChatApi_startConversation","summary":"Start a new chat conversation","description":"\n## Start Conversation\n\nCreates a new conversation with the AI fitness coach and returns the assistant's response to the initial message.\n\n---\n\n### User Identification\n\nProvide at least one of `userEmail` or `userExternalUUID` in the request body to identify the end user.\n\n---\n\n### Organization ID\n\n- Use `\"default\"` to automatically resolve the organization from the API key\n- Or provide a valid 24-character hex organization id\n\n---\n\n### Response\n\nReturns the created conversation metadata and the AI assistant's first response message. The assistant message may include `metadata.contentPreview` (workouts, programs, exercises) or `metadata.pendingAction` when the AI proposes a state-changing action.\n\n---\n\n### Pending Actions\n\nWhen the AI proposes a state-changing action (e.g. log nutrition, add workouts, generate workout), the assistant message will include `metadata.pendingAction` with an `id`, `type`, `summary`, and `payload`. Use the Confirm Action endpoint to execute it.\n\n---\n\n### Rate Limit\n\nThis endpoint counts as 10x API calls toward your hourly and daily limits.\n\n---\n\n### Related Endpoints\n\n- `POST /v1/chat/conversations/{conversationId}/messages` - Send follow-up messages\n- `GET /v1/chat/conversations` - List user conversations\n- `POST /v1/chat/conversations/{conversationId}/actions/confirm` - Confirm a pending action\n        ","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartConversationBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatConversationResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"End user not found in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-ai-chat"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/chat/conversations' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function startConversation() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/chat/conversations', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/chat/conversations\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]},"get":{"operationId":"ChatApi_getConversations","summary":"Get user conversations","description":"\n## List Conversations\n\nReturns a paginated list of the end user's chat conversations, ordered by most recent activity.\n\n---\n\n### User Identification\n\nProvide at least one of `userEmail` or `userExternalUUID` as query parameters to identify the end user.\n\n---\n\n### Pagination\n\n| Parameter | Default | Max |\n|-----------|---------|-----|\n| `page` | 1 | - |\n| `limit` | 20 | 100 |\n\n---\n\n### Related Endpoints\n\n- `POST /v1/chat/conversations` - Start a new conversation\n- `GET /v1/chat/conversations/{conversationId}/messages` - Get messages in a conversation\n- `DELETE /v1/chat/conversations/{conversationId}` - Archive a conversation\n        ","parameters":[{"name":"organizationId","required":true,"in":"query","description":"Organization ID - use \"default\" to use the user's default organization","example":"default","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"minimum":1,"maximum":100,"default":20,"type":"number"}},{"name":"userEmail","required":false,"in":"query","description":"User email address to identify the end user","example":"user@example.com","schema":{"type":"string"}},{"name":"userExternalUUID","required":false,"in":"query","description":"External unique identifier for the end user","example":"user-12345","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatConversationsResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"End user not found in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-ai-chat"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/chat/conversations?organizationId=default' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getConversations() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/chat/conversations?organizationId=default', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/chat/conversations?organizationId=default\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/chat/conversations/{conversationId}/messages":{"get":{"operationId":"ChatApi_getConversationMessages","summary":"Get conversation messages","description":"\n## Get Messages\n\nReturns a paginated list of messages in a conversation, ordered chronologically.\n\n---\n\n### User Identification\n\nProvide at least one of `userEmail` or `userExternalUUID` as query parameters to identify the end user. The user must be the owner of the conversation.\n\n---\n\n### Message Structure\n\nEach message includes:\n- `role`: `\"user\"` or `\"assistant\"`\n- `content`: The message text\n- `status`: `\"pending\"`, `\"delivered\"`, or `\"failed\"`\n- `metadata`: Optional object containing `reasoning`, `topics`, `contentPreview`, `pendingAction`, or `confirmedResult`\n\n---\n\n### Pagination\n\n| Parameter | Default | Max |\n|-----------|---------|-----|\n| `page` | 1 | - |\n| `limit` | 50 | 100 |\n\n---\n\n### Related Endpoints\n\n- `POST /v1/chat/conversations/{conversationId}/messages` - Send a new message\n- `GET /v1/chat/conversations` - List conversations\n        ","parameters":[{"name":"conversationId","required":true,"in":"path","schema":{"type":"string"}},{"name":"organizationId","required":true,"in":"query","description":"Organization ID - use \"default\" to use the user's default organization","example":"default","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}},{"name":"userEmail","required":false,"in":"query","description":"User email address to identify the end user","example":"user@example.com","schema":{"type":"string"}},{"name":"userExternalUUID","required":false,"in":"query","description":"External unique identifier for the end user","example":"user-12345","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatMessagesResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"End user or conversation not found in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-ai-chat"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X GET 'https://content.api.hyperhuman.cc/v1/chat/conversations/<CONVERSATIONID>/messages?organizationId=default' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function getConversationMessages() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/chat/conversations/<CONVERSATIONID>/messages?organizationId=default', {\n  method: 'GET',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.get(\"https://content.api.hyperhuman.cc/v1/chat/conversations/<CONVERSATIONID>/messages?organizationId=default\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]},"post":{"operationId":"ChatApi_sendMessage","summary":"Send message to conversation","description":"\n## Send Message\n\nSends a user message to an existing conversation and returns the AI coach's response.\n\n---\n\n### User Identification\n\nProvide at least one of `userEmail` or `userExternalUUID` in the request body to identify the end user. The user must be the owner of the conversation.\n\n---\n\n### Response\n\nReturns three objects:\n- `userMessage` - The saved user message\n- `assistantMessage` - The AI coach response\n- `conversation` - Updated conversation metadata (messageCount, lastMessageAt)\n\n---\n\n### AI Capabilities\n\nThe AI coach can:\n- List, search, and recommend workouts, programs, and exercises (returned in `metadata.contentPreview`)\n- Propose state-changing actions like logging nutrition, adding/assigning workouts and plans, adapting or generating workouts and programs (returned in `metadata.pendingAction`)\n- Provide personalized advice based on user profile, training history, and goals\n\n---\n\n### Rate Limit\n\nThis endpoint counts as 10x API calls toward your hourly and daily limits.\n\n---\n\n### Related Endpoints\n\n- `POST /v1/chat/conversations` - Start a new conversation\n- `POST /v1/chat/conversations/{conversationId}/actions/confirm` - Confirm a pending action\n- `GET /v1/chat/conversations/{conversationId}/messages` - Get message history\n        ","parameters":[{"name":"conversationId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMessageBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMessageResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Conversation not found or does not belong to the user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-ai-chat"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/chat/conversations/<CONVERSATIONID>/messages' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function sendMessage() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/chat/conversations/<CONVERSATIONID>/messages', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/chat/conversations/<CONVERSATIONID>/messages\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/chat/conversations/{conversationId}/actions/confirm":{"post":{"operationId":"ChatApi_confirmAction","summary":"Confirm a pending AI action","description":"\n## Confirm Action\n\nExecutes a pending action proposed by the AI coach after user confirmation.\n\n---\n\n### How It Works\n\n1. The AI proposes an action via `assistantMessage.metadata.pendingAction`\n2. Your client shows a confirmation UI with the action `summary`\n3. User confirms, and you call this endpoint with the `pendingActionId`\n4. The action is executed and the result is returned\n\n---\n\n### Supported Action Types\n\n| Type | Description | Response Field |\n|------|-------------|----------------|\n| `log_nutrition` | Log a meal or nutrition entry | `nutritionOverview` |\n| `add_workouts` | Add workouts to user's library | `message` |\n| `add_plans` | Add plans to user's library | `message` |\n| `assign_workouts` | Assign workouts to the user | `message` |\n| `assign_plans` | Assign plans to the user | `message` |\n| `adapt_workout` | Adapt a workout on the fly | `adaptedWorkout` |\n| `adapt_program` | Adapt a program on the fly | `adaptedProgram` |\n| `generate_workout` | Generate a new workout | `generatedWorkout` |\n| `generate_program` | Generate a new program | `generatedProgram` |\n\n---\n\n### Adapted/Generated Content\n\n`adaptedWorkout` and `generatedWorkout` use the same response format as `POST /v1/orgs/{orgId}/workouts/{id}/adapt` and `POST /v1/orgs/{orgId}/workouts/generate` respectively. Same applies to program equivalents. Clients can reuse the same types and rendering logic.\n\n---\n\n### Related Endpoints\n\n- `POST /v1/chat/conversations/{conversationId}/messages` - Send a message (may return pendingAction)\n- `POST /v1/chat/conversations` - Start a conversation (may return pendingAction)\n        ","parameters":[{"name":"conversationId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmActionBody"}}}},"responses":{"200":{"description":"Action executed successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmActionResponseDto"}}}},"400":{"description":"Action expired or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Pending action not found or already used.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-ai-chat"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X POST 'https://content.api.hyperhuman.cc/v1/chat/conversations/<CONVERSATIONID>/actions/confirm' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{}'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function confirmAction() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/chat/conversations/<CONVERSATIONID>/actions/confirm', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({}),\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.post(\n    \"https://content.api.hyperhuman.cc/v1/chat/conversations/<CONVERSATIONID>/actions/confirm\",\n    headers={**headers, \"Content-Type\": \"application/json\"},\n    json={},\n)\nresponse.raise_for_status()\nprint(response.json())"}]}},"/v1/chat/conversations/{conversationId}":{"delete":{"operationId":"ChatApi_archiveConversation","summary":"Archive conversation","description":"\n## Archive Conversation\n\nSoft-deletes a conversation by setting its status to `archived`. The conversation and its messages are retained in the database but will no longer appear in the conversations list.\n\n---\n\n### User Identification\n\nProvide at least one of `userEmail` or `userExternalUUID` as query parameters to identify the end user. The user must be the owner of the conversation.\n\n---\n\n### Related Endpoints\n\n- `GET /v1/chat/conversations` - List active conversations\n- `GET /v1/chat/conversations/{conversationId}/messages` - Get messages before archiving\n        ","parameters":[{"name":"conversationId","required":true,"in":"path","schema":{"type":"string"}},{"name":"organizationId","required":true,"in":"query","description":"Organization ID - use \"default\" to use the user's default organization","example":"default","schema":{"type":"string"}},{"name":"userEmail","required":false,"in":"query","description":"User email address to identify the end user","example":"user@example.com","schema":{"type":"string"}},{"name":"userExternalUUID","required":false,"in":"query","description":"External unique identifier for the end user","example":"user-12345","schema":{"type":"string"}}],"responses":{"200":{"description":"Conversation archived successfully."},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Authentication failed - API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key is not authorized for this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"End user or conversation not found in this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["endusers-ai-chat"],"security":[{"X-Api-Key":["X-Api-Key"]}],"x-codeSamples":[{"lang":"curl","label":"cURL","source":"curl -X DELETE 'https://content.api.hyperhuman.cc/v1/chat/conversations/<CONVERSATIONID>?organizationId=default' \\\n  -H 'X-Api-Key: YOUR_API_KEY'"},{"lang":"typescript","label":"TypeScript (fetch)","source":"async function archiveConversation() {\n  const res = await fetch('https://content.api.hyperhuman.cc/v1/chat/conversations/<CONVERSATIONID>?organizationId=default', {\n  method: 'DELETE',\n  headers: {\n    'X-Api-Key': process.env.HYPERHUMAN_API_KEY ?? '',\n  },\n  });\n  if (!res.ok) {\n    const err = await res.json().catch(() => ({}));\n    throw new Error(err.error?.code ?? res.statusText);\n  }\n  return res.json();\n}"},{"lang":"python","label":"Python (requests)","source":"import os\nimport requests\n\nheaders = {\"X-Api-Key\": os.environ[\"HYPERHUMAN_API_KEY\"]}\nresponse = requests.delete(\"https://content.api.hyperhuman.cc/v1/chat/conversations/<CONVERSATIONID>?organizationId=default\", headers=headers)\nresponse.raise_for_status()\nprint(response.json())"}]}}},"info":{"title":"Hyperhuman Content API","description":"<!--\n  Do not add an `# H1` here. Swagger UI and Scalar both render `info.title`\n  (\"Hyperhuman Content API\") above this description; an h1 would duplicate it.\n  Start with the tagline blockquote and a positioning paragraph instead.\n-->\n\n> One API for delivery, personalization, and insights across your entire product.\n\nFitness content infrastructure for modern health, wellness, and fitness products: workout API, AI recommendations, AI generation, AI adaptation, and insights in one platform. Most teams ship Publish + Recommend in the first week and add the AI layers as their audience signals demand it.\n\n---\n\n## Quick Start\n\n**1. Get credentials** -> [team.hyperhuman.cc/settings?tab=integrations](https://team.hyperhuman.cc/settings?tab=integrations)\n\n**2. First request:**\n```bash\ncurl -X GET 'https://content.api.hyperhuman.cc/v1/workouts/metadata' \\\n  -H 'X-Api-Key: YOUR_API_KEY'\n```\n\n**3. Generate a workout:**\n```bash\ncurl -X POST 'https://content.api.hyperhuman.cc/v1/orgs/{organizationId}/workouts/generate' \\\n  -H 'X-Api-Key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"endUserProfileDetails\": {\"age\": 28, \"fitnessLevels\": [\"beginner\"]},\n    \"exerciseSources\": [\"premium_stock\"],\n    \"durationOptions\": {\"minMinutes\": 20, \"maxMinutes\": 20},\n    \"categoryId\": \"615aa3f0dbe7140012c59e94\",\n    \"locale\": \"fr-FR\"\n  }'\n```\n\nResponse includes additive localization fields when `locale` is set: `nameTranslations` (AI title in en-US + target locale), `nameLocalized` / `muscleGroupsLocalized` / `equipmentLocalized` on exercises, and `difficultyLabel`. Legacy `name` stays English.\n\n---\n\n## For LLMs and AI agents\n\nIf you are a coding assistant integrating against this API, prefer these machine-readable artifacts over scraping this HTML page:\n\n| Artifact | URL | Use it for |\n|----------|-----|------------|\n| Compact LLM index (markdown) | [https://content.api.hyperhuman.cc/llms.txt](https://content.api.hyperhuman.cc/llms.txt) | Short overview + links to deeper docs. Drop into context windows. |\n| Full LLM bundle (markdown) | [https://content.api.hyperhuman.cc/llms-full.txt](https://content.api.hyperhuman.cc/llms-full.txt) | Auth, error envelope, pagination, locales, and per-endpoint summaries in one file. |\n| OpenAPI 3 spec (JSON) | [https://content.api.hyperhuman.cc/openapi.json](https://content.api.hyperhuman.cc/openapi.json) | Source of truth for tool/function calling. Stable `operationId`s of the form `Controller_method`. |\n| OpenAPI 3 spec (YAML) | [https://content.api.hyperhuman.cc/openapi.yaml](https://content.api.hyperhuman.cc/openapi.yaml) | Same content as `openapi.json`, friendlier for diffing and most CLI codegen tools. |\n| Agent integration guide | [https://content.api.hyperhuman.cc/AGENTS.md](https://content.api.hyperhuman.cc/AGENTS.md) | Conventions for generated client code (auth, errors, pagination, locales) plus **§11–12**: strict whitelisted query/body keys, public `/openapi.json` scope, id wording, and **repository** notes for API maintainers (DTOs, `parse-csv-ids`, OpenAPI `include` list). |\n| Custom player guide | [https://content.api.hyperhuman.cc/docs/guides/custom-player.md](https://content.api.hyperhuman.cc/docs/guides/custom-player.md) | Reference implementation for building a custom interactive workout player on top of `/playlist` and `/music`. |\n\n> Need a copy-paste prompt? Send the agent the URL of `/llms-full.txt` plus the prose: \"Use this Hyperhuman Content API. Authenticate with the `X-Api-Key` header. Every error response is `{ \"error\": { \"code\", \"message\" } }`. Prefer `links.next` for pagination (`offset`/`limit` at runtime; OpenAPI may hide `offset`).\"\n\n---\n\n## Five capabilities, one API\n\nFive product surfaces stack on the same library. Start where you are; add the AI layers as your product matures.\n\n| # | Capability | Primary endpoint | What it does | Latency band |\n|---|------------|------------------|--------------|--------------|\n| 1 | **Publish Content** | `GET /v1/orgs/{organizationId}/workouts` <br> `GET /v1/orgs/{organizationId}/plans` | List, filter, and play workouts and multi-week plans from your library. Your library becomes your product surface. | Fast |\n| 2 | **AI Recommend** | `POST /v1/orgs/{organizationId}/workouts/recommend` <br> `POST /v1/orgs/{organizationId}/plans/recommend` | Rank **existing** library workouts or plans for a user profile (e.g. quiz → best curated match). Does not create new content. | Sub-second |\n| 3 | **AI Generate** | `POST /v1/orgs/{organizationId}/workouts/generate` <br> `POST /v1/orgs/{organizationId}/plans/generate` | Create a brand-new workout or multi-week plan on the fly. Workout generate returns ephemeral JSON (no library id). Plan generate returns a top-level plan `id` **only** when `endUserProfileDetails.endUserId` is set — store that id; without it there is no plan id. Optional body `locale` localizes AI output. | 2-8 seconds |\n| 4 | **AI Adapt** | `POST /v1/orgs/{organizationId}/workouts/{workoutId}/adapt` <br> `POST /v1/orgs/{organizationId}/plans/{planId}/adapt` | Evolve an existing workout or plan as the user progresses. Workout adapt is ephemeral JSON (no workout id). Plan adapt **requires** `endUserProfileId` and returns a persisted adapted program `id`. Counts as 10x rate-limit weight. | 2-8 seconds |\n| 5 | **AI Insights** | `GET /v1/orgs/{organizationId}/endusers/{endUserId}/insights/digest?date=<ISO 8601 date-time>` <br> `GET /v1/orgs/{organizationId}/endusers/{endUserId}/insights/pillars/{pillarType}` <br> `POST /v1/orgs/{organizationId}/endusers/{endUserId}/insights/health-data` <br> `POST /v1/orgs/{organizationId}/endusers/{endUserId}/nutrition/log` | Daily digest plus per-pillar drill-downs (health pulse, training, recovery, movement, nutrition, body) for re-engagement loops. Push your own health data (activities, sleep, steps, body metrics, heart rate, hydration, SpO2, pre-computed scores — batch of up to 50, idempotent per `externalId`) and nutrition logs into the same pipeline that powers the insights. | Fast |\n\n> `{endUserId}` is the end-user identifier. It accepts the user's email, your `externalUUID`, or the internal user id (24-character hex DB id returned by the endusers endpoints) - they all resolve to the same end user. Treat all ids as opaque strings. An identifier that does not resolve to an end user in the organization returns `404` (an unknown identifier never produces a `500`).\n\n### Recommend vs Generate (pick one)\n\n| Need | Use | Result |\n|------|-----|--------|\n| Pair a quiz / profile to workouts your team already published | `POST .../workouts/recommend` (or `.../plans/recommend`) | Ranked library items with `recommendation` text; play via persisted workout/plan ids |\n| Create a new workout structure on the fly | `POST .../workouts/generate` | Ephemeral `{ name, instances[], … }` — **JSON-receiver iframe** + `GET /video-asset/{id}`; **no** `/playlist`, `/music`, or sessions by id |\n| Create a new multi-week program | `POST .../plans/generate` | Set `endUserProfileDetails.endUserId` to get a persisted plan `id` to **store** (`GET /v1/plans/{planId}`); without `endUserId` → no top-level id. Not listed on org plan library. Body sources field: `workoutCollectionSources` |\n| Fixed conditional branches (e.g. week 1 + beginner → workout X) | Your app logic + Recommend / library select / Generate with a specific profile | Not a deterministic rules engine inside Generate |\n\n---\n\n## Three delivery models\n\nThe same library and intelligence layer ship through three integration paths. Pick by team capacity and product surface.\n\n### 1. Embed & Go\n\nDrop Hyperhuman-hosted surfaces into a webview, landing page, or portal: a **single-workout or JSON player** on `team.hyperhuman.cc` (see **Embedded Player**), or a **full workouts or programs library grid** on the member web app with configurable discovery UI (see **Branded library embed**). Fastest path to live content; no custom player build required. Best for web apps, MVPs, corporate wellness portals, marketing pages.\n\n### 2. Stream Videos\n\nGet a pre-rendered, full-length workout **video** or **narrative audio** as a **single presigned HTTPS URL** in the response body. Best for VOD catalogs, CMS publishing, YouTube workflows, audio-first products.\n\n```bash\ncurl -X GET 'https://content.api.hyperhuman.cc/v1/workouts/{workoutId}/export/video/stream_url?locale=en-US' \\\n  -H 'X-Api-Key: YOUR_API_KEY'\n```\n\n```bash\ncurl -X GET 'https://content.api.hyperhuman.cc/v1/workouts/{workoutId}/export/audio/stream_url?locale=en-US' \\\n  -H 'X-Api-Key: YOUR_API_KEY'\n```\n\nReturns **`200`** with **`Content-Type: text/plain`**: a **single** presigned URL string (not JSON). The URL points to the full-workout **video** or **narrative audio** object stored for that locale — commonly **progressive MP4** (video) or **M4A** (audio). Follow the URL extension and response `Content-Type`. URLs are time-limited AWS S3 presigned links (on the order of **7 days**); re-fetch before expiry. Not HLS/DASH/ABR. Pre-rendered video/audio takes 2-5 minutes to produce after a workout is created or generated; until then the export endpoint returns `404`. If the requested locale has not been rendered, the endpoint also returns `404` - retry with `locale=en-US` or trigger a render for the missing locale.\n\n### 3. Build Your UX\n\nPower your own player UI with our structured playlist and time-limited S3 **presigned progressive MP4** / M4A media URLs (~7 days). Maximum control over UI, analytics, and offline behavior. Best for mobile apps, connected hardware, and premium coaching experiences. See the **Custom Interactive Workout Player** section below for the reference implementation.\n\n---\n\n## Embedded Player\n\nTwo drop-in **iframes** (always frame them — do not open the player URLs as a top-level page) for the most common integration paths. Host: `https://team.hyperhuman.cc`. The same player powers both — only the data source differs.\n\n| | Pre-built (`/embed/workout/{id}`) | AI / JSON (`/embed/workout-json-receiver`) |\n|--|--|--|\n| Data source | Persisted library workout id | `HYPERHUMAN_EMBED_INIT.workout` (pass generate/adapt JSON as-is) |\n| PulseMix / `videoAudioMode` / `mixBgMusic` query overrides | Yes | No |\n| Session tracking, attributed feedback, `HYPERHUMAN_SESSION_EVENT` | Yes | **No** (no persisted workout id) |\n| Media resolution | `GET /v1/workouts/{id}` + `/playlist` (+ `/music`) | `GET /v1/video-asset/{exerciseId}` per exercise |\n| Typical Content API prep | List/recommend → pick id | `POST .../workouts/generate` (or adapt) → post JSON |\n\n### Pre-built Workout\n\nRenders any workout from your library by id. Under the hood the player loads details, playlist, and (when enabled) PulseMix via the Content API for that persisted id.\n\n```html\n<!-- Landscape card (16:9). For mobile / immersive hosts prefer the full-viewport snippet below. -->\n<iframe\n  src=\"https://team.hyperhuman.cc/embed/workout/{workoutId}?organizationId={organizationId}&apiKey={apiKey}&locale=en-US\"\n  style=\"width: 100%; aspect-ratio: 16/9; border: none; border-radius: 8px;\"\n  allow=\"autoplay; fullscreen; accelerometer; gyroscope\"\n  referrerpolicy=\"strict-origin-when-cross-origin\"\n  allowfullscreen>\n</iframe>\n```\n\n**Full-viewport (recommended for mobile / portrait):** give the player the visible viewport so Club-style letterboxed 16:9 video + top/bottom bands have room. Hide your own app chrome when entering an immersive mode; the in-player UI keeps a floating exit only when the host does the same.\n\n```html\n<div style=\"position: relative; width: 100%; height: 100vh; height: 100dvh; background: #000;\">\n  <iframe\n    src=\"https://team.hyperhuman.cc/embed/workout/{workoutId}?organizationId={organizationId}&apiKey={apiKey}&locale=en-US\"\n    style=\"position: absolute; inset: 0; width: 100%; height: 100%; border: none;\"\n    allow=\"autoplay; fullscreen; accelerometer; gyroscope\"\n    referrerpolicy=\"strict-origin-when-cross-origin\"\n    allowfullscreen>\n  </iframe>\n</div>\n```\n\n> Prefer copying the snippet from **Teams → Workout details → Deliver → Embed** so `allow` and container height stay current. Missing `allowfullscreen` or `allow` tokens that include `autoplay` / `fullscreen` is the most common cause of broken playback/fullscreen.\n\n#### Query Parameters\n\n| Param | Required | Type | Default | Description |\n|-------|----------|------|---------|-------------|\n| `organizationId` | yes | string | - | Organization id (24-character hex DB id) the workout belongs to. Used for org branding and (with standard/club keys) session attribution. |\n| `apiKey` | conditional | string | - | Your Content API key (`X-Api-Key` value). Required **unless** you deliver it over `postMessage` with `keyHandshake=1` (see **Keeping the API key out of the URL** below). |\n| `keyHandshake` | no | boolean | `false` | Accept `1`/`true`. When set **and** the URL has no `apiKey`, the player announces readiness and waits for `HYPERHUMAN_EMBED_INIT` with the key (same channel as the AI-Generated receiver). If `apiKey` is also present in the URL, the URL key wins and the handshake is skipped. |\n| `locale` | no | string | `en-US` | BCP-47 locale. Falls back to English when unsupported. |\n| `segment` | no | string | first segment | Segment id to start playback from (e.g. resume from a specific exercise). |\n| `presentationStyle` | no | enum | workout default | One of `full`, `minimal`, `essential`, `noOverlays`. Overrides the workout's own `presentationStyle`. |\n| `videoAudioMode` | no | enum | workout default | One of `full`, `instructionsOnly`, `beepsOnly`, `none`. Overrides the workout's own `videoAudioMode` audio policy (see the matrix in **Custom Interactive Workout Player → Audio policy matrix**). Use `instructionsOnly` to keep voice but drop beeps and background music. |\n| `mixBgMusic` | no | boolean | workout default | Accept `1`/`true` or `0`/`false`. Overrides the workout's own `mixBgMusic` flag. Set `0` to suppress background music while keeping voice instructions; omit to use the workout's stored value. |\n| `muted` | no | boolean | `false` | Accept `1` or `true`. Hard mute - silences voice, beeps, background music, and inline video audio together (equivalent to `videoAudioMode=none`). For finer control use `videoAudioMode` / `mixBgMusic` instead. Pair with `autoplay=1` for unattended embeds. |\n| `autoplay` | no | boolean | `false` | Accept `1` or `true`. Browsers block sound autoplay without a user gesture - combine with `muted=1`. |\n| `brandLogoUrl` | no | string (URL) | org logo | Overrides the player logo. Square PNG recommended. |\n| `brandWatermarkUrl` | no | string (URL) | org watermark | Overrides the bottom-right watermark (your org's brand mark). Square PNG with transparent background recommended. |\n| `brandMainColor` | no | hex string | org main color | Player accent color: action-button backgrounds (start / pause / done / resume / play-again), progress-bar completion fill, the upcoming-exercise badge, and the active class-chapter highlight. URL-encode the `#` (`%23FF6600`). |\n| `brandSecondaryColor` | no | hex string | org secondary color | Progress-bar incomplete (remaining-track) color and the translucent background of the music-control buttons. URL-encode the `#`. |\n| `brandTextColor` | no | hex string | org text color | Foreground color for timer / time-left / next-exercise / outro text and for button labels and icons (including the music controls). URL-encode the `#`. |\n| `sessionMode` | no | enum | `anonymous` | `anonymous` · `attributed` · `host`. May also be sent in `HYPERHUMAN_EMBED_INIT` (see **Session attribution**). URL value wins over the envelope when both are set. |\n| `endUserId` | no | string | - | With `sessionMode=attributed`: Hyperhuman user id or email. May also be sent in the INIT envelope (preferred if you want it out of the URL). |\n| `externalUserId` | no | string | - | Alternative to `endUserId` (external id on the team membership). |\n\n> Tip: org-level branding (logo, watermark, colors) is applied automatically from your org settings (exposed by `GET /v1/orgs/{organizationId}/metadata`). Pass the `brand*` overrides only when you need to differ from the org defaults (e.g. white-label per end-user). The same metadata payload includes `ai*Enabled` / `insightsEnabled` — those are **member-app visibility** flags, not Content API capability gates.\n\n#### Keeping the API key out of the URL (optional)\n\nThe snippet above puts `apiKey` in the iframe URL. That is fine for a server-rendered page where the URL is never user-visible, but the key then also lands in the page source, browser history, and the `Referer` header / access logs of resources the iframe loads. To avoid that, drop `apiKey`, add `keyHandshake=1`, and reply to the player's ready signal with the key over `postMessage` - the same handshake the **AI-Generated Workout** receiver uses below.\n\n```html\n<iframe id=\"player\"\n  src=\"https://team.hyperhuman.cc/embed/workout/{workoutId}?organizationId={organizationId}&keyHandshake=1&locale=en-US\"\n  style=\"width: 100%; aspect-ratio: 16/9; border: none; border-radius: 8px;\"\n  allow=\"autoplay; fullscreen; accelerometer; gyroscope\"\n  referrerpolicy=\"strict-origin-when-cross-origin\"\n  allowfullscreen>\n</iframe>\n\n<script>\n  // Pin the player origin so the key is only ever sent to (and accepted from) Hyperhuman.\n  var HYPERHUMAN_PLAYER_ORIGIN = 'https://team.hyperhuman.cc';\n\n  window.addEventListener('message', (e) => {\n    if (e.origin !== HYPERHUMAN_PLAYER_ORIGIN) return;        // ignore other frames\n    if (e.data === 'hyperhumanPlayerReadyForData') {\n      document.getElementById('player').contentWindow.postMessage({\n        type: 'HYPERHUMAN_EMBED_INIT',\n        apiKey: '{apiKey}'      // your Content API key\n      }, HYPERHUMAN_PLAYER_ORIGIN);\n    }\n  });\n</script>\n```\n\nThe `workoutId` stays in the URL (it is not a secret); only the key moves to the message. Always set an explicit `targetOrigin` (`https://team.hyperhuman.cc`) on the post - never `'*'`, which would broadcast the key to any frame. The player waits briefly for the message before it starts.\n\n> The key is a **client-visible** credential either way - it runs in the browser, so a determined viewer can read it from JS or the network tab. `keyHandshake` only keeps it out of the URL, history, logs, and `Referer`. There is **no separate publishable or scoped player key** today. For a key that never reaches the browser at all, render server-side and use the **Stream Videos** export URLs or the **Custom Interactive Workout Player** below, where `X-Api-Key` stays on your backend.\n\n---\n\n### AI-Generated Workout\n\nFor workouts produced on the fly by your own backend or by `POST /v1/orgs/{organizationId}/workouts/generate` (or workout **adapt**). Load the receiver **in an iframe**; it announces readiness, then your page replies with the API key **and** the generate JSON over `postMessage` — the key is **not** placed in the iframe URL.\n\n```html\n<iframe id=\"player\"\n  src=\"https://team.hyperhuman.cc/embed/workout-json-receiver?organizationId={organizationId}&locale=en-US\"\n  style=\"width: 100%; aspect-ratio: 16/9; border: none; border-radius: 8px;\"\n  allow=\"autoplay; fullscreen; accelerometer; gyroscope\"\n  referrerpolicy=\"strict-origin-when-cross-origin\"\n  allowfullscreen>\n</iframe>\n\n<script>\n  // Pin the player origin so the key is only ever sent to (and accepted from) Hyperhuman.\n  var HYPERHUMAN_PLAYER_ORIGIN = 'https://team.hyperhuman.cc';\n\n  window.addEventListener('message', (e) => {\n    if (e.origin !== HYPERHUMAN_PLAYER_ORIGIN) return;            // ignore other frames\n    if (e.data === 'hyperhumanPlayerReadyForData') {\n      document.getElementById('player').contentWindow.postMessage({\n        type: 'HYPERHUMAN_EMBED_INIT',\n        apiKey: '{apiKey}',       // your Content API key\n        workout: workoutJSON      // payload shape below\n      }, HYPERHUMAN_PLAYER_ORIGIN);\n    }\n  });\n</script>\n```\n\nDelivering the key over `postMessage` instead of the URL keeps it out of the page source, browser history, server/CDN access logs, and the `Referer` header.\n\n#### Query Parameters\n\n| Param | Required | Type | Default | Description |\n|-------|----------|------|---------|-------------|\n| `organizationId` | yes | string | - | Organization id (24-character hex DB id). |\n| `locale` | no | string | `en-US` | BCP-47 locale. |\n| `segment` | no | string | first segment | Segment id to start playback from. |\n\n> The API key is **no longer a query parameter** - send it in the `HYPERHUMAN_EMBED_INIT` message instead. For backward compatibility the receiver still accepts a legacy `apiKey` query param and a raw (un-enveloped) workout payload, but new integrations should use the envelope above.\n\n#### postMessage Protocol\n\n1. The iframe loads, confirms `organizationId` is present (the key arrives by message, so it does not gate this step), then after a short delay (~1s) posts the literal string `'hyperhumanPlayerReadyForData'` to its parent. If `organizationId` is **missing**, the receiver shows **Error: Organization ID is required** and does **not** post ready.\n2. Your page replies with a single `HYPERHUMAN_EMBED_INIT` envelope carrying `apiKey` and `workout` (pass the generate/adapt response object). Always set an explicit `targetOrigin` (`https://team.hyperhuman.cc`) — never `'*'`.\n3. An invalid key is not validated up front — it surfaces as failed `GET /v1/video-asset/{id}` calls (**401**) in the console, not as a blocking error screen. An invalid/non-workout payload shows an inline format error until a valid INIT arrives.\n4. Subsequent `HYPERHUMAN_EMBED_INIT` posts replace the current workout (useful for \"play next\"); the key may be omitted on follow-up posts once set.\n\n#### Workout JSON Payload Shape\n\nThis object is the `workout` field of the `HYPERHUMAN_EMBED_INIT` envelope (or, for legacy embeds, the raw `postMessage` body).\n\n```json\n{\n  \"name\": \"Quick Morning Burner\",\n  \"totalDurationSeconds\": 600,\n  \"difficulty\": \"intermediate\",\n  \"categoryId\": \"615aa3f0dbe7140012c59e94\",\n  \"initialSegmentId\": \"instance_1\",\n  \"instances\": [\n    {\n      \"id\": \"instance_1\",\n      \"kind\": \"single-exercise\",\n      \"durationSeconds\": 45,\n      \"pace\": \"medium\",\n      \"weightLevel\": \"medium\",\n      \"rpe\": 7,\n      \"amrap\": false,\n      \"skipIntro\": false,\n      \"exercise\": {\n        \"id\": \"507f1f77bcf86cd799439011\",\n        \"name\": \"Bodyweight Squats\",\n        \"thumbnailUrl\": \"https://images.hyperhuman.cc/squat-thumb.jpg\"\n      }\n    },\n    {\n      \"id\": \"instance_rest_1\",\n      \"kind\": \"rest\",\n      \"durationSeconds\": 30\n    }\n  ]\n}\n```\n\n| Field | Required | Notes |\n|-------|----------|-------|\n| `name` | yes | Workout title (page title / intro). Receiver validates `name` + `instances[]` only. |\n| `instances[]` | yes | Ordered exercise + rest segments. Generate emits wire kinds `single-exercise` \\| `rest` only. |\n| `instances[].kind` | yes | `single-exercise` or `rest` (generate/adapt). |\n| `instances[].exercise.id` | yes (for exercises) | 24-character hex exercise id → player calls `GET /v1/video-asset/{id}`. |\n| `instances[].durationSeconds` | conditional | Segment length in **seconds** (generate already converts from internal ms). |\n| `instances[].reps` | conditional | Rep-based exercises; duration estimated from `exercise.estimatedRepDuration` when `durationSeconds` omitted. Provide `durationSeconds` **or** `reps`. |\n| `instances[].exercise.equipment` | optional | `string[]`; upcoming-exercise overlay. |\n| `instances[].exercise.muscleGroups` | optional | `string[]`; upcoming-exercise overlay. |\n| `instances[].skipIntro` | optional | When `true`, skips per-exercise intro/preview. |\n| `instances[].pace` / `weightLevel` / `weight` / `weightUnit` / `rpe` / `amrap` | optional | Overlay metadata when present (`rpe`/`amrap` are host-optional; generate often omits them). |\n| `totalDurationSeconds` | recommended | Progress bar / “N min left”. |\n| `initialSegmentId` | optional | Same effect as the `segment` query param. |\n\n> **Audio / video (JSON receiver):** Prefer posting the generate/adapt response as `workout` unchanged. The player resolves each exercise via `GET /v1/video-asset/{exerciseId}` (instruction audio capped at 3 clips; some assets have **zero** instruction tracks — video still plays). Generate may include `exercise.videoUri`; the embed still re-fetches by `exercise.id`. Preview/intro cues are **silent** for AI/JSON workouts — instructions play during execution when available.\n>\n> **Background music / PulseMix:** Not available. No `GET .../music`. `mixBgMusic` / `videoAudioMode` on the posted JSON are ignored. Use the **Pre-built** embed for music + audio-policy overrides.\n>\n> **Sessions / feedback:** Not available on this path (no persisted workout id). Sending `sessionMode` / `endUserId` on INIT does **not** enable tracking — use the pre-built embed for sessions, in-player feedback, or `host` events.\n\n#### Security Model\n\nThe receiver accepts the `HYPERHUMAN_EMBED_INIT` message from **any parent origin** so third-party customer pages can drive the player without per-tenant allow-list configuration; the trust boundary inside the iframe is **payload-shape validation** - the receiver only honors a `workout` object matching the schema above.\n\nReceiving the API key here from the framing parent is legitimate - the parent already owns it. What matters is the host hygiene shown above: send the key only with an explicit `targetOrigin`, and accept the ready signal only from the pinned player origin. Aside from that key, treat this channel as untrusted - do not transmit other secrets, access tokens, or PII over it.\n\n---\n\n### Session attribution & modes (pre-built only)\n\n**Pre-built** embeds track a workout session against the Content API (`sessions/start` → PATCH → `complete` / `end`, optional feedback). **JSON-receiver** embeds do **not** call session or feedback APIs today.\n\nDefault is **anonymous** (API key only, `traineeId: null`). Choose ownership via query params on `/embed/workout/{id}` and/or fields on `HYPERHUMAN_EMBED_INIT` (URL values win when both are set):\n\n| Field | Type | Default | Description |\n|-------|------|---------|-------------|\n| `sessionMode` | enum | `anonymous` | `anonymous` (no identity), `attributed` (player attributes the session to an end user), or `host` (player emits lifecycle events; your page owns tracking server-side). |\n| `endUserId` | string | - | Attribute to an end user by Hyperhuman user id or email. Used when `sessionMode=attributed`. |\n| `externalUserId` | string | - | Alternative to `endUserId`: external id on the team membership. |\n\n```javascript\n// Prefer INIT for identity (keeps endUserId out of the iframe URL / logs / Referer).\ndocument.getElementById('player').contentWindow.postMessage({\n  type: 'HYPERHUMAN_EMBED_INIT',\n  apiKey: '{apiKey}',\n  sessionMode: 'attributed',\n  endUserId: 'member-123'      // Hyperhuman user id or email\n}, HYPERHUMAN_PLAYER_ORIGIN);\n```\n\nIn `attributed` mode the player also shows an in-player feedback prompt at completion (`GET /v1/workouts/feedback/options` + `POST /v1/workouts/{id}/feedback` with option **ids**). Attribution follows the session rules in [AGENTS.md](https://content.api.hyperhuman.cc/AGENTS.md) section 9. In `host` mode the player does not call the session API; it emits the outbound events below for your page to relay.\n\n---\n\n### Player Cast Controls (optional)\n\nBoth iframes accept playback control messages from any parent origin. Useful for casting, custom UI overlays, or remote control surfaces.\n\n```javascript\nplayerIframe.contentWindow.postMessage({\n  type: 'CAST_CONTROL',\n  action: 'play' // 'play' | 'pause' | 'next' | 'prev' | 'restart' | 'done' | 'done_exercise'\n}, '*');\n```\n\nAction strings are matched literally - use `prev` (not `previous`). `next`/`prev` advance whole segments, or step exercises within a class/multi-exercise block when one is active. `done` jumps to the outro; `done_exercise` marks the current rep-based exercise complete (no-op otherwise). Unknown actions are ignored.\n\n**Host chrome / orientation (optional):**\n\n```javascript\n// Host → player: app chrome hidden / full-viewport stage (player may tighten padding)\nplayerIframe.contentWindow.postMessage({\n  type: 'HYPERHUMAN_HOST_IMMERSIVE',\n  immersive: true\n}, HYPERHUMAN_PLAYER_ORIGIN);\n```\n\nSame security model as the JSON receiver: payload-shape validated, origin-open for CAST. Prefer an explicit `targetOrigin` for `HYPERHUMAN_HOST_IMMERSIVE`. Do not transmit secrets.\n\n#### Outbound events (player → your page)\n\nThe player posts these messages to its parent (`window.parent`) when framed. They are display/relay only - they never drive navigation, and you do not have to handle them (except `HYPERHUMAN_ORIENTATION_TOGGLE` if you want rotate-lock).\n\n| Message | When | Payload |\n|---------|------|---------|\n| `'hyperhumanPlayerReadyForData'` | Player is ready for the `HYPERHUMAN_EMBED_INIT` envelope (string literal). | - |\n| `CAST_STATE` | Active section or class chapter changes. | `{ type: 'CAST_STATE', exerciseName?, chapterIndex?, chapterCount?, chapterName? }` |\n| `HYPERHUMAN_SESSION_EVENT` | **Pre-built + `host` mode only.** Session lifecycle. | `{ type: 'HYPERHUMAN_SESSION_EVENT', event, workoutId?, progressSeconds? }` where `event` is `started` / `progress` / `paused` / `resumed` / `completed` / `ended`. Your backend owns the actual session API calls; these are relay only. |\n| `HYPERHUMAN_ORIENTATION_TOGGLE` | In-player **Rotate** could not lock orientation inside the iframe (typical cross-origin). | `{ type: 'HYPERHUMAN_ORIENTATION_TOGGLE', orientation: 'portrait' \\| 'landscape' }`. Host should enter immersive/fullscreen if needed, then `screen.orientation.lock(orientation)`. Free device rotate still works if you ignore this. |\n\n> **Portrait & music (player behavior):** Landscape clips letterbox to 16:9 with bands in portrait (not cover-crop). PulseMix music-off **pauses** background audio (`HTMLMediaElement.pause` + `muted`) — do not rely on `volume = 0` in custom hosts either; iOS/WebKit ignores volume. Workout pause always stops BGM. Music controls are hidden when `mixBgMusic` is false or `videoAudioMode` is `none`.\n\n---\n\n## Branded library embed (workouts and programs)\n\nBranded, responsive **library pages**: a searchable grid of your team's workouts or multi-week programs, hosted on the **member web app** (not the Content API origin in `https://content.api.hyperhuman.cc`). Visitors browse and open workouts without you building a catalog UI. There is **no API key in the URL** — access and visibility follow your org's member-app and publishing settings.\n\nIn [Hyperhuman Teams](https://team.hyperhuman.cc), open **Share** on **Manage Content** (workouts or programs) and use the **Embed page** tab to copy a snippet and toggle options; the same query contract is documented here for hand-built URLs.\n\n### Base URL\n\nProduction host: `https://member.hyperhuman.cc`. Your team may use a different host in white-label deployments — use the member app URL shown in Teams when copying the embed.\n\n### Paths\n\n| Surface | Path |\n|---------|------|\n| Workout library grid | `/workouts` |\n| Program library grid | `/plans` |\n\nAlways pass `orgId` (your organization id, same value as `{organizationId}` in Content API paths).\n\n### Query parameters\n\nOnly **non-default** options are serialized on the URL (short, readable links). Defaults match the Teams **Embed page** UI.\n\n| Param | Required | Type | Default | When it appears in the URL |\n|-------|----------|------|---------|----------------------------|\n| `orgId` | yes | string (24 hex chars) | - | Always. |\n| `showSearch` | no | boolean | `true` (search bar on) | Only as `showSearch=false` when the search bar is hidden. |\n| `showFilters` | no | boolean | `true` (filter chips on) | Only as `showFilters=false` when filters are hidden. |\n| `gridCols` | no | integer, one of 2, 3, or 4 | `3` | Only when not `3` (e.g. `gridCols=2` or `gridCols=4`). |\n| `playbackMode` | no | string | `overlay` | Only when `dedicated-page`. Default `overlay` opens playback in a lightbox over the embed; `dedicated-page` opens the workout in a **new browser tab** so the host page stays in place. |\n| `showDuration` | no | boolean | `true` (length badge on cards) | Only as `showDuration=false` when hidden. |\n| `showDifficulty` | no | boolean | `true` (difficulty badge on cards) | Only as `showDifficulty=false` when hidden. |\n\n### Iframe snippet\n\nThe Teams **Embed page** tab generates a container-filling iframe (your page controls the outer box size):\n\n```html\n<iframe width=\"100%\" height=\"100%\" src=\"MEMBER_APP_URL_AND_QUERY\" title=\"Your team title\" frameborder=\"0\" allow=\"encrypted-media; accelerometer; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>\n```\n\nReplace `MEMBER_APP_URL_AND_QUERY` with the full `https://member.hyperhuman.cc/workouts?...` or `https://member.hyperhuman.cc/plans?...` URL from Teams or built from the table above.\n\n### Examples\n\n**Workouts grid** — search and filters off, 2 columns, open in new tab, length and difficulty badges off:\n\n```html\n<iframe width=\"100%\" height=\"100%\" src=\"https://member.hyperhuman.cc/workouts?orgId=507f1f77bcf86cd799439011&showSearch=false&showFilters=false&gridCols=2&playbackMode=dedicated-page&showDuration=false&showDifficulty=false\" title=\"Your Team's Workouts\" frameborder=\"0\" allow=\"encrypted-media; accelerometer; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>\n```\n\n**Programs grid** — same options with 4 columns:\n\n```html\n<iframe width=\"100%\" height=\"100%\" src=\"https://member.hyperhuman.cc/plans?orgId=507f1f77bcf86cd799439011&showSearch=false&showFilters=false&gridCols=4&playbackMode=dedicated-page&showDuration=false&showDifficulty=false\" title=\"Your Team's Programs\" frameborder=\"0\" allow=\"encrypted-media; accelerometer; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>\n```\n\n### API parity\n\nTo drive the same catalogs from your own UI, use the Content API:\n\n- `GET /v1/orgs/{organizationId}/workouts` — list and filter workouts (query params such as `limit`, `q`, `sort`, `visibility`, `difficulty`, `categoryIds`, duration filters; advance via `links.next`; no `page` — see [AGENTS.md](https://content.api.hyperhuman.cc/AGENTS.md) section 4).\n- `GET /v1/orgs/{organizationId}/plans` — list and filter plans (e.g. `difficulties`, `goalIds`, `durationInWeeks`, `workoutsPerWeek`).\n\n---\n\n## Custom Interactive Workout Player\n\nFor full UI control, build your own player on top of the public API. The contract is small:\n\n| Endpoint | Returns |\n|----------|---------|\n| `GET /v1/workouts/{workoutId}` | Workout metadata (name, duration, difficulty, `videoAudioMode`, `mixBgMusic`). |\n| `GET /v1/workouts/{workoutId}/playlist?locale={locale}` | Ordered segments with media assets and timing. Drives the player. |\n| `GET /v1/workouts/{workoutId}/music` | Shuffled PulseMix pool for a **persisted** workout id (pre-signed URLs, ~7-day expiration). Not used by the JSON-receiver embed. Empty pool returns `200` with `tracks: []`. Gate playback on `videoAudioMode`/`mixBgMusic`. |\n\nThe full reference implementation - playlist manager, media controller, progress tracker, navigation handler, audio policy compliance - lives in the [Custom Player Guide](https://content.api.hyperhuman.cc/docs/guides/custom-player.md). It mirrors the Hyperhuman first-party players byte-for-byte and is the recommended starting point if you ship your own UX.\n\n### Audio Policy\n\nEach workout has a `videoAudioMode` (see `GET /v1/workouts/{workoutId}`) that controls which audio tracks the player must mix. Mirror this matrix exactly so your custom player matches the rendered MP4 export and the Hyperhuman first-party players byte-for-byte.\n\n| `videoAudioMode` | Voice instructions | Beeps / countdowns | Background music* |\n|-------------------|---------------------|--------------------|-------------------|\n| `full` (default) | yes | yes | yes |\n| `instructionsOnly` | yes | no | yes |\n| `beepsOnly` | no | yes | yes |\n| `none` | no | no | no |\n\n\\* Background music is additionally gated by the workout's `mixBgMusic` flag - if `mixBgMusic` is `false`, music never plays regardless of `videoAudioMode`.\n\n```javascript\n// Reference snippet - matches backend export pipeline 1:1.\nconst shouldIncludeVoiceInstructions = (mode) =>\n  mode === undefined || mode === 'full' || mode === 'instructionsOnly';\n\nconst shouldIncludeBeeps = (mode) =>\n  mode === undefined || mode === 'full' || mode === 'beepsOnly';\n\nconst shouldIncludeBackgroundMusic = (mode, mixBgMusic) =>\n  mode !== 'none' && (mixBgMusic ?? true);\n```\n\n---\n\n## Localization\n\n**Supported locales (16):** `en-US`, `en-GB`, `en-AU`, `fr-FR`, `de-DE`, `es-ES`, `it-IT`, `pt-PT`, `he-IL`, `ro-RO`, `cs-CZ`, `fi-FI`, `lt-LT`, `nl-NL`, `pl-PL`, `ar-XA`.\n\n```bash\ncurl 'https://content.api.hyperhuman.cc/v1/workouts/{workoutId}?locale=fr-FR' \\\n  -H 'X-Api-Key: YOUR_API_KEY'\n```\n\nLocalizes: workout titles and descriptions, exercise names, equipment, muscle groups, player metadata, and audio guidance (where enabled).\n\n**AI generate** (`POST .../workouts/generate`, `POST .../plans/generate`): pass optional body `\"locale\": \"fr-FR\"`. Returns additive `nameTranslations` (workout) or `nameTranslations` + `descriptionTranslations` (plan), plus `*Localized` fields. Legacy English fields unchanged. Invalid locale → `400`. Plan translation maps are persisted — `GET /v1/plans/{id}?locale=fr-FR` returns resolved top-level name/description.\n\n#### Fallback Behavior\n\n| Endpoint family | Behavior when locale is unsupported |\n|-----------------|-------------------------------------|\n| Metadata, workout details, playlist (text + voice cues) | Falls back to English so playback never breaks. |\n| AI generate (`POST .../workouts/generate`, `POST .../plans/generate`) | Returns **`400 BadRequest`** (`Unsupported locale: ...`). |\n| Pre-rendered video / audio exports (`/export/...`) | Returns `404` if no rendered asset exists in the requested locale. Re-request with `locale=en-US`, or trigger an export job for the missing locale. |\n\n---\n\n## Authentication\n\nAdd to all requests:\n\n```\nX-Api-Key: YOUR_API_KEY\n```\n\nGet your key: [team.hyperhuman.cc/settings?tab=integrations](https://team.hyperhuman.cc/settings?tab=integrations).\n\nA handful of end-user-scoped endpoints (`/me/...`) additionally accept a JWT `Authorization: Bearer <token>` header in place of, or in addition to, the API key. The OpenAPI spec marks these explicitly with `bearer` security.\n\n---\n\n## Complete API Workflows\n\n### Workflow 1: Browse and play pre-built content\n```\n1. GET /v1/workouts/metadata             -> categories and filters\n2. GET /v1/orgs/{organizationId}/workouts -> browse the library\n3. GET /v1/workouts/{workoutId}           -> workout details\n4. GET /v1/workouts/{workoutId}/playlist  -> video segments\n5. (optional) GET /v1/workouts/{workoutId}/music         -> background music\n6. (optional) POST /v1/workouts/{workoutId}/sessions/start -> track progress\n```\n\n### Workflow 2: Recommend a library workout (quiz → curated match)\n```\n1. Map quiz / profile answers → endUserProfileDetails (age, fitnessLevels, equipment, …)\n2. POST /v1/orgs/{organizationId}/workouts/recommend      -> ranked library workouts\n3. Pick a returned workout id\n4. GET  /v1/workouts/{workoutId}                          -> details (incl. videoAudioMode, mixBgMusic)\n5. GET  /v1/workouts/{workoutId}/playlist                 -> segments for custom player\n   or embed /embed/workout/{workoutId}                   -> Pre-built Workout iframe\n6. (optional) GET /v1/workouts/{workoutId}/music          -> PulseMix tracks (persisted id only)\n7. (optional) sessions/start → PATCH progress → sessions/complete or sessions/end → feedback\n```\n\n### Workflow 3: AI-generated workout (ephemeral JSON)\n```\n1. GET  /v1/workouts/metadata                              -> category IDs\n2. POST /v1/orgs/{organizationId}/workouts/generate        -> ephemeral JSON (no top-level id; optional body locale)\n3. Store the returned structure if you need to replay later\n4. iframe /embed/workout-json-receiver?organizationId=...  -> wait for hyperhumanPlayerReadyForData\n5. postMessage HYPERHUMAN_EMBED_INIT { apiKey, workout }   -> player calls GET /v1/video-asset/{exerciseId} per exercise\n   or build a custom player from instances[] + GET /v1/video-asset/{id}\n6. Do NOT call /playlist, /music, or sessions/feedback for this response — those need a persisted workout id\n```\n\n### Workflow 4: AI adaptation (evolve existing content)\n```\nWorkout adapt (ephemeral JSON — same playback as Workflow 3):\n1. GET  /v1/orgs/{organizationId}/workouts                            -> pick a base workout\n2. POST /v1/orgs/{organizationId}/workouts/{workoutId}/adapt          -> { name, instances[], ... } (no top-level workout id)\n3. Play via JSON receiver or custom player; do NOT call /playlist or /music on a synthetic id\n\nPlan adapt (persisted program — endUserProfileId required):\n1. POST /v1/orgs/{organizationId}/plans/{planId}/adapt\n     body includes endUserProfileId + endUserProfileDetails + workoutSources\n     -> adapted program with id (400 if endUserProfileId omitted)\n2. Store returned id; retrieve with GET /v1/plans/{id} and .../workouts\n   Active enrollment for that user → next workout slot only; else full future schedule\n```\n\n> The source `{workoutId}` / `{planId}` must belong to `{organizationId}`. Adapting content that is not part of your organization returns `404`.\n\n### Workflow 5: Multi-week training programs\n```\n1. GET  /v1/plans/metadata                                -> plan goals and difficulties\n2. POST /v1/orgs/{organizationId}/plans/generate          -> create multi-week plan (optional body locale)\n     Include endUserProfileDetails.endUserId to receive a persisted plan id\n   OR POST .../plans/recommend                            -> pick an existing library plan\n3. If generate returned id: store it; use nameTranslations / descriptionTranslations on the response\n4. GET  /v1/plans/{planId}?locale=fr-FR                   -> localized plan (only when you have a persisted id)\n5. GET  /v1/plans/{planId}/workouts                       -> ordered workouts (no per-item week field)\n6. Derive week N from durationInWeeks × workoutsPerWeek and array order\n   OR use end-user active plan: currentWeekNumber + .../plans/active/progress (positionInPlan)\n7. For each persisted workout: follow Workflow 2 from step 4.\n```\n\n### Workflow 6: End-user governance (B2B lifecycle)\n```\n1. GET  /v1/orgs/{organizationId}/endusers          -> list users\n2. POST /v1/orgs/{organizationId}/endusers/invite   -> add new users\n3. GET  /v1/orgs/{organizationId}/endusers/find     -> check user status\n4. PUT  /v1/orgs/{organizationId}/endusers/suspend  -> temporarily disable access\n5. PUT  /v1/orgs/{organizationId}/endusers/reactivate -> restore access\n6. DELETE /v1/orgs/{organizationId}/endusers        -> remove user permanently\n```\n\n### Workflow 7: Daily insights and re-engagement\n```\n1. (optional) POST /v1/orgs/{organizationId}/endusers/{endUserId}/insights/health-data\n   -> push your own health data (activity/sleep/steps/body/heart_rate/hydration/oxygenation/scores;\n      max 50 entries; always 200 - check per-entry results; idempotent on (dataType, externalId))\n2. (optional) POST /v1/orgs/{organizationId}/endusers/{endUserId}/nutrition/log\n   -> log meals (caloriesKcal/proteinG/carbsG/fatG; externalId = idempotent replace + DELETE support)\n3. GET /v1/orgs/{organizationId}/endusers/{endUserId}/insights/digest?date=2026-04-20T00:00:00.000Z\n   -> 3-5 pillar summaries + todaysFocus + dataCompleteness (reflects pushed data)\n4. GET /v1/orgs/{organizationId}/endusers/{endUserId}/insights/pillars/{pillarType}\n   -> drill-down for any pillar (health_pulse, training, recovery, movement, nutrition, body)\nCorrections: re-POST the same externalId, or DELETE .../insights/health-data/{dataType}/{externalId}\n             and DELETE .../nutrition/log/{externalId}\n```\n\n---\n\n## Error Handling\n\n### Common HTTP Status Codes\n\n| Code | Meaning | Common Causes | How to Handle |\n|------|---------|----------------|---------------|\n| **200** | Success | Request completed successfully (includes AI recommend/generate/adapt) | Continue normal flow |\n| **201** | Created | Resource created (e.g. session start, enduser invite, chat create, autopilot/social-publish create) | Extract ID from response |\n| **400** | Bad Request | Invalid query/path parameters, malformed JSON body, or request validation failure | Check request body and parameters. Field-level validation failures use `error.code` = `ValidationError` with `error.details[]` populated (see below) |\n| **401** | Unauthorized | Missing, malformed or invalid API key (`X-Api-Key` header) | Verify the API key is sent on every request |\n| **403** | Forbidden | Valid API key, but not authorized for the requested organization or resource | Check that the API key belongs to the same org as the resource being accessed |\n| **404** | Not Found | Resource doesn't exist, was deleted, or the requested locale variant has not been rendered yet (export endpoints) | Verify IDs; for exports, retry without `locale` or with `locale=en-US` |\n| **409** | Conflict | Resource already exists (e.g. active session) or state transition not allowed | Reconcile against current state before retrying |\n| **422** | Unprocessable Entity | Request is well-formed but a business rule blocks it (e.g. activating a social-publish schedule with no connected accounts for the target platforms). Carries a human-readable `error.message`; `error.details` is not populated | Resolve the precondition described in `error.message`, then retry |\n| **429** | Too Many Requests | Hourly or daily rate limit exceeded (see headers below) | Implement exponential backoff; respect `X-RateLimit-Reset` |\n| **500** | Internal Server Error | Server-side issue | Retry with exponential backoff |\n\n### Error Response Format\n\nEvery non-2xx response is wrapped in a single `error` envelope. The body is always JSON, even when the failing endpoint normally returns `text/plain` (e.g. stream URL endpoints).\n\n```json\n{\n  \"error\": {\n    \"code\": \"ValidationError\",\n    \"message\": \"ValidationError\",\n    \"target\": \"GetUserDigestQuery\",\n    \"details\": [\n      {\n        \"code\": \"ConstraintError\",\n        \"message\": \"date must be a ISOString\",\n        \"target\": \"date\"\n      }\n    ]\n  }\n}\n```\n\nField-level validation failures (query, path, or body) return **HTTP 400** with `error.code` = `ValidationError`. `error.target` is the DTO name and each `error.details[].code` is `ConstraintError`. Business-rule failures use the status-mapped code instead (e.g. `422` -> `UnprocessableEntity`, `409` -> `Conflict`) with a plain `error.message` and no `details`.\n\n| Field | Type | Always present | Notes |\n|-------|------|----------------|-------|\n| `error.code` | string | yes | A stable machine-readable identifier from the closed enum below. Switch on this - never on `message`. |\n| `error.message` | string | yes | Human-readable English summary. Suitable for logs; not for end-user UI. |\n| `error.target` | string | no | The primary field/parameter related to the overall error (e.g. `requestBody`, `workoutId`). |\n| `error.details` | array | no | Field-level breakdown - populated for `400 ValidationError` responses (each item `code` is `ConstraintError`) and entity-not-found errors. Each item has `code`, `message`, and optional `target`. |\n\n#### Stable error codes\n\n| HTTP status | `error.code` |\n|-------------|----------------|\n| 400 | `BadRequest` or `ValidationError` (field validation, with `error.details[]`) |\n| 401 | `Unauthorized` |\n| 403 | `Forbidden` |\n| 404 | `NotFound` |\n| 405 | `MethodNotAllowed` |\n| 408 | `RequestTimeout` |\n| 409 | `Conflict` |\n| 410 | `Gone` |\n| 413 | `PayloadTooLarge` |\n| 415 | `UnsupportedMediaType` |\n| 422 | `UnprocessableEntity` |\n| 500 | `InternalServerError` |\n| 501 | `NotImplemented` |\n| 502 | `BadGateway` |\n| 503 | `ServiceUnavailable` |\n| 504 | `GatewayTimeout` |\n\n> Treat the `error.code` enum as the contract. `error.message` wording can change between releases.\n\n### Best Practices\n\n**Do:**\n- Always check HTTP status codes\n- Implement exponential backoff for 429/500 errors\n- Log error details for debugging\n- Provide user-friendly error messages\n- Handle network timeouts gracefully\n\n**Don't:**\n- Ignore error responses\n- Retry immediately on all errors\n- Expose internal error details to users\n- Make requests without proper error handling\n\n### Retry Strategy\n\n```javascript\nconst retryWithBackoff = async (fn, maxRetries = 3) => {\n  for (let i = 0; i < maxRetries; i++) {\n    try {\n      return await fn();\n    } catch (error) {\n      if (error.status === 429 || error.status >= 500) {\n        const delay = Math.pow(2, i) * 1000;\n        await new Promise(resolve => setTimeout(resolve, delay));\n        continue;\n      }\n      throw error;\n    }\n  }\n  throw new Error('Max retries exceeded');\n};\n```\n\n---\n\n## Rate Limiting\n\nEvery response carries:\n\n```\nX-RateLimit-Limit: 1000\nX-RateLimit-Remaining: 999\nX-RateLimit-Reset: 1640995200\n```\n\n- `X-RateLimit-Limit` - Maximum requests per window\n- `X-RateLimit-Remaining` - Requests remaining in current window\n- `X-RateLimit-Reset` - Unix timestamp when the window resets\n\n**Note:** AI and full-video endpoints (workout/plan generate, recommend, adapt, insights, chat, video generation, full video export) count as **10x** API calls toward your limits. The health-data batch push and nutrition log write endpoints count as **1x** per request (the batch is capped at 50 entries instead).\n\n**When rate limited (429):**\n1. Stop making requests immediately\n2. Wait until reset time (check `X-RateLimit-Reset`)\n3. Implement exponential backoff\n4. Consider upgrading your plan for higher limits\n\n**Best practices:**\n- Monitor remaining requests via `GET /v1/orgs/{organizationId}/stats`\n- Cache and reuse generated **plan ids** and library **workout ids** instead of regenerating on every page load\n- Prefer Recommend over Generate when your library already has the right content\n\n**Billing / quotas:** API access and request caps are part of your Hyperhuman subscription (see [Pricing](https://hyperhuman.cc/pricing)). You are not billed per individual API call in the docs sense — usage is governed by the hourly/daily limits above (with AI ops at 10x weight).\n\n---\n\n## Hyperhuman product surfaces\n\nThe Content API is one surface in a wider platform. If a capability you need isn't in this API, it likely lives in one of these:\n\n- **Teams workspace** ([team.hyperhuman.cc](https://team.hyperhuman.cc)) - production hub for the Smart Library, AI Workout Builder, Content Autopilot, Social Publishing, and team analytics. This is where API keys are issued.\n- **Hyperhuman Club** ([hyperhuman.cc/club](https://hyperhuman.cc/club)) - white-label branded member app for iOS and Android. Plug-and-play health HQ that companies launch in weeks instead of months.\n- **Wix widget** ([hyperhuman.cc/wix](https://hyperhuman.cc/wix)) - embeddable workout library and player for Wix sites.\n- **Pricing** ([hyperhuman.cc/pricing](https://hyperhuman.cc/pricing)) - plan-dependent quotas and module availability.\n- **Book a demo** ([hyperhuman.cc/book-a-demo](https://hyperhuman.cc/book-a-demo)) - if you're scoping a custom integration.\n\n---\n\n## Resources\n\n- **OpenAPI spec (JSON):** [https://content.api.hyperhuman.cc/openapi.json](https://content.api.hyperhuman.cc/openapi.json)\n- **OpenAPI spec (YAML):** [https://content.api.hyperhuman.cc/openapi.yaml](https://content.api.hyperhuman.cc/openapi.yaml)\n- **Modern reference (Scalar):** [https://content.api.hyperhuman.cc/docs](https://content.api.hyperhuman.cc/docs)\n- **Classic explorer (Swagger UI):** [https://content.api.hyperhuman.cc/docs/api-explorer](https://content.api.hyperhuman.cc/docs/api-explorer)\n- **LLM bundle:** [https://content.api.hyperhuman.cc/llms-full.txt](https://content.api.hyperhuman.cc/llms-full.txt)\n- **Agent guide:** [https://content.api.hyperhuman.cc/AGENTS.md](https://content.api.hyperhuman.cc/AGENTS.md)\n- **Custom player guide:** [https://content.api.hyperhuman.cc/docs/guides/custom-player.md](https://content.api.hyperhuman.cc/docs/guides/custom-player.md)\n- **Support:** support@hyperhuman.cc\n- **Website:** [hyperhuman.cc](https://hyperhuman.cc)\n","version":"1.0","contact":{}},"tags":[{"name":"workouts"},{"name":"plans"},{"name":"library-exercises"},{"name":"library-stock-exercises"},{"name":"exercise-groups"},{"name":"ai-generation"},{"name":"ai-recommendation"},{"name":"ai-adaptation"},{"name":"organization"},{"name":"social"},{"name":"content-autopilot"},{"name":"social-publish"},{"name":"endusers-ai-insights"},{"name":"endusers-ai-chat"},{"name":"endusers-nutrition"},{"name":"endusers-plans"},{"name":"endusers-management"}],"servers":[{"url":"https://content.api.hyperhuman.cc"}],"components":{"securitySchemes":{"X-Api-Key":{"type":"apiKey","in":"header","name":"X-Api-Key","description":"Choose a plan that fits your expected API usage. Once activated, you'll receive your content key and organization ID in the [integrations tab](https://team.hyperhuman.cc/settings?tab=integrations)."}},"schemas":{"ApiErrorDetails":{"type":"object","properties":{"code":{"type":"string","description":"A specific error code related to this detail. For request validation failures this is 'ConstraintError'.","example":"ConstraintError"},"message":{"type":"string","description":"A human-readable message explaining this specific error detail.","example":"email must be a valid email address"},"target":{"type":"string","description":"The specific field or parameter that caused this error detail, if applicable.","example":"email"}},"required":["code","message"]},"ApiError":{"type":"object","properties":{"code":{"type":"string","description":"A general error code classifying the error.","example":"BadRequest"},"message":{"type":"string","description":"A human-readable message summarizing the overall error.","example":"The request is invalid."},"target":{"type":"string","description":"The primary field or parameter related to the overall error, if applicable.","example":"requestBody"},"details":{"description":"An array of specific error details, often related to validation failures on individual fields.","type":"array","items":{"$ref":"#/components/schemas/ApiErrorDetails"}}},"required":["code","message"]},"ErrorResponse":{"type":"object","properties":{"error":{"description":"Contains the details of the error that occurred.","allOf":[{"$ref":"#/components/schemas/ApiError"}]}},"required":["error"]},"TrainerRef":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the trainer.","example":"trainer-jane-doe"},"name":{"type":"string","description":"Display name of the trainer.","example":"Jane Doe"}},"required":["id","name"]},"WorkoutAudio":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the audio asset","example":"68b0557adbaf49d17ee429bb"},"createdAt":{"format":"date-time","type":"string","description":"Timestamp when the audio was created","example":"2025-08-28T13:11:22.242Z"},"isStock":{"type":"boolean","description":"Whether this is a stock audio asset","example":false},"assetUri":{"type":"string","description":"Pre-signed URL to access the audio file","format":"url","example":"https://example-bucket.s3.eu-central-1.amazonaws.com/a/example-audio.m4a"},"scriptText":{"type":"string","description":"Script text for the audio","example":"Welcome to your workout!"},"type":{"type":"string","description":"Type of audio asset","example":"workoutIntro"},"locale":{"type":"string","description":"Locale/language of the audio","example":"en-US"},"duration":{"type":"number","description":"Duration of the audio in seconds","example":0.875},"status":{"type":"string","description":"Processing status of the audio","example":"generated"}},"required":["id","createdAt","isStock","assetUri","type","locale","duration","status"]},"VideoLinks":{"type":"object","properties":{"url":{"type":"string","description":"Time-limited AWS S3 presigned HTTPS URL to progressive MP4 (typically 1080p). Valid ~7 days — re-fetch via the API; do not treat as a durable identifier. Not HLS/DASH/ABR.","format":"url","example":"https://hhcontent.s3.eu-central-1.amazonaws.com/example/workout-123.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=604800&X-Amz-Signature=..."},"poster":{"type":"object","description":"URL of a poster image to display before video playback.","format":"url","example":"https://assets.hyperhuman.cc/video/workout-123/poster.jpg"},"thumbnail":{"type":"object","description":"URL of a thumbnail image representing the video.","format":"url","example":"https://assets.hyperhuman.cc/video/workout-123/thumb.jpg"},"loop":{"type":"number","description":"Playback looping behavior hint. 0 = no loop, -1 = infinite loop, >0 = specific number of loops (if supported by player). Default is typically 0 or 1 depending on context.","example":-1,"default":0}},"required":["url"]},"Category":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the category.","example":"cat-hiit-123"},"name":{"type":"string","description":"Display name of the category. Localized based on locale query parameter.","example":"HIIT"}},"required":["id","name"]},"Equipment":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the equipment item.","example":"eq-dumbbell-abc"},"name":{"type":"string","description":"Display name of the equipment. Localized based on locale query parameter.","example":"Dumbbell"}},"required":["id","name"]},"MusicPlaylistLink":{"type":"object","properties":{"url":{"type":"string","description":"URL of the music playlist on an external platform (e.g., Spotify, Apple Music).","format":"url","example":"https://open.spotify.com/playlist/37i9dQZF1DX..."}},"required":["url"]},"MusicPlaylists":{"type":"object","properties":{"spotify":{"description":"Spotify music playlist","allOf":[{"$ref":"#/components/schemas/MusicPlaylistLink"}]},"youtube":{"description":"Youtube music playlist","allOf":[{"$ref":"#/components/schemas/MusicPlaylistLink"}]},"appleMusic":{"description":"Apple Music playlist","allOf":[{"$ref":"#/components/schemas/MusicPlaylistLink"}]},"amazonMusic":{"description":"Amazon Music playlist","allOf":[{"$ref":"#/components/schemas/MusicPlaylistLink"}]}}},"ShareLink":{"type":"object","properties":{"url":{"type":"string","description":"URL that can be shared to provide access or reference to the resource.","format":"url","example":"https://share.hyperhuman.cc/w/a1b2c3d4"}},"required":["url"]},"ImageLinks":{"type":"object","properties":{"url":{"type":"string","description":"URL of the primary/original image.","format":"url","example":"https://assets.hyperhuman.cc/images/workout-cover-123.jpg"},"thumbnail":{"type":"object","description":"URL of a smaller (thumbnail) version of the image.","format":"url","example":"https://assets.hyperhuman.cc/images/workout-thumb-123.jpg"}},"required":["url"]},"Organization":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the organization.","example":"org-fitness-first"},"name":{"type":"string","description":"Display name of the organization.","example":"Fitness First Gym"},"logo":{"description":"Links to the organization's logo images (if available).","allOf":[{"$ref":"#/components/schemas/ImageLinks"}]}},"required":["id","name"]},"MuscleGroupPercentage":{"type":"object","properties":{"muscleGroupId":{"type":"string","description":"Unique identifier of the muscle group","example":"507f1f77bcf86cd799439011"},"muscleGroupName":{"type":"string","description":"Localized name of the muscle group","example":"Chest"},"percentage":{"type":"number","description":"Percentage of workout focused on this muscle group","minimum":0,"maximum":100,"example":35.5}},"required":["muscleGroupId","muscleGroupName","percentage"]},"Workout":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier (UUID) for the workout.","example":"12ab3efd45c67c1234566cd1"},"createdAt":{"format":"date-time","type":"string","description":"Timestamp when the workout was created.","example":"2023-10-26T10:00:00.000Z"},"updatedAt":{"format":"date-time","type":"string","description":"Timestamp when the workout was last updated.","example":"2023-10-27T11:30:00.000Z"},"trainer":{"description":"Reference to the trainer associated with the workout.","allOf":[{"$ref":"#/components/schemas/TrainerRef"}]},"name":{"type":"string","description":"Display name of the workout. Localized based on locale query parameter.","example":"Full Body Blast"},"description":{"type":"string","description":"Detailed description of the workout, potentially including goals and target audience. Localized based on locale query parameter.","example":"A 30-minute high-intensity interval training session designed to improve cardiovascular fitness and strength."},"audioIntro":{"description":"Localized workout introduction audio. Selected based on locale query parameter and user preferences.","allOf":[{"$ref":"#/components/schemas/WorkoutAudio"}]},"audioOutro":{"description":"Localized workout outro audio. Selected based on locale query parameter and user preferences.","allOf":[{"$ref":"#/components/schemas/WorkoutAudio"}]},"duration":{"type":"number","description":"Estimated workout duration in seconds.","example":1800},"difficulty":{"type":"string","enum":["beginner","intermediate","advanced"],"description":"Raw difficulty enum value (beginner|intermediate|advanced). Clients should map to localized strings. Null if not specified.","example":"beginner"},"preview":{"description":"Links to the preview video (presigned progressive MP4 URL, ~7-day expiry). Null if no preview is available.","allOf":[{"$ref":"#/components/schemas/VideoLinks"}]},"rating":{"type":"number","description":"Average user rating (e.g., 1-5). Null if not rated.","example":4.5},"visibility":{"type":"string","enum":["private","public"],"description":"Visibility level of the workout.","example":"public"},"locked":{"type":"boolean","description":"Indicates if the workout requires a subscription or specific entitlement to access.","example":false},"mixBgMusic":{"type":"boolean","description":"Whether to mix background music with workout audio. If true, background music will be played alongside exercise instructions.","example":true},"presentationStyle":{"type":"string","enum":["full","minimal","essential","noOverlays"],"description":"Video overlay presentation style. Controls which UI elements are shown during workout playback.","example":"full"},"skipWorkoutPreview":{"type":"boolean","description":"If true, skip workout preview/intro segment in interactive player","example":false},"skipWorkoutCompletionScreen":{"type":"boolean","description":"If true, skip workout completion/outro screen in interactive player","example":false},"videoAudioMode":{"type":"string","enum":["full","instructionsOnly","beepsOnly","none"],"description":"Audio policy for interactive playback and full-workout export. Controls which audio components are included (voice, beeps, background music).","example":"full"},"categories":{"description":"List of categories associated with the workout (e.g., HIIT, Strength, Yoga). Category names are localized based on locale query parameter.","type":"array","items":{"$ref":"#/components/schemas/Category"}},"allowAssessment":{"type":"boolean","description":"Whether this workout supports AI assessment mode","example":false},"assessmentType":{"type":"string","enum":["mobility_baseline","glp1_muscle_guard","movement_assessment","overall_assessment","learning_tutorial","learning_practice"],"description":"Type of assessment supported (if allowAssessment is true)","example":"mobility_baseline","nullable":true},"equipment":{"description":"List of equipment required or recommended for the workout. Equipment names are localized based on locale query parameter.","type":"array","items":{"$ref":"#/components/schemas/Equipment"}},"musicPlaylists":{"description":"Links to suggested music playlists on various platforms (Spotify, Apple Music, etc.).","allOf":[{"$ref":"#/components/schemas/MusicPlaylists"}]},"shareLink":{"description":"A shareable link for the workout.","allOf":[{"$ref":"#/components/schemas/ShareLink"}]},"organization":{"description":"Reference to the organization that owns/published this workout, if applicable.","allOf":[{"$ref":"#/components/schemas/Organization"}]},"video":{"description":"Links to the full workout video when present on the document (presigned progressive MP4). Prefer GET /export/video/stream_url for the rendered full-workout export URL.","allOf":[{"$ref":"#/components/schemas/VideoLinks"}]},"muscleGroupPercentages":{"description":"Percentage distribution of muscle groups in this workout, sorted by highest percentage first","type":"array","items":{"$ref":"#/components/schemas/MuscleGroupPercentage"}}},"required":["id","createdAt","updatedAt","trainer","name","description","duration","visibility","locked","categories","equipment","shareLink","muscleGroupPercentages"]},"WorkoutResponse":{"type":"object","properties":{"data":{"description":"Contains the detailed workout object.","allOf":[{"$ref":"#/components/schemas/Workout"}]}},"required":["data"]},"PageLinks":{"type":"object","properties":{"next":{"type":"string","description":"URL of the next page. Missing if there is no next page.","example":"https://content.api.hyperhuman.cc/resource/next-page-link"},"total":{"type":"number","description":"Total number of items available across all pages.","example":100}}},"WorkoutListItem":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier (UUID) for the workout.","example":"12ab3efd45c67c1234566cd1"},"createdAt":{"format":"date-time","type":"string","description":"Timestamp when the workout was created.","example":"2023-10-26T10:00:00.000Z"},"updatedAt":{"format":"date-time","type":"string","description":"Timestamp when the workout was last updated.","example":"2023-10-27T11:30:00.000Z"},"trainer":{"description":"Reference to the trainer associated with the workout.","allOf":[{"$ref":"#/components/schemas/TrainerRef"}]},"name":{"type":"string","description":"Display name of the workout. Localized based on locale query parameter.","example":"Full Body Blast"},"description":{"type":"string","description":"Detailed description of the workout, potentially including goals and target audience. Localized based on locale query parameter.","example":"A 30-minute high-intensity interval training session designed to improve cardiovascular fitness and strength."},"audioIntro":{"description":"Localized workout introduction audio. Selected based on locale query parameter and user preferences.","allOf":[{"$ref":"#/components/schemas/WorkoutAudio"}]},"audioOutro":{"description":"Localized workout outro audio. Selected based on locale query parameter and user preferences.","allOf":[{"$ref":"#/components/schemas/WorkoutAudio"}]},"duration":{"type":"number","description":"Estimated workout duration in seconds.","example":1800},"difficulty":{"type":"string","enum":["beginner","intermediate","advanced"],"description":"Raw difficulty enum value (beginner|intermediate|advanced). Clients should map to localized strings. Null if not specified.","example":"beginner"},"preview":{"description":"Links to the preview video (presigned progressive MP4 URL, ~7-day expiry). Null if no preview is available.","allOf":[{"$ref":"#/components/schemas/VideoLinks"}]},"rating":{"type":"number","description":"Average user rating (e.g., 1-5). Null if not rated.","example":4.5},"visibility":{"type":"string","enum":["private","public"],"description":"Visibility level of the workout.","example":"public"},"locked":{"type":"boolean","description":"Indicates if the workout requires a subscription or specific entitlement to access.","example":false},"mixBgMusic":{"type":"boolean","description":"Whether to mix background music with workout audio. If true, background music will be played alongside exercise instructions.","example":true},"presentationStyle":{"type":"string","enum":["full","minimal","essential","noOverlays"],"description":"Video overlay presentation style. Controls which UI elements are shown during workout playback.","example":"full"},"skipWorkoutPreview":{"type":"boolean","description":"If true, skip workout preview/intro segment in interactive player","example":false},"skipWorkoutCompletionScreen":{"type":"boolean","description":"If true, skip workout completion/outro screen in interactive player","example":false},"videoAudioMode":{"type":"string","enum":["full","instructionsOnly","beepsOnly","none"],"description":"Audio policy for interactive playback and full-workout export. Controls which audio components are included (voice, beeps, background music).","example":"full"},"categories":{"description":"List of categories associated with the workout (e.g., HIIT, Strength, Yoga). Category names are localized based on locale query parameter.","type":"array","items":{"$ref":"#/components/schemas/Category"}},"allowAssessment":{"type":"boolean","description":"Whether this workout supports AI assessment mode","example":false},"assessmentType":{"type":"string","enum":["mobility_baseline","glp1_muscle_guard","movement_assessment","overall_assessment","learning_tutorial","learning_practice"],"description":"Type of assessment supported (if allowAssessment is true)","example":"mobility_baseline","nullable":true}},"required":["id","createdAt","updatedAt","trainer","name","description","duration","visibility","locked","categories"]},"WorkoutListResponse":{"type":"object","properties":{"links":{"description":"Pagination envelope. Use `links.next` to fetch the next page; `links.total` is the count across all pages and is omitted on endpoints where it is too expensive to compute.","allOf":[{"$ref":"#/components/schemas/PageLinks"}]},"data":{"type":"array","items":{"$ref":"#/components/schemas/WorkoutListItem"}},"explanation":{"type":"string","description":"Explanation for how this list was filtered or sorted"}},"required":["links","data"]},"EndUserProfileDetailsDto":{"type":"object","properties":{"age":{"type":"number","description":"User age. Maps to age groups (16-24: Young, 25-34: Young Adult, 35-44: Early Middle Age, 45-54: Mid Life, 55-64: Late Middle Age, 65-74: Early Senior, 75+: Senior) for appropriate exercise intensity selection.","minimum":16,"maximum":99,"example":32},"gender":{"type":"string","enum":["male","female","other"],"description":"User gender. Influences coach gender matching preference (not guaranteed match).","example":"female"},"fitnessLevels":{"type":"array","description":"User fitness levels. Only the FIRST level is used for exercise difficulty selection. Provide only one for clarity. AI may adjust actual workout difficulty based on exercise availability and safety considerations.","example":["intermediate"],"items":{"type":"string","enum":["beginner","intermediate","advanced"]}},"goalIds":{"description":"Goal IDs the user is interested in. Accepted on the request; may be ignored by the current ranking pipeline.","example":["63c92926f920a9005c4e619c"],"type":"array","items":{"type":"string"}},"trainingDaysPerWeek":{"type":"number","description":"Number of days per week the user wants to train. Accepted on the request; may be ignored by the current ranking pipeline.","minimum":1,"maximum":7,"example":4},"preferredEquipmentCategoryIds":{"description":"Preferred equipment category IDs. Used as guidance (not strict filter). AI may include bodyweight exercises for safety. Use GET /v1/workouts/equipment/metadata to fetch available equipment categories.","example":["67deb36a6a5e49797c122f56","67deb3696a5e49797c122f55"],"type":"array","items":{"type":"string"}},"endUserId":{"type":"string","description":"End user profile ID for personalization. When provided, user context (workout history, digest, metrics) is used for AI workout generation and recommendations. Must belong to the same organization as the request.","example":"64e3bca9d1b7e600141a9712"}}},"WorkoutRecommendationRequestDto":{"type":"object","properties":{"endUserProfileDetails":{"description":"Detailed user profile information for personalized recommendations","allOf":[{"$ref":"#/components/schemas/EndUserProfileDetailsDto"}]},"locale":{"type":"string","description":"Preferred BCP-47 locale for recommendation text when the stack supports it.","example":"en-US"}}},"RecommendedWorkoutDto":{"type":"object","properties":{"id":{"type":"string","description":"Workout ID"},"name":{"type":"string","description":"Workout name"},"description":{"type":"string","description":"Workout description"},"duration":{"type":"number","description":"Workout duration in seconds"},"difficulty":{"type":"string","enum":["beginner","intermediate","advanced"]},"thumbnailUrl":{"type":"string","description":"URL to workout thumbnail image"},"recommendation":{"type":"string","description":"Reasoning for this recommendation"},"categories":{"description":"Workout categories","items":{"type":"array"},"type":"array"},"preview":{"description":"Preview video (playable URL when available). url is empty when only a thumbnail image exists.","allOf":[{"$ref":"#/components/schemas/VideoLinks"}]}},"required":["id","name","description","duration","difficulty","thumbnailUrl","recommendation","categories"]},"WorkoutRecommendationResponseDto":{"type":"object","properties":{"workouts":{"description":"List of recommended workouts (max 12)","type":"array","items":{"$ref":"#/components/schemas/RecommendedWorkoutDto"}},"reasoning":{"type":"string","description":"Overall explanation for the recommendation strategy used"}},"required":["workouts","reasoning"]},"WorkoutDurationOptionsDto":{"type":"object","properties":{"minMinutes":{"type":"number","description":"Minimum workout duration in minutes","minimum":5,"example":5},"maxMinutes":{"type":"number","description":"Maximum workout duration in minutes","minimum":5,"example":30}}},"WorkoutGenerationRequestDto":{"type":"object","properties":{"endUserProfileDetails":{"description":"Detailed user profile information for personalized workout generation.","allOf":[{"$ref":"#/components/schemas/EndUserProfileDetailsDto"}]},"exerciseSources":{"type":"array","description":"Preferred source(s) of exercises. Use only `premium_stock` for consistent quality, or `team_exercises` for brand consistency. Avoid mixing `free_stock` with `premium_stock` for visual consistency.","example":["premium_stock"],"items":{"type":"string","enum":["premium_stock","free_stock","team_exercises"]}},"durationOptions":{"description":"Preferred workout duration range in minutes. You can specify minimum and maximum duration to generate workouts within a specific time range.","example":{"minMinutes":5,"maxMinutes":30},"allOf":[{"$ref":"#/components/schemas/WorkoutDurationOptionsDto"}]},"categoryId":{"type":"string","description":"Workout category ID to theme the workout. Use GET /v1/workouts/metadata to fetch available categories (HIIT, Strength, Mobility, Cardio, etc.).","example":"615aa3f0dbe7140012c59e94"},"muscleGroupIds":{"description":"Muscle group IDs to focus on during the workout. The workout will be generated with emphasis on exercises that target these muscle groups. Use the GET /v1/workouts/exercises/metadata endpoint to fetch the available muscle groups. Note that this is used for guidance, not as a strict filter - the workout will still include exercises for complementary muscle groups as needed.","example":["604b0129beaba770c284ff40","604b0165076fe2727354d73e"],"type":"array","items":{"type":"string"}},"includeExerciseCollections":{"description":"Exercise collection names to use as the only allowed exercise pool, narrowed within the selected exercise sources (case-insensitive). Mutually exclusive with excludeExerciseCollections. Prefer this when locking trainer, location, or brand look. Use GET /v1/workouts/exercises/metadata for available collection names and counts. After filtering, the pool must have at least 10 exercises or the request returns 400.","example":["Premium - Studio"],"type":"array","items":{"type":"string"}},"excludeExerciseCollections":{"description":"Exercise collection names to exclude from the exercise pool (case-insensitive). Mutually exclusive with includeExerciseCollections. Use GET /v1/workouts/exercises/metadata for available collection names and counts. Do not simulate include by excluding every other collection — use includeExerciseCollections instead.","example":["Free - Eclectic Home","Premium - Industrial"],"type":"array","items":{"type":"string"}},"userRequirements":{"type":"string","description":"High-level context, definitions, and guidelines for workout generation. Provides customer-specific grounding (e.g., \"intermediate osteoporosis strength training\", \"one-sided exercises, rep schemes\"). Used to inform exercise selection, intensity, and structure.","example":"Intermediate strength / stimulus, one-sided exercises, rep schemes. Focus on controlled movements suitable for osteoporosis patients.","maxLength":2000},"locale":{"type":"string","description":"Optional BCP-47 locale (e.g. \"fr-FR\", \"de-DE\", \"en-GB\"). Localizes the AI workout title and read-side exercise metadata. Omit for English-only output. Unsupported values return 400.","example":"fr-FR"}}},"LocalizedRefDto":{"type":"object","properties":{"id":{"type":"string","description":"Entity id (24-character hex DB id)"},"name":{"type":"string","description":"Localized name resolved for the requested locale (silent en-US fallback)"}},"required":["id","name"]},"ApiExerciseDto":{"type":"object","properties":{"id":{"type":"string","description":"Exercise id (24-character hex DB id)"},"name":{"type":"string","description":"Name of the exercise (canonical English / en-US base)"},"nameLocalized":{"type":"string","description":"Exercise name resolved for the requested locale (silent en-US fallback), same resolution as the workout playlist. Additive localization field.","example":"Pompes"},"thumbnailUrl":{"type":"string","description":"Thumbnail URL for the exercise video"},"videoUri":{"type":"string","description":"Signed main video URI when present. The JSON-receiver embed still resolves playback media via `GET /v1/video-asset/{exerciseId}` using `exercise.id`."},"estimatedRepDuration":{"type":"number","description":"Estimated duration of one repetition in milliseconds"},"muscleGroups":{"description":"Primary muscle groups targeted (canonical English names)","type":"array","items":{"type":"string"}},"muscleGroupsLocalized":{"description":"Primary muscle groups with id and locale-resolved name. Additive localization field.","type":"array","items":{"$ref":"#/components/schemas/LocalizedRefDto"}},"equipment":{"description":"Equipment needed for this exercise (canonical English names)","type":"array","items":{"type":"string"}},"equipmentLocalized":{"description":"Equipment with id and locale-resolved name. Additive localization field.","type":"array","items":{"$ref":"#/components/schemas/LocalizedRefDto"}}},"required":["id","name"]},"ApiInstanceDto":{"type":"object","properties":{"id":{"type":"string","description":"Instance id (24-character hex DB id)"},"kind":{"type":"string","enum":["rest","single-exercise","multi-exercise","class","promo","educational"],"description":"Instance kind on the wire: `rest` or `single-exercise` (generate/adapt). Other enum values exist for library workouts but are not emitted by generate.","example":"single-exercise"},"durationSeconds":{"type":"number","description":"Duration in **seconds** for time-based exercises and rests (already converted from internal milliseconds).","example":30},"reps":{"type":"number","description":"Number of repetitions (for reps-based exercises)"},"exercise":{"description":"Exercise details, if this instance is an exercise.","allOf":[{"$ref":"#/components/schemas/ApiExerciseDto"}]},"skipIntro":{"type":"boolean","description":"Whether to skip intro for the exercise video."},"pace":{"type":"string","enum":["slow","medium","fast"],"nullable":true,"description":"Pacing for time-based exercises."},"weightLevel":{"type":"string","enum":["light","medium","heavy"],"nullable":true,"description":"Weight level for reps-based exercises."},"weight":{"type":"number","description":"Prescribed/target weight (0-1000). Unit in weightUnit.","minimum":0,"maximum":1000},"weightUnit":{"type":"string","enum":["metric","imperial"],"description":"Unit for weight: metric (kg) or imperial (lbs)."}},"required":["id","kind"]},"GeneratedWorkoutCategoryDto":{"type":"object","properties":{"id":{"type":"string","description":"Category id (24-character hex DB id)"},"name":{"type":"string","description":"Category name resolved for the requested locale (silent en-US fallback)"}},"required":["id","name"]},"WorkoutGenerationResponseDto":{"type":"object","properties":{"name":{"type":"string","description":"Name of the generated workout (canonical English / en-US base)."},"nameTranslations":{"type":"object","description":"Per-locale workout name map produced by the AI. Always includes en-US; includes the requested locale when it is non-English. Additive localization field.","additionalProperties":{"type":"string"},"example":{"en-US":"Full Body HIIT Power","fr-FR":"Puissance HIIT Corps Entier"}},"instances":{"description":"List of instances (exercises and rests) in the workout.","type":"array","items":{"$ref":"#/components/schemas/ApiInstanceDto"}},"totalDurationSeconds":{"type":"number","description":"Estimated total duration of the workout in seconds. Calculated if possible."},"difficulty":{"type":"string","description":"Overall difficulty of the workout, as determined or used by the generator (raw key, e.g. 'intermediate')."},"difficultyLabel":{"type":"string","description":"Difficulty label resolved for the requested locale (silent en-US fallback). Additive localization field."},"categoryId":{"type":"string","description":"The category ID used for generating the workout."},"category":{"description":"Category with id and locale-resolved name. Present when the category is resolvable. Additive localization field.","allOf":[{"$ref":"#/components/schemas/GeneratedWorkoutCategoryDto"}]}},"required":["name","instances"]},"AdaptationEndUserProfileDetailsDto":{"type":"object","properties":{"age":{"type":"number","description":"User age","minimum":16,"maximum":99,"example":32},"gender":{"type":"string","enum":["male","female","other"],"description":"User gender","example":"female"},"fitnessLevels":{"type":"array","description":"User fitness levels. First level is primary.","example":["intermediate"],"items":{"type":"string","enum":["beginner","intermediate","advanced"]}},"goalIds":{"description":"Goal IDs","example":["63c92926f920a9005c4e619c"],"type":"array","items":{"type":"string"}},"trainingDaysPerWeek":{"type":"number","description":"Training days per week","minimum":1,"maximum":7,"example":4},"preferredEquipmentCategoryIds":{"description":"Preferred equipment category IDs","type":"array","items":{"type":"string"}}}},"WorkoutAdaptationRequestDto":{"type":"object","properties":{"endUserProfileId":{"type":"string","description":"End user profile ID for fetching 60-day wearable data, workout feedback, and completed sessions","example":"64e3bca9d1b7e600141a9712"},"endUserProfileDetails":{"description":"User profile information for workout adaptation","allOf":[{"$ref":"#/components/schemas/AdaptationEndUserProfileDetailsDto"}]},"exerciseSources":{"type":"array","description":"Exercise sources for potential substitutions","example":["premium_stock","team_exercises"],"items":{"type":"string","enum":["premium_stock","free_stock","team_exercises"]}},"userGuidance":{"type":"string","description":"User free text for guidance/feedback/context/injury/environment/constraints","example":"I have a slight knee injury, avoid high-impact exercises. Working out at home with limited space.","maxLength":2000}},"required":["endUserProfileDetails","exerciseSources"]},"WorkoutAdaptationMetaDto":{"type":"object","properties":{"path":{"type":"string","enum":["gemini","repaired","fallback_recompose","fallback_basic"]},"noveltyScore":{"type":"number"},"softScore":{"type":"number"},"restComplianceScore":{"type":"number"},"hardConstraintsPassed":{"type":"boolean"}},"required":["path","noveltyScore","softScore","restComplianceScore","hardConstraintsPassed"]},"WorkoutAdaptationChangesReplacedItemDto":{"type":"object","properties":{"instanceId":{"type":"string"},"fromExerciseId":{"type":"string"},"toExerciseId":{"type":"string"}},"required":["instanceId","fromExerciseId","toExerciseId"]},"WorkoutAdaptationChangesDto":{"type":"object","properties":{"addedExerciseIds":{"type":"array","items":{"type":"string"}},"removedInstanceIds":{"type":"array","items":{"type":"string"}},"replaced":{"type":"array","items":{"$ref":"#/components/schemas/WorkoutAdaptationChangesReplacedItemDto"}},"reorderedCount":{"type":"number"},"restPolicyApplied":{"type":"boolean"}},"required":["addedExerciseIds","removedInstanceIds","replaced","reorderedCount","restPolicyApplied"]},"WorkoutAdaptationResponseDto":{"type":"object","properties":{"name":{"type":"string","description":"Adapted workout name"},"instances":{"description":"Adapted instances","type":"array","items":{"$ref":"#/components/schemas/ApiInstanceDto"}},"totalDurationSeconds":{"type":"number","description":"Total duration in seconds"},"difficulty":{"type":"string","description":"Adapted workout difficulty"},"categoryId":{"type":"string","description":"Original category ID (preserved)"},"adaptationReasoning":{"type":"string","description":"Explanation of adaptations made"},"adaptationMeta":{"description":"Machine-readable adaptation metadata","allOf":[{"$ref":"#/components/schemas/WorkoutAdaptationMetaDto"}]},"changes":{"description":"Structured diff of what changed vs source","allOf":[{"$ref":"#/components/schemas/WorkoutAdaptationChangesDto"}]}},"required":["name","instances","adaptationReasoning"]},"AutopilotTaskResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Task ID"},"organizationId":{"type":"string","description":"Organization ID"},"ownerId":{"type":"string","description":"Task owner ID"},"name":{"type":"string","description":"Task name"},"status":{"type":"string","enum":["active","draft"],"description":"Task status"},"scope":{"type":"string","enum":["ai_generate","create_similar","publish_existing"],"description":"Task scope"},"contentType":{"type":"string","enum":["workout","program"],"description":"Content type"},"sourceContentId":{"type":"string","description":"Source content ID (for create_similar)"},"existingContentId":{"type":"string","description":"Existing content ID (for publish_existing)"},"categoryIds":{"description":"Category IDs","type":"array","items":{"type":"string"}},"goalIds":{"description":"Goal IDs","type":"array","items":{"type":"string"}},"durationMin":{"type":"number","description":"Min duration"},"durationMax":{"type":"number","description":"Max duration"},"workoutsPerWeekMin":{"type":"number","description":"Min workouts per week"},"workoutsPerWeekMax":{"type":"number","description":"Max workouts per week"},"difficultyOptions":{"description":"Difficulty options","type":"array","items":{"type":"string"}},"includeFreeStock":{"type":"boolean","description":"Include free stock exercises"},"includePremiumStock":{"type":"boolean","description":"Include premium stock exercises"},"includeTeamContent":{"type":"boolean","description":"Include team exercises"},"includeExerciseCollections":{"description":"Collection names used as the only allowed pool (create-similar workout tasks)","type":"array","items":{"type":"string"}},"excludeExerciseCollections":{"description":"Collection names excluded from the pool (create-similar workout tasks)","type":"array","items":{"type":"string"}},"repeatMode":{"type":"string","enum":["once","daily","weekly","biweekly","monthly"],"description":"Repeat schedule"},"repeatUntil":{"format":"date-time","type":"string","description":"Repeat until date"},"nextRunAt":{"type":"object","description":"Next scheduled execution","format":"date-time","nullable":true},"lastRunAt":{"type":"object","description":"Last execution time","format":"date-time","nullable":true},"assignToClientUserIds":{"description":"Client user IDs for content assignment","type":"array","items":{"type":"string"}},"promptGuidanceMode":{"type":"string","enum":["none","custom","ai_tuned","ai_driven"],"description":"Prompt guidance mode"},"customPromptGuidance":{"type":"string","description":"Custom prompt guidance text"},"createdAt":{"format":"date-time","type":"string","description":"Created at"},"updatedAt":{"format":"date-time","type":"string","description":"Updated at"}},"required":["id","organizationId","ownerId","name","status","scope","contentType","difficultyOptions","includeFreeStock","includePremiumStock","includeTeamContent","repeatMode","createdAt","updatedAt"]},"CreateAutopilotTaskDto":{"type":"object","properties":{"name":{"type":"string","description":"User-friendly task name (max 200 chars)","example":"Daily HIIT Generator"},"scope":{"type":"string","enum":["ai_generate","create_similar","publish_existing"],"description":"Task scope: ai_generate, create_similar, or publish_existing"},"contentType":{"type":"string","enum":["workout","program"],"description":"Content type to create: workout or program"},"sourceContentId":{"type":"string","description":"Source workout/program ID (required for create_similar scope)"},"existingContentId":{"type":"string","description":"Existing workout/program ID (required for publish_existing scope)"},"categoryIds":{"description":"Workout category IDs. One picked randomly per run when multiple.","type":"array","items":{"type":"string"}},"goalIds":{"description":"Program goal IDs. One picked randomly per run when multiple.","type":"array","items":{"type":"string"}},"durationMin":{"type":"number","description":"Min duration (minutes for workouts, weeks for programs)","minimum":1},"durationMax":{"type":"number","description":"Max duration (minutes for workouts, weeks for programs). Must be >= durationMin.","minimum":1},"workoutsPerWeekMin":{"type":"number","description":"Min workouts per week (programs only)","minimum":1,"maximum":7},"workoutsPerWeekMax":{"type":"number","description":"Max workouts per week (programs only). Must be >= workoutsPerWeekMin.","minimum":1,"maximum":7},"difficultyOptions":{"type":"array","description":"Difficulty options (1-3 values). One picked randomly per run when multiple.","example":["beginner","intermediate"],"items":{"type":"string","enum":["beginner","intermediate","advanced"]}},"includeFreeStock":{"type":"boolean","description":"Include free stock exercises","default":true},"includePremiumStock":{"type":"boolean","description":"Include premium stock exercises (requires premiumStock entitlement)","default":false},"includeTeamContent":{"type":"boolean","description":"Include team exercises","default":false},"includeExerciseCollections":{"description":"Exercise collection names to use as the only allowed pool for create-similar workout tasks (case-insensitive). Mutually exclusive with excludeExerciseCollections.","type":"array","items":{"type":"string"}},"excludeExerciseCollections":{"description":"Exercise collection names to exclude from the pool for create-similar workout tasks (case-insensitive). Mutually exclusive with includeExerciseCollections.","type":"array","items":{"type":"string"}},"repeatMode":{"type":"string","enum":["once","daily","weekly","biweekly","monthly"],"description":"Repeat schedule: once, daily, weekly, biweekly, monthly"},"repeatUntil":{"type":"string","description":"Repeat until date (ISO 8601). Omit for indefinite scheduling."},"nextRunAt":{"type":"string","description":"Initial scheduled execution date (ISO 8601). When omitted, computed on activation."},"assignToClientUserIds":{"description":"Client user IDs to assign created content to (max 100)","type":"array","items":{"type":"string"}},"promptGuidanceMode":{"type":"string","enum":["none","custom","ai_tuned","ai_driven"],"description":"Prompt guidance mode: none, custom, ai_tuned, ai_driven","default":"none"},"customPromptGuidance":{"type":"string","description":"Custom prompt guidance text (max 2000 chars). Used when promptGuidanceMode is custom.","maxLength":2000}},"required":["name","scope","contentType","difficultyOptions","repeatMode"]},"UpdateAutopilotTaskDto":{"type":"object","properties":{"name":{"type":"string","description":"Task name (max 200 chars)"},"categoryIds":{"description":"Workout category IDs","type":"array","items":{"type":"string"}},"goalIds":{"description":"Program goal IDs","type":"array","items":{"type":"string"}},"durationMin":{"type":"number","description":"Min duration"},"durationMax":{"type":"number","description":"Max duration"},"workoutsPerWeekMin":{"type":"number","description":"Min workouts per week (programs only)"},"workoutsPerWeekMax":{"type":"number","description":"Max workouts per week (programs only)"},"difficultyOptions":{"type":"array","description":"Difficulty options","items":{"type":"string","enum":["beginner","intermediate","advanced"]}},"includeFreeStock":{"type":"boolean","description":"Include free stock exercises"},"includePremiumStock":{"type":"boolean","description":"Include premium stock exercises"},"includeTeamContent":{"type":"boolean","description":"Include team exercises"},"includeExerciseCollections":{"description":"Exercise collection names to use as the only allowed pool (create-similar workout tasks). Mutually exclusive with excludeExerciseCollections.","type":"array","items":{"type":"string"}},"excludeExerciseCollections":{"description":"Exercise collection names to exclude from the pool (create-similar workout tasks). Mutually exclusive with includeExerciseCollections.","type":"array","items":{"type":"string"}},"repeatMode":{"type":"string","enum":["once","daily","weekly","biweekly","monthly"],"description":"Repeat schedule"},"repeatUntil":{"type":"string","description":"Repeat until date (ISO 8601)"},"nextRunAt":{"type":"string","description":"Next run date (ISO 8601). Use to reschedule an active task."},"assignToClientUserIds":{"description":"Client user IDs to assign content to","type":"array","items":{"type":"string"}},"promptGuidanceMode":{"type":"string","enum":["none","custom","ai_tuned","ai_driven"],"description":"Prompt guidance mode"},"customPromptGuidance":{"type":"string","description":"Custom prompt guidance text (max 2000 chars)","maxLength":2000}}},"ExportDropDto":{"type":"object","properties":{"channelPreset":{"type":"string","enum":["ig_reels","ig_stories","ig_carousel","tiktok","yt_shorts","fb_reels","yt_longform"],"description":"Channel preset; if omitted, uses drop channelPreset"},"aspectRatio":{"type":"string","enum":["9:16","1:1","16:9"],"description":"Aspect ratio override"},"duration":{"type":"number","enum":[15,30,60],"description":"Duration in seconds override"}}},"OrganizationConnectedPlatformsResponseDto":{"type":"object","properties":{"connectedPlatforms":{"type":"array","description":"Social platforms (instagram, tiktok, youtube, facebook) that have a connected account id stored for this organization","items":{"type":"string","enum":["instagram","tiktok","youtube","facebook"]}}},"required":["connectedPlatforms"]},"OrganizationSocialPublishTaskResponseDto":{"type":"object","properties":{"_id":{"type":"string","deprecated":true,"description":"Deprecated. Legacy internal id; use `id` instead. Will be removed in the next major Content API release."},"_teamId":{"type":"string","deprecated":true,"description":"Deprecated. Legacy internal team id; use `organizationId` instead. Will be removed in the next major Content API release."},"_ownerId":{"type":"string","deprecated":true,"description":"Deprecated. Legacy internal owner id; use `ownerId` instead. Will be removed in the next major Content API release."},"name":{"type":"string"},"status":{"type":"string","enum":["active","draft"]},"publishAssetType":{"type":"string","enum":["social_drop","workout_full_video"]},"sourceMode":{"type":"string","enum":["manual_fixed","random_ready","ai_insights","ai_pick"]},"dropId":{"type":"string"},"workoutId":{"type":"string"},"publishCopyPacks":{"type":"object","description":"workout_full_video: sanitized copy packs per channel (same shape as drop copyPacks)."},"workoutExportLocale":{"type":"string"},"coverOverridesByChannel":{"type":"object","description":"workout_full_video: S3 object keys for social/AI covers by channel preset and aspect ratio (same shape as Drop.coverOverridesByChannel). Not workout library thumbnails."},"readyDropPick":{"type":"string","enum":["random","latest"]},"allowedDropSourceTypes":{"type":"array","items":{"type":"string","enum":["exercise","exerciseCollection","workout","workoutCollection"]}},"primaryChannelPreset":{"type":"string","enum":["ig_reels","ig_stories","ig_carousel","tiktok","yt_shorts","fb_reels","yt_longform"]},"channelPresets":{"type":"array","items":{"type":"string","enum":["ig_reels","ig_stories","ig_carousel","tiktok","yt_shorts","fb_reels","yt_longform"]}},"exportAspectRatio":{"type":"string","enum":["9:16","1:1","16:9"]},"exportDurationSeconds":{"type":"number","enum":[15,30,60]},"repeatMode":{"type":"string","enum":["once","daily","weekly","biweekly","monthly"]},"repeatUntil":{"type":"object","nullable":true},"nextRunAt":{"type":"object"},"lastRunAt":{"type":"object"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"id":{"type":"string","description":"Automation ID. Use this for all subsequent /v1/orgs/{orgId}/social-publish/{taskId} calls."},"organizationId":{"type":"string","description":"Organization (team) ID that owns this automation."},"ownerId":{"type":"string","description":"User ID of the organization owner that the automation runs on behalf of."},"lastRunOutcome":{"type":"string","enum":["success","failed","skipped_limit","skipped_no_drop","skipped_no_workout_export","skipped_zernio_config"],"description":"Outcome of the most recent execution event for this automation"},"lastErrorSummary":{"type":"string","description":"Error or skip message from the most recent execution when it was not a success"},"lastExecutionAt":{"format":"date-time","type":"string","description":"Timestamp of the most recent execution event"}},"required":["name","status","publishAssetType","sourceMode","readyDropPick","allowedDropSourceTypes","primaryChannelPreset","channelPresets","repeatMode","createdAt","updatedAt","id","organizationId","ownerId"]},"OrganizationSocialPublishTaskListResponse":{"type":"object","properties":{"links":{"description":"Pagination envelope. Use `links.next` to fetch the next page; `links.total` is the count across all pages and is omitted on endpoints where it is too expensive to compute.","allOf":[{"$ref":"#/components/schemas/PageLinks"}]},"data":{"type":"array","items":{"$ref":"#/components/schemas/OrganizationSocialPublishTaskResponseDto"}}},"required":["links","data"]},"CreateSocialDropPublishTaskDto":{"type":"object","properties":{"name":{"type":"string","description":"Automation name"},"publishAssetType":{"type":"string","enum":["social_drop","workout_full_video"],"description":"Defaults to social_drop. Use workout_full_video for full WorkoutExport video (not a social drop)."},"sourceMode":{"type":"string","enum":["manual_fixed","random_ready","ai_insights","ai_pick"],"description":"Required for social_drop automations. When publishAssetType is workout_full_video, omit to default to manual_fixed."},"dropId":{"type":"string","description":"Required when sourceMode is manual_fixed and publishAssetType is social_drop"},"workoutId":{"type":"string","description":"Required when publishAssetType is workout_full_video"},"publishCopyPacks":{"type":"object","description":"workout_full_video: copy packs per channel (same fields as drop copyPacks). The outbound publish payload uses copy for primaryChannelPreset; if hook and caption are both empty at run time, Gemini generates and the result is saved on the task."},"workoutExportLocale":{"type":"string","description":"Locale for choosing WorkoutExport variant when publishAssetType is workout_full_video"},"locale":{"type":"string","description":"Alias for workoutExportLocale when publishAssetType is workout_full_video. If both are set, workoutExportLocale wins."},"readyDropPick":{"type":"string","enum":["random","latest"],"description":"For random_ready / ai_insights: random among up to 80 most recently updated ready drops, or single latest by updatedAt. Ignored for manual_fixed.","default":"random"},"allowedDropSourceTypes":{"type":"array","description":"Pool of drop source types (exercise=clip/video, exerciseCollection=exercise groups, workout, workoutCollection=program). Omit or empty = all types.","items":{"type":"string","enum":["exercise","exerciseCollection","workout","workoutCollection"]}},"primaryChannelPreset":{"type":"string","enum":["ig_reels","ig_stories","ig_carousel","tiktok","yt_shorts","fb_reels","yt_longform"]},"channelPresets":{"type":"array","description":"Target channel presets for publishing; must include primary.","items":{"type":"string","enum":["ig_reels","ig_stories","ig_carousel","tiktok","yt_shorts","fb_reels","yt_longform"]}},"repeatMode":{"type":"string","enum":["once","daily","weekly","biweekly","monthly"]},"repeatUntil":{"type":"string","description":"Repeat until (ISO 8601)"},"nextRunAt":{"type":"string","description":"Next run (ISO 8601)"},"exportAspectRatio":{"type":"string","enum":["9:16","1:1","16:9"],"description":"Export variant aspect ratio override"},"exportDurationSeconds":{"type":"number","enum":[15,30,60],"description":"Export variant duration override (seconds)"}},"required":["name","primaryChannelPreset","channelPresets","repeatMode"]},"OrganizationPatchSocialPublishTaskDto":{"type":"object","properties":{"name":{"type":"string"},"publishAssetType":{"type":"string","enum":["social_drop","workout_full_video"]},"sourceMode":{"type":"string","enum":["manual_fixed","random_ready","ai_insights","ai_pick"]},"dropId":{"type":"object","nullable":true,"description":"Id of the drop, or null to clear (omit to leave unchanged)"},"workoutId":{"type":"object","nullable":true,"description":"Id of the workout, or null to clear (omit to leave unchanged)"},"publishCopyPacks":{"type":"object","description":"workout_full_video: merges into existing publishCopyPacks by channel key (same semantics as PATCH drop copyPacks)."},"workoutExportLocale":{"type":"object"},"locale":{"type":"object","description":"Alias for workoutExportLocale on workout_full_video tasks. If both are set in one request, workoutExportLocale wins."},"readyDropPick":{"type":"string","enum":["random","latest"]},"allowedDropSourceTypes":{"type":"array","items":{"type":"string","enum":["exercise","exerciseCollection","workout","workoutCollection"]}},"primaryChannelPreset":{"type":"string","enum":["ig_reels","ig_stories","ig_carousel","tiktok","yt_shorts","fb_reels","yt_longform"]},"channelPresets":{"type":"array","items":{"type":"string","enum":["ig_reels","ig_stories","ig_carousel","tiktok","yt_shorts","fb_reels","yt_longform"]}},"repeatMode":{"type":"string","enum":["once","daily","weekly","biweekly","monthly"]},"repeatUntil":{"type":"object","nullable":true,"description":"ISO 8601 end of recurrence, or null to clear"},"nextRunAt":{"type":"string"},"exportAspectRatio":{"type":"string","enum":["9:16","1:1","16:9"]},"exportDurationSeconds":{"type":"number","enum":[15,30,60]},"status":{"type":"string","enum":["active","draft"],"description":"Set to active to schedule runs (requires connected accounts for all channel preset platforms). Set to draft to pause and clear nextRunAt."}}},"WorkoutPlaylistResponse":{"type":"object","properties":{"data":{"description":"An ordered array of workout segments. Each object in the array has a single key indicating the segment type (e.g., 'intro', 'exercise', 'break') and the value is the corresponding segment object.","example":[{"intro":{"kind":"workout-intro","id":"intro","duration":5.2}},{"exercise":{"kind":"exercise","id":"exercise_squats_1","exerciseId":"507f1f77bcf86cd799439011","duration":45,"name":"Bodyweight Squats"}},{"class":{"kind":"class","id":"class_strength_1","exerciseId":"507f1f77bcf86cd799439013","duration":1200,"name":"Morning Strength Class","chapters":[{"name":"Goblet Squat","startTimeSec":180.5,"endTimeSec":420,"equipment":[{"id":"60812e08606fc90011eb4408","name":"Kettlebell"}],"muscleGroups":[{"id":"604b0177076fe2727354d743","name":"Quadriceps"}]}]}},{"break":{"kind":"break","id":"break_1","duration":30}},{"exercise":{"kind":"exercise","id":"exercise_pushups_1","exerciseId":"507f1f77bcf86cd799439012","duration":45,"name":"Push-ups"}},{"outro":{"kind":"workout-outro","id":"outro","duration":45.5}}],"type":"array","items":{"type":"string"}},"presentationStyle":{"type":"string","enum":["full","minimal","essential","noOverlays"],"description":"Video overlay presentation style for this workout. Determines which UI elements the player should render. Null if not specified.","example":"full"},"links":{"type":"object","description":"Related links for the workout playlist (currently unused).","example":{}}},"required":["data","links"]},"WorkoutMusicTrack":{"type":"object","properties":{"id":{"type":"string","description":"Track ID","example":"track_123"},"name":{"type":"string","description":"Track name","example":"Upbeat Workout Mix"},"duration":{"type":"number","description":"Track duration in seconds","example":180},"url":{"type":"string","description":"Pre-signed S3 URL for the track","example":"https://s3.amazonaws.com/bucket/track.mp4a?signature=..."},"filename":{"type":"string","description":"Track filename","example":"upbeat-mix.mp4a"},"bpm":{"type":"number","description":"Track BPM (beats per minute)","example":128}},"required":["id","name","duration","url"]},"WorkoutMusicPlaylistResponse":{"type":"object","properties":{"tracks":{"description":"Ordered list of music tracks","type":"array","items":{"$ref":"#/components/schemas/WorkoutMusicTrack"}},"totalDuration":{"type":"number","description":"Total playlist duration in seconds","example":1800},"workoutDuration":{"type":"number","description":"Workout duration in seconds","example":1650}},"required":["tracks","totalDuration","workoutDuration"]},"StartWorkoutSessionBody":{"type":"object","properties":{"endUserId":{"type":"string","description":"Attribute the session to a specific end user, by internal Hyperhuman user id or email. Resolved against the API key team. Ignored when a member Bearer token is present.","example":"64f1a2b3c4d5e6f7a8b9c0d1"},"externalUserId":{"type":"string","description":"Attribute the session to a specific end user by their external UUID (the externalUUID stored on the team membership). Alternative to endUserId.","example":"ext-user-12345"},"organizationId":{"type":"string","description":"Organization (team) id the end user belongs to. Required for standard/club keys that span organizations; defaults to the API key team for team-scoped keys.","example":"a1b2c3d4e5f6a7b8c9d0e1f2"}}},"WorkoutSessionWearableActivity":{"type":"object","properties":{"activityType":{"type":"object","description":"Wearable activity type (null when the provider could not classify it)","nullable":true},"source":{"type":"object","description":"Wearable provider (e.g. Garmin)","nullable":true},"activeCaloriesKcal":{"type":"object","description":"Measured active calories (kcal)","nullable":true},"distanceMeters":{"type":"object","description":"Measured distance (meters)","nullable":true},"hrAvg":{"type":"object","description":"Measured average heart rate (BPM)","nullable":true},"hrMax":{"type":"object","description":"Measured maximum heart rate (BPM)","nullable":true},"hrMin":{"type":"object","description":"Measured minimum heart rate (BPM)","nullable":true},"lowIntensitySeconds":{"type":"object","description":"Seconds spent in the low-intensity effort band","nullable":true},"moderateIntensitySeconds":{"type":"object","description":"Seconds spent in the moderate-intensity effort band","nullable":true},"vigorousIntensitySeconds":{"type":"object","description":"Seconds spent in the vigorous-intensity effort band","nullable":true}}},"WorkoutSession":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the workout session.","example":"12ab3efd45c67c1234566cd1"},"createdAt":{"format":"date-time","type":"string","description":"Timestamp when the session was created.","example":"2023-10-28T10:00:00.000Z"},"updatedAt":{"format":"date-time","type":"string","description":"Timestamp when the session was last updated.","example":"2023-10-28T10:30:15.500Z"},"workoutId":{"type":"string","description":"ID of the workout associated with this session.","example":"12ab3efd45c67c1234566cd1"},"workoutSegmentId":{"type":"string","description":"ID of the current workout segment being played (from playlist). Use this to track which part of the workout the user is on.","example":"seg-exercise-2"},"status":{"type":"string","description":"Current status of the workout session.","enum":["started","completed"],"example":"started"},"duration":{"type":"number","description":"Total actual playback time in seconds (not including pauses). This is the duration the user has been actively engaged with the workout.","example":125.5,"minimum":0},"progress":{"type":"number","description":"Completion progress as a fraction (0.0 = not started, 1.0 = 100% complete). Calculated based on current segment position within the total workout.","example":0.75,"minimum":0,"maximum":1},"wearableActivity":{"description":"Measured biometrics from an overlapping wearable activity reconciled to this workout (if any).","nullable":true,"allOf":[{"$ref":"#/components/schemas/WorkoutSessionWearableActivity"}]}},"required":["id","createdAt","updatedAt","workoutId","workoutSegmentId","status","duration","progress"]},"WorkoutSessionResponse":{"type":"object","properties":{"data":{"description":"Contains the detailed workout session object.","allOf":[{"$ref":"#/components/schemas/WorkoutSession"}]}},"required":["data"]},"PatchWorkoutSessionBody":{"type":"object","properties":{"endUserId":{"type":"string","description":"Attribute the session to a specific end user, by internal Hyperhuman user id or email. Resolved against the API key team. Ignored when a member Bearer token is present.","example":"64f1a2b3c4d5e6f7a8b9c0d1"},"externalUserId":{"type":"string","description":"Attribute the session to a specific end user by their external UUID (the externalUUID stored on the team membership). Alternative to endUserId.","example":"ext-user-12345"},"organizationId":{"type":"string","description":"Organization (team) id the end user belongs to. Required for standard/club keys that span organizations; defaults to the API key team for team-scoped keys.","example":"a1b2c3d4e5f6a7b8c9d0e1f2"},"workoutSegmentId":{"type":"string","description":"ID of the current workout segment.","example":"seg-exercise-squat-1"},"progressSeconds":{"type":"number","description":"Actual playback time in seconds. This is the primary method for tracking session duration accurately. Send this value on each PATCH to record how much time the user has actually spent playing the workout (excluding paused time). Duration is capped at 2x the expected workout duration.","example":125.5,"minimum":0},"state":{"type":"string","description":"[Deprecated] This field is accepted for backward compatibility but does not affect duration calculation. Duration is tracked via progressSeconds.","enum":["active","paused"],"example":"paused","deprecated":true}}},"EndWorkoutSessionBody":{"type":"object","properties":{"endUserId":{"type":"string","description":"Attribute the session to a specific end user, by internal Hyperhuman user id or email. Resolved against the API key team. Ignored when a member Bearer token is present.","example":"64f1a2b3c4d5e6f7a8b9c0d1"},"externalUserId":{"type":"string","description":"Attribute the session to a specific end user by their external UUID (the externalUUID stored on the team membership). Alternative to endUserId.","example":"ext-user-12345"},"organizationId":{"type":"string","description":"Organization (team) id the end user belongs to. Required for standard/club keys that span organizations; defaults to the API key team for team-scoped keys.","example":"a1b2c3d4e5f6a7b8c9d0e1f2"},"sessionId":{"type":"string","description":"The ID of the session to end.","example":"session-uuid-12345"},"progress":{"type":"number","description":"[Deprecated] This field is accepted but the actual progress is calculated from the last progressSeconds sent via PATCH.","example":100,"deprecated":true}},"required":["sessionId"]},"CompleteWorkoutSessionBody":{"type":"object","properties":{"endUserId":{"type":"string","description":"Attribute the session to a specific end user, by internal Hyperhuman user id or email. Resolved against the API key team. Ignored when a member Bearer token is present.","example":"64f1a2b3c4d5e6f7a8b9c0d1"},"externalUserId":{"type":"string","description":"Attribute the session to a specific end user by their external UUID (the externalUUID stored on the team membership). Alternative to endUserId.","example":"ext-user-12345"},"organizationId":{"type":"string","description":"Organization (team) id the end user belongs to. Required for standard/club keys that span organizations; defaults to the API key team for team-scoped keys.","example":"a1b2c3d4e5f6a7b8c9d0e1f2"},"sessionId":{"type":"string","description":"The ID of the specific workout session to mark as completed with 100% progress.","example":"session-uuid-12345"}},"required":["sessionId"]},"WorkoutFeedbackRatingOption":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for this rating option","example":"507f1f77bcf86cd799439011"},"label":{"type":"string","description":"Human-readable label for this rating option","example":"Very Good"},"value":{"type":"number","description":"Numeric value representing this rating","example":4,"minimum":1,"maximum":5}},"required":["id","label","value"]},"WorkoutFeedbackDifficultyOption":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for this difficulty option","example":"507f1f77bcf86cd799439012"},"label":{"type":"string","description":"Human-readable label for this difficulty level","example":"Challenging"},"value":{"type":"number","description":"Numeric value representing this difficulty level","example":4,"minimum":1,"maximum":5}},"required":["id","label","value"]},"WorkoutFeedbackOptions":{"type":"object","properties":{"rating":{"type":"array","items":{"$ref":"#/components/schemas/WorkoutFeedbackRatingOption"}},"difficulty":{"type":"array","items":{"$ref":"#/components/schemas/WorkoutFeedbackDifficultyOption"}}},"required":["rating","difficulty"]},"WorkoutFeedbackOptionsResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WorkoutFeedbackOptions"}},"required":["data"]},"ExerciseFeedbackData":{"type":"object","properties":{"instanceId":{"type":"string","description":"Instance ID from workout playlist segment","example":"64f1a2b3c4d5e6f7a8b9c0d1"},"weight":{"type":"number","description":"Weight used for this exercise (in the unit specified by weightUnit). Can be provided alone or together with reps.","minimum":0,"maximum":1000,"example":25.5},"reps":{"type":"number","description":"Number of reps completed. Can be provided alone or together with weight. Required for AMRAP/time-based exercises or rep-based exercises.","minimum":1,"maximum":100,"example":15}},"required":["instanceId"]},"SubmitWorkoutFeedbackBody":{"type":"object","properties":{"endUserId":{"type":"string","description":"Attribute the session to a specific end user, by internal Hyperhuman user id or email. Resolved against the API key team. Ignored when a member Bearer token is present.","example":"64f1a2b3c4d5e6f7a8b9c0d1"},"externalUserId":{"type":"string","description":"Attribute the session to a specific end user by their external UUID (the externalUUID stored on the team membership). Alternative to endUserId.","example":"ext-user-12345"},"organizationId":{"type":"string","description":"Organization (team) id the end user belongs to. Required for standard/club keys that span organizations; defaults to the API key team for team-scoped keys.","example":"a1b2c3d4e5f6a7b8c9d0e1f2"},"workoutSessionId":{"type":"string","description":"The ID of the completed workout session this feedback pertains to.","example":"12ab3efd45c67c1234566cd1"},"ratingId":{"type":"string","description":"Overall rating option ID. Refer to `GET /workouts/feedback/options` for possible values.","example":"rating-opt-5star"},"difficultyId":{"type":"string","description":"Perceived difficulty option ID. Refer to `GET /workouts/feedback/options` for possible values.","example":"difficulty-opt-moderate"},"comment":{"type":"string","description":"Optional free-text user comment about the workout.","example":"Great workout, but the music was a bit too loud.","maxLength":1000},"weightUnit":{"type":"string","enum":["metric","imperial"],"description":"Unit system for weight values. Required if exerciseData contains weight values.","example":"metric"},"exerciseData":{"description":"Exercise-specific data (weights and reps) in the same order as workout playlist (excluding rest segments).","type":"array","items":{"$ref":"#/components/schemas/ExerciseFeedbackData"}}},"required":["workoutSessionId"]},"ExerciseFeedbackDataResponse":{"type":"object","properties":{"instanceId":{"type":"string","description":"Instance ID from workout playlist identifying which exercise this feedback is for","example":"64f1a2b3c4d5e6f7a8b9c0d2"},"weight":{"type":"number","description":"Weight used for this exercise (in weightUnit specified in feedback)","example":25.5},"reps":{"type":"number","description":"Number of repetitions completed for this exercise","example":12,"minimum":0}},"required":["instanceId"]},"WorkoutFeedback":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for this feedback record","example":"67d1a2b3c4e5f6789abc0d2"},"createdAt":{"format":"date-time","type":"string","description":"When this feedback was submitted","example":"2025-01-10T09:30:00.000Z"},"updatedAt":{"format":"date-time","type":"string","description":"When this feedback was last updated","example":"2025-01-10T09:30:00.000Z"},"workoutId":{"type":"string","description":"ID of the workout this feedback is for","example":"12ab3efd45c67c1234566cd1"},"workoutSessionId":{"type":"string","description":"ID of the workout session this feedback is associated with","example":"67d1a2b3c4e5f6789abc0d1"},"rating":{"nullable":true,"description":"User rating of the workout experience","allOf":[{"$ref":"#/components/schemas/WorkoutFeedbackRatingOption"}]},"difficulty":{"nullable":true,"description":"User assessment of workout difficulty level","allOf":[{"$ref":"#/components/schemas/WorkoutFeedbackDifficultyOption"}]},"comment":{"type":"string","description":"Optional user comment or additional feedback","nullable":true,"example":"Great workout! Felt appropriately challenging."},"weightUnit":{"type":"string","enum":["metric","imperial"],"nullable":true,"description":"Unit system used for weight measurements","example":"metric"},"exerciseData":{"nullable":true,"description":"Detailed performance data for individual exercises","type":"array","items":{"$ref":"#/components/schemas/ExerciseFeedbackDataResponse"}}},"required":["id","createdAt","updatedAt","workoutId","workoutSessionId","rating","difficulty"]},"WorkoutFeedbackResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WorkoutFeedback"}},"required":["data"]},"MuscleGroup":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the muscle group.","example":"mg-legs-abc"},"name":{"type":"string","description":"Display name of the muscle group. Localized based on locale query parameter.","example":"Legs"}},"required":["id","name"]},"ExerciseBundleRefDto":{"type":"object","properties":{"id":{"type":"string","description":"Bundle ID"},"bundleIdentifier":{"type":"string","description":"Asensei bundle identifier"},"downloadUrl":{"type":"string","description":"Pre-signed download URL for bundle JSON content"},"displayName":{"type":"string","description":"Human-readable display name"}},"required":["id","bundleIdentifier","downloadUrl"]},"AudioDto":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"assetUri":{"type":"string"},"type":{"type":"string"},"locale":{"type":"string"},"scriptText":{"type":"string","description":"Verbatim transcript / script of the spoken instruction (the text the narrator reads in the `assetUri` clip). Useful for closed captions, accessibility, search indexing, and AI summarization. Optional: legacy or stock recordings without a stored script omit this field.","example":"Stand tall with your feet shoulder-width apart. Lower into a squat, keeping your chest up."}},"required":["id","createdAt","assetUri","type","locale"]},"VideoAssetListItem":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"trainer":{"description":"Creator reference for the workspace member who owns this asset in Hyperhuman Teams. The JSON field name remains `trainer` for API compatibility.","allOf":[{"$ref":"#/components/schemas/TrainerRef"}]},"name":{"type":"string"},"kind":{"type":"string","enum":["single-exercise","multi-exercise","class","promo","educational"],"description":"Video kind. See the VIDEO TYPE GUIDE on the list operation for product names and audio behavior."},"muscleGroups":{"type":"array","items":{"$ref":"#/components/schemas/MuscleGroup"}},"equipment":{"type":"array","items":{"$ref":"#/components/schemas/Equipment"}},"preview":{"description":"Preview video stream","allOf":[{"$ref":"#/components/schemas/VideoLinks"}]},"collectionName":{"type":"string"},"coach":{"type":"string","enum":["male","female"]},"tags":{"type":"array","items":{"type":"string"}},"skillLevel":{"type":"string","enum":["beginner","intermediate","advanced"]},"categories":{"type":"array","items":{"type":"string","enum":["strength","cardio","mobility","balance","endurance","flexibility","plyometrics","recovery","running"]}},"executionSide":{"type":"string","enum":["both","left","right","alternating"]},"showcasedReps":{"type":"number"},"bundle":{"description":"Asensei movement bundle for this exercise","allOf":[{"$ref":"#/components/schemas/ExerciseBundleRefDto"}]},"playsInLoop":{"type":"boolean","description":"When true, preview playback is intended to loop (for example smart clips aligned with reps or duration)."},"organization":{"nullable":true,"description":"Workspace (organization) this exercise belongs to. `null` when the workspace cannot be resolved.","allOf":[{"$ref":"#/components/schemas/Organization"}]},"audioInstructions":{"description":"Locale-specific instruction audio tracks. Emitted only for `kind: single-exercise` (the smart-clip product type that strips original audio in favor of multilingual instructions). When `?locale=` is supplied, narrowed to matching locales via the standard locale chain (English fallback); when omitted, returns all available locales so catalog UIs can render a \"languages available\" indicator. Empty array for `single-exercise` rows that have not yet been narrated. Always empty for the other kinds (`multi-exercise`, `educational`, `promo`, `class`) which keep their original audio baked into the video. Currently populated by `GET /v1/orgs/{organizationId}/video-assets`; other endpoints that share this list-item shape do not yet emit this field.","type":"array","items":{"$ref":"#/components/schemas/AudioDto"}}},"required":["id","createdAt","trainer","name","kind","muscleGroups","equipment","playsInLoop","organization"]},"VideoAssetsListResponse":{"type":"object","properties":{"links":{"description":"Pagination envelope. Use `links.next` to fetch the next page; `links.total` is the count across all pages and is omitted on endpoints where it is too expensive to compute.","allOf":[{"$ref":"#/components/schemas/PageLinks"}]},"data":{"type":"array","items":{"$ref":"#/components/schemas/VideoAssetListItem"}},"explanation":{"type":"string","description":"Explanation for how this list was filtered or scoped."}},"required":["links","data"]},"StockVideoAssetListItem":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"name":{"type":"string"},"kind":{"type":"string","enum":["single-exercise","multi-exercise","class","promo","educational"],"description":"Video kind. See the VIDEO TYPE GUIDE on the list operation for product names and audio behavior."},"muscleGroups":{"type":"array","items":{"$ref":"#/components/schemas/MuscleGroup"}},"equipment":{"type":"array","items":{"$ref":"#/components/schemas/Equipment"}},"preview":{"description":"Preview video stream","allOf":[{"$ref":"#/components/schemas/VideoLinks"}]},"collectionName":{"type":"string"},"coach":{"type":"string","enum":["male","female"]},"tags":{"type":"array","items":{"type":"string"}},"skillLevel":{"type":"string","enum":["beginner","intermediate","advanced"]},"categories":{"type":"array","items":{"type":"string","enum":["strength","cardio","mobility","balance","endurance","flexibility","plyometrics","recovery","running"]}},"executionSide":{"type":"string","enum":["both","left","right","alternating"]},"showcasedReps":{"type":"number"},"playsInLoop":{"type":"boolean","description":"When true, preview playback is intended to loop (for example smart clips aligned with reps or duration)."},"audioInstructions":{"description":"Locale-specific instruction audio tracks. Emitted only for `kind: single-exercise` (the smart-clip product type that strips original audio in favor of multilingual instructions). When `?locale=` is supplied, narrowed to matching locales via the standard locale chain (English fallback); when omitted, returns all available locales so catalog UIs can render a \"languages available\" indicator. Empty array for `single-exercise` rows that have not yet been narrated. Always empty for the other kinds (`multi-exercise`, `educational`, `promo`, `class`) which keep their original audio baked into the video. Currently populated by `GET /v1/orgs/{organizationId}/video-assets`; other endpoints that share this list-item shape do not yet emit this field.","type":"array","items":{"$ref":"#/components/schemas/AudioDto"}}},"required":["id","createdAt","name","kind","muscleGroups","equipment","playsInLoop"]},"StockVideoAssetsListResponse":{"type":"object","properties":{"links":{"description":"Pagination envelope. Use `links.next` to fetch the next page; `links.total` is the count across all pages and is omitted on endpoints where it is too expensive to compute.","allOf":[{"$ref":"#/components/schemas/PageLinks"}]},"data":{"type":"array","items":{"$ref":"#/components/schemas/StockVideoAssetListItem"}},"explanation":{"type":"string","description":"Explanation for how this list was filtered or scoped."}},"required":["links","data"]},"TimeBasedConfig":{"type":"object","properties":{"kind":{"type":"string","enum":["timeBased"]},"duration":{"type":"number"},"pace":{"type":"string","enum":["slow","medium","fast"],"nullable":true},"weightLevel":{"type":"string","enum":["light","medium","heavy"],"nullable":true},"rpe":{"type":"number","description":"Rate of Perceived Exertion (0-10). Target intensity level for this exercise.","minimum":0,"maximum":10},"amrap":{"type":"boolean","description":"As Many Reps As Possible mode. Only applicable for time-based exercises."}},"required":["kind","duration"]},"RepsBasedConfig":{"type":"object","properties":{"kind":{"type":"string","enum":["repsBased"]},"reps":{"type":"number"},"weightLevel":{"type":"string","enum":["light","medium","heavy"],"nullable":true},"pace":{"type":"string","enum":["slow","medium","fast"],"nullable":true},"rpe":{"type":"number","description":"Rate of Perceived Exertion (0-10). Target intensity level for this exercise.","minimum":0,"maximum":10}},"required":["kind","reps"]},"SingleExerciseConfig":{"type":"object","properties":{"timeBasedConfig":{"description":"Time based configuration","allOf":[{"$ref":"#/components/schemas/TimeBasedConfig"}]},"repsBasedConfig":{"description":"Reps based configuration","allOf":[{"$ref":"#/components/schemas/RepsBasedConfig"}]}}},"GroupListItem":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"trainer":{"$ref":"#/components/schemas/TrainerRef"},"name":{"type":"string"},"kind":{"type":"string","enum":["circuit","sets"]},"preview":{"description":"Preview video stream","allOf":[{"$ref":"#/components/schemas/VideoLinks"}]},"rounds":{"type":"number"},"roundBreakDuration":{"type":"number"},"exerciseBreakDuration":{"type":"number"},"exerciseConfig":{"$ref":"#/components/schemas/SingleExerciseConfig"}},"required":["id","createdAt","updatedAt","trainer","name","kind","rounds","roundBreakDuration","exerciseBreakDuration","exerciseConfig"]},"GroupListResponse":{"type":"object","properties":{"links":{"description":"Pagination envelope. Use `links.next` to fetch the next page; `links.total` is the count across all pages and is omitted on endpoints where it is too expensive to compute.","allOf":[{"$ref":"#/components/schemas/PageLinks"}]},"data":{"type":"array","items":{"$ref":"#/components/schemas/GroupListItem"}},"explanation":{"type":"string","description":"Explanation for how this list was filtered or sorted"}},"required":["links","data"]},"Group":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"trainer":{"$ref":"#/components/schemas/TrainerRef"},"name":{"type":"string"},"kind":{"type":"string","enum":["circuit","sets"]},"preview":{"description":"Preview video stream","allOf":[{"$ref":"#/components/schemas/VideoLinks"}]},"rounds":{"type":"number"},"roundBreakDuration":{"type":"number"},"exerciseBreakDuration":{"type":"number"},"exerciseConfig":{"$ref":"#/components/schemas/SingleExerciseConfig"},"organization":{"$ref":"#/components/schemas/Organization"}},"required":["id","createdAt","updatedAt","trainer","name","kind","rounds","roundBreakDuration","exerciseBreakDuration","exerciseConfig"]},"GroupResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Group"}},"required":["data"]},"GroupExerciseInstanceDto":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"trainer":{"description":"Creator reference for the workspace member who owns this asset in Hyperhuman Teams. The JSON field name remains `trainer` for API compatibility.","allOf":[{"$ref":"#/components/schemas/TrainerRef"}]},"name":{"type":"string"},"kind":{"type":"string","enum":["single-exercise","multi-exercise","class","promo","educational"],"description":"Video kind. See the VIDEO TYPE GUIDE on the list operation for product names and audio behavior."},"muscleGroups":{"type":"array","items":{"$ref":"#/components/schemas/MuscleGroup"}},"equipment":{"type":"array","items":{"$ref":"#/components/schemas/Equipment"}},"preview":{"description":"Preview video stream","allOf":[{"$ref":"#/components/schemas/VideoLinks"}]},"collectionName":{"type":"string"},"coach":{"type":"string","enum":["male","female"]},"tags":{"type":"array","items":{"type":"string"}},"skillLevel":{"type":"string","enum":["beginner","intermediate","advanced"]},"categories":{"type":"array","items":{"type":"string","enum":["strength","cardio","mobility","balance","endurance","flexibility","plyometrics","recovery","running"]}},"executionSide":{"type":"string","enum":["both","left","right","alternating"]},"showcasedReps":{"type":"number"},"bundle":{"description":"Asensei movement bundle for this exercise","allOf":[{"$ref":"#/components/schemas/ExerciseBundleRefDto"}]},"playsInLoop":{"type":"boolean","description":"When true, preview playback is intended to loop (for example smart clips aligned with reps or duration)."},"organization":{"nullable":true,"description":"Workspace (organization) this exercise belongs to. `null` when the workspace cannot be resolved.","allOf":[{"$ref":"#/components/schemas/Organization"}]},"audioInstructions":{"description":"Locale-specific instruction audio tracks. Emitted only for `kind: single-exercise` (the smart-clip product type that strips original audio in favor of multilingual instructions). When `?locale=` is supplied, narrowed to matching locales via the standard locale chain (English fallback); when omitted, returns all available locales so catalog UIs can render a \"languages available\" indicator. Empty array for `single-exercise` rows that have not yet been narrated. Always empty for the other kinds (`multi-exercise`, `educational`, `promo`, `class`) which keep their original audio baked into the video. Currently populated by `GET /v1/orgs/{organizationId}/video-assets`; other endpoints that share this list-item shape do not yet emit this field.","type":"array","items":{"$ref":"#/components/schemas/AudioDto"}},"duration":{"type":"number","description":"Duration of this exercise in seconds.","example":30},"reps":{"type":"number","description":"Target reps for reps-based exercises. Null for time-based.","example":12},"pace":{"type":"string","enum":["slow","medium","fast"],"nullable":true,"description":"Recommended pace/tempo.","example":"medium"},"weightLevel":{"type":"string","enum":["light","medium","heavy"],"nullable":true,"description":"Recommended weight level for reps-based exercises.","example":"medium"},"rpe":{"type":"number","description":"Rate of Perceived Exertion (0-10). Target intensity level.","minimum":0,"maximum":10,"example":8},"amrap":{"type":"boolean","description":"As Many Reps As Possible mode. Only applicable for time-based exercises.","example":false},"weight":{"type":"number","description":"Prescribed/target weight (0-1000). Unit in weightUnit.","minimum":0,"maximum":1000},"weightUnit":{"type":"string","enum":["metric","imperial"],"nullable":true,"description":"Unit for weight: metric (kg) or imperial (lbs)."}},"required":["id","createdAt","trainer","name","kind","muscleGroups","equipment","playsInLoop","organization","duration"]},"GroupExercisesListResponse":{"type":"object","properties":{"links":{"description":"Pagination envelope. Use `links.next` to fetch the next page; `links.total` is the count across all pages and is omitted on endpoints where it is too expensive to compute.","allOf":[{"$ref":"#/components/schemas/PageLinks"}]},"data":{"type":"array","items":{"$ref":"#/components/schemas/GroupExerciseInstanceDto"}}},"required":["links","data"]},"Goal":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the goal.","example":"goal-strength-gain"},"name":{"type":"string","description":"Display name of the goal. Localized based on locale query parameter.","example":"Strength Gain"},"nameTranslations":{"type":"object","additionalProperties":{"type":"string"},"description":"Localized goal names for different locales","example":{"en-US":"Weight Loss","de-DE":"Gewichtsverlust","fr-FR":"Perte de Poids"}}},"required":["id","name"]},"PlanListItem":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier (UUID) for the workout plan.","example":"12ab3efd45c67c1234566cd1"},"createdAt":{"format":"date-time","type":"string","description":"Timestamp when the plan was created.","example":"2023-10-26T10:00:00.000Z"},"updatedAt":{"format":"date-time","type":"string","description":"Timestamp when the plan was last updated.","example":"2023-10-27T11:30:00.000Z"},"trainer":{"description":"Reference to the trainer associated with the plan. Can be null.","allOf":[{"$ref":"#/components/schemas/TrainerRef"}]},"name":{"type":"string","description":"Display name of the workout plan. Localized based on locale query parameter.","example":"4-Week Strength Builder"},"description":{"type":"string","description":"Detailed description of the plan, including its purpose and target audience. Localized based on locale query parameter.","example":"A structured 4-week program designed to increase overall strength using compound lifts."},"difficulty":{"type":"string","enum":["beginner","intermediate","advanced"],"description":"Overall difficulty level of the plan.","example":"intermediate"},"visibility":{"type":"string","enum":["private","public","end-user-ai-generated"],"description":"Visibility level of the plan.","example":"public"},"durationInWeeks":{"type":"number","description":"Program duration in weeks (1-24). Use for filtering: ?durationInWeeks=8. Total workouts = durationInWeeks × workoutsPerWeek","example":8,"minimum":1,"maximum":24},"workoutsPerWeek":{"type":"number","description":"Weekly workout frequency (1-7). Total workouts = durationInWeeks × workoutsPerWeek","example":3,"minimum":1,"maximum":7},"adaptationReasoning":{"type":"string","description":"AI adaptation reasoning explanation (only present for AI-adapted programs)","example":"Program adapted to reduce intensity based on low sleep scores. Replaced 3 high-intensity workouts with recovery-focused alternatives."},"originalProgramId":{"type":"string","description":"Original program ID if this program was adapted from another (only present for AI-adapted programs)","example":"507f1f77bcf86cd799439016"},"preview":{"description":"Links to a preview video for the plan (if available).","allOf":[{"$ref":"#/components/schemas/VideoLinks"}]},"goals":{"description":"List of primary goals this plan is designed for (e.g., Strength, Endurance, Weight Loss).","type":"array","items":{"$ref":"#/components/schemas/Goal"}}},"required":["id","createdAt","updatedAt","name","description","difficulty","visibility","goals"]},"PlanListResponse":{"type":"object","properties":{"links":{"description":"Pagination envelope. Use `links.next` to fetch the next page; `links.total` is the count across all pages and is omitted on endpoints where it is too expensive to compute.","allOf":[{"$ref":"#/components/schemas/PageLinks"}]},"data":{"description":"The array of plan list items for the current page.","type":"array","items":{"$ref":"#/components/schemas/PlanListItem"}},"explanation":{"type":"string","description":"Explanation for how this list was filtered or sorted"}},"required":["links","data"]},"PlanRecommendationRequestDto":{"type":"object","properties":{"endUserProfileDetails":{"description":"Detailed user profile information for personalized recommendations","allOf":[{"$ref":"#/components/schemas/EndUserProfileDetailsDto"}]},"goalIds":{"description":"Optional goal IDs at the root of the body (mobile clients; max 2; first = primary). Merged with endUserProfileDetails.goalIds for library matching.","example":["63c92926f920a9005c4e61a0"],"maxItems":2,"type":"array","items":{"type":"string"}},"locale":{"type":"string","description":"Preferred BCP-47 locale for recommendation text when the stack supports it.","example":"en-US"}}},"RecommendedPlanDto":{"type":"object","properties":{"id":{"type":"string","description":"Plan ID"},"name":{"type":"string","description":"Plan name"},"description":{"type":"string","description":"Plan description"},"difficulty":{"type":"string","enum":["beginner","intermediate","advanced"]},"thumbnailUrl":{"type":"object","description":"URL to plan thumbnail image","nullable":true},"recommendation":{"type":"string","description":"Reasoning for this recommendation"},"goals":{"description":"Plan goals","items":{"type":"array"},"type":"array"},"preview":{"description":"Preview video (playable URL when available). url is empty when only a thumbnail image exists.","allOf":[{"$ref":"#/components/schemas/VideoLinks"}]}},"required":["id","name","description","difficulty","thumbnailUrl","recommendation","goals"]},"PlanRecommendationResponseDto":{"type":"object","properties":{"plans":{"description":"List of recommended plans (max 12)","type":"array","items":{"$ref":"#/components/schemas/RecommendedPlanDto"}},"reasoning":{"type":"string","description":"Overall explanation for the recommendation strategy used"}},"required":["plans","reasoning"]},"DurationOptionsDto":{"type":"object","properties":{"minWeeks":{"type":"number","description":"Minimum program duration in weeks","minimum":1,"maximum":24,"example":4},"maxWeeks":{"type":"number","description":"Maximum program duration in weeks","minimum":1,"maximum":24,"example":8}}},"PlanGenerationRequestDto":{"type":"object","properties":{"goalIds":{"description":"Array of goal IDs for the program (max 2; first = primary, second = secondary)","example":["507f1f77bcf86cd799439011","507f1f77bcf86cd799439012"],"maxItems":2,"type":"array","items":{"type":"string"}},"difficulty":{"type":"string","enum":["beginner","intermediate","advanced"],"description":"Difficulty level for the program","example":"intermediate"},"workoutsPerWeek":{"type":"number","description":"Number of workouts per week","minimum":1,"maximum":7,"example":3},"durationOptions":{"description":"Duration preferences for the program","allOf":[{"$ref":"#/components/schemas/DurationOptionsDto"}]},"endUserProfileDetails":{"description":"Detailed user profile information for personalized program generation","allOf":[{"$ref":"#/components/schemas/EndUserProfileDetailsDto"}]},"workoutCollectionSources":{"type":"array","description":"Sources of workout collections for plan generation (`template` | `team`). Defaults to both if omitted. Field name is `workoutCollectionSources` — not `workoutSources` (that name is only valid on plan adapt).","example":["team","template"],"items":{"type":"string","enum":["team","template"]}},"userRequirements":{"type":"string","description":"High-level context, definitions, and guidelines for program generation. Provides customer-specific grounding for training methodologies, progression schemes, and program structure.","example":"Progressive overload with 3-week cycles. Include deload weeks every 4th week. Focus on unilateral movements for balance.","maxLength":2000},"locale":{"type":"string","description":"Optional BCP-47 locale (e.g. \"fr-FR\", \"de-DE\", \"en-GB\"). Localizes the AI program name/description and nested workout fields. Omit for English-only output. Unsupported values return 400.","example":"fr-FR"}}},"ApiWorkoutDto":{"type":"object","properties":{"id":{"type":"string","description":"Workout ID","example":"507f1f77bcf86cd799439017"},"name":{"type":"string","description":"Workout name (canonical English base)","example":"Upper Body Strength"},"nameLocalized":{"type":"string","description":"Workout name resolved for the requested locale (silent en-US fallback). Additive localization field.","example":"Force du haut du corps"},"duration":{"type":"number","description":"Workout duration in milliseconds","example":900000},"difficulty":{"type":"string","enum":["beginner","intermediate","advanced"],"description":"Workout difficulty level","example":"intermediate"},"description":{"type":"string","description":"Workout description (canonical English base)"},"descriptionLocalized":{"type":"string","description":"Workout description resolved for the requested locale (silent en-US fallback). Additive localization field."}},"required":["id","name","duration","difficulty"]},"PlanGenerationResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Generated program ID when persisted. Present only if the request included `endUserProfileDetails.endUserId`; omit means no top-level id was stored.","example":"507f1f77bcf86cd799439017"},"name":{"type":"string","description":"Generated plan name (canonical English base)","example":"4-Week Intermediate General Fitness"},"nameTranslations":{"type":"object","description":"Per-locale plan name. Always includes en-US; includes the requested locale when a non-English locale was requested.","example":{"en-US":"4-Week Intermediate General Fitness","fr-FR":"Forme Générale Intermédiaire 4 Semaines"}},"description":{"type":"string","description":"Generated plan description (canonical English base)","example":"A comprehensive 8-week program designed to build strength and muscle mass."},"descriptionTranslations":{"type":"object","description":"Per-locale plan description. Always includes en-US; includes the requested locale when a non-English locale was requested.","example":{"en-US":"A comprehensive 8-week program designed to build strength and muscle mass.","fr-FR":"Un programme complet de 8 semaines conçu pour développer la force et la masse musculaire."}},"difficulty":{"type":"string","enum":["beginner","intermediate","advanced"],"description":"Plan difficulty level","example":"intermediate"},"difficultyLabel":{"type":"string","description":"Localized human-readable difficulty label for the requested locale (silent en-US fallback).","example":"Intermédiaire"},"goalIds":{"description":"Array of goal IDs the plan addresses","example":["507f1f77bcf86cd799439011","507f1f77bcf86cd799439012"],"type":"array","items":{"type":"string"}},"workouts":{"description":"Array of workouts in the plan","type":"array","items":{"$ref":"#/components/schemas/ApiWorkoutDto"}},"durationInWeeks":{"type":"number","description":"Total number of weeks in the program","example":8},"workoutsPerWeek":{"type":"number","description":"Number of workouts per week","example":3}},"required":["name","nameTranslations","description","descriptionTranslations","difficulty","goalIds","workouts","durationInWeeks","workoutsPerWeek"]},"PlanAdaptationRequestDto":{"type":"object","properties":{"endUserProfileId":{"type":"string","description":"End user profile ID (24-char hex org member id). Required on Content API — adapted programs are persisted under this user (omit → 400). Also used for wearable/session/feedback context. When this user has the source plan active, only the next workout slot is adapted.","example":"64e3bca9d1b7e600141a9712"},"endUserProfileDetails":{"description":"User profile information for program adaptation","allOf":[{"$ref":"#/components/schemas/AdaptationEndUserProfileDetailsDto"}]},"workoutSources":{"type":"array","description":"Workout sources for additions/replacements (`template` | `team`). Field name is `workoutSources` — not `workoutCollectionSources` (that name is only valid on plan generate).","example":["template","team"],"items":{"type":"string","enum":["template","team"]}},"userGuidance":{"type":"string","description":"User free text for guidance/feedback/context/injury/environment/constraints","example":"I have a slight knee injury, avoid high-impact exercises. Reduce program intensity for recovery.","maxLength":2000}},"required":["endUserProfileId","endUserProfileDetails","workoutSources"]},"ApiAdaptedWorkoutDto":{"type":"object","properties":{"id":{"type":"string","description":"Workout ID","example":"507f1f77bcf86cd799439017"},"name":{"type":"string","description":"Workout name","example":"Upper Body Strength"},"duration":{"type":"number","description":"Workout duration in seconds","example":2700},"difficulty":{"type":"string","enum":["beginner","intermediate","advanced"],"description":"Workout difficulty"},"description":{"type":"string","description":"Workout description"},"position":{"type":"number","description":"Position in program (0-based)"},"action":{"type":"string","description":"Action taken","enum":["kept","replaced","added"]}},"required":["id","name"]},"PlanAdaptationResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Adapted program ID","example":"507f1f77bcf86cd799439017"},"name":{"type":"string","description":"Adapted program name","example":"Adapted: 8-Week Strength Program"},"description":{"type":"string","description":"Program description"},"workouts":{"description":"Workouts in adapted program","type":"array","items":{"$ref":"#/components/schemas/ApiAdaptedWorkoutDto"}},"totalWorkouts":{"type":"number","description":"Total number of workouts"},"durationInWeeks":{"type":"number","description":"Program duration in weeks"},"workoutsPerWeek":{"type":"number","description":"Workouts per week"},"difficulty":{"type":"string","enum":["beginner","intermediate","advanced"],"description":"Program difficulty"},"adaptationReasoning":{"type":"string","description":"Explanation of adaptations made"},"wasDuplicated":{"type":"boolean","description":"True if program was duplicated from team program"},"originalProgramId":{"type":"string","description":"Original program ID if duplicated"}},"required":["id","name","workouts","totalWorkouts","durationInWeeks","workoutsPerWeek","adaptationReasoning"]},"OrganizationMetadataResponse":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the organization","example":"12ab3efd45c67c1234566cd1"},"name":{"type":"string","description":"The name of the organization","example":"Hyperhuman LLC"},"handle":{"type":"object","description":"The organization handle (typically used in URLs)","example":"hyperhuman"},"logoUrl":{"type":"object","description":"URL to the organization logo","example":"https://assets.example.com/logos/hyperhuman-logo.png"},"watermarkUrl":{"type":"object","description":"URL to the brand watermark used in workout video exports and the embedded player. Square PNG with transparent background recommended.","example":"https://assets.example.com/logos/hyperhuman-watermark.png"},"description":{"type":"object","description":"The description of the organization","example":"A company dedicated to fitness and wellness solutions"},"website":{"type":"object","description":"The website URL of the organization","example":"https://hyperhuman.cc"},"brandMainColor":{"type":"object","description":"The primary brand color (hex format)","example":"#11CC88"},"brandSecondaryColor":{"type":"object","description":"The secondary brand color (hex format)","example":"#F3F8F8"},"brandTextColor":{"type":"object","description":"The text color that goes with the brand colors (hex format)","example":"#FFFFFF"},"clientsJoinSetting":{"type":"string","description":"Setting that controls how clients can join the organization","enum":["OPEN","INVITE_ONLY","SUBSCRIPTION_REQUIRED"],"example":"OPEN","default":"OPEN"},"hasAssenseiModuleActive":{"type":"boolean","description":"Whether the organization has the Asensei Assessment module active (AI form analysis)","example":false},"hasWearableModuleActive":{"type":"boolean","description":"Whether the organization has the ROOK Wearables module active (health data sync)","example":false},"hasWhiteLabelAppActive":{"type":"boolean","description":"Whether the organization has a White-Label App active (custom branded consumer app)","example":false},"iosAppStoreId":{"type":"object","description":"Numeric iOS App Store ID of the branded app. Used by the end-user web app to build App Store links and deep links. Only meaningful when hasWhiteLabelAppActive is true.","example":"1559570894"},"androidPackageName":{"type":"object","description":"Android package name of the branded app. Used by the end-user web app to build Google Play links and the custom deep-link scheme. Only meaningful when hasWhiteLabelAppActive is true.","example":"cc.hyperhuman.club"},"aiChatEnabled":{"type":"boolean","description":"Member-app visibility for AI chat (admin toggle AND org chat capability). Does **not** gate Content API `/v1/chat/...` — API access uses the key + capability checks on those routes.","example":true},"aiGenerationEnabled":{"type":"boolean","description":"Member-app visibility for AI workout/program generation (admin toggle AND org generation capability). Does **not** gate Content API `.../workouts/generate` or `.../plans/generate` — those use separate API capability asserts.","example":true},"aiAdaptationEnabled":{"type":"boolean","description":"Member-app visibility for AI workout/program adaptation (admin toggle AND org adaptation capability). Does **not** gate Content API `.../adapt` routes — those use separate API capability asserts.","example":true},"aiRecommendationEnabled":{"type":"boolean","description":"Member-app visibility for AI recommend. Defaults to true when unset. Does **not** gate Content API `.../recommend` routes.","example":true},"insightsEnabled":{"type":"boolean","description":"Member-app visibility for Daily Digest / Health HQ. Pure capability (no admin toggle): true when the team plan carries dailyDigestInsights or the org sells an insights-entitled club tier. Content API insights routes still enforce their own capability checks.","example":true}},"required":["id","name","clientsJoinSetting","hasAssenseiModuleActive","hasWearableModuleActive","hasWhiteLabelAppActive","aiChatEnabled","aiGenerationEnabled","aiAdaptationEnabled","aiRecommendationEnabled","insightsEnabled"]},"OrganizationBrandingNewsItemDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique item ID generated from article URL and title.","example":"rss-12244532"},"title":{"type":"string","description":"Article title.","example":"How to Build a Sustainable Training Routine"},"description":{"type":"string","description":"Short article summary.","example":"A practical guide for building consistency across training cycles."},"url":{"type":"string","description":"Article URL.","example":"https://example.com/articles/sustainable-training-routine"},"imageUrl":{"type":"string","description":"Article image URL if available.","example":"https://cdn.example.com/images/article-cover.jpg"},"source":{"type":"string","description":"Source name derived from feed host.","example":"Example"},"channelTitle":{"type":"string","description":"Feed/channel title when available.","example":"Example Fitness Journal"},"categories":{"description":"Article categories/tags.","example":["Training","Recovery"],"type":"array","items":{"type":"string"}},"publishedAt":{"type":"string","description":"Published date in ISO format.","example":"2026-05-11T17:30:00.000Z"}},"required":["id","title","url","source","categories","publishedAt"]},"OrganizationBrandingNewsResponse":{"type":"object","properties":{"items":{"description":"News items for organization branding section.","type":"array","items":{"$ref":"#/components/schemas/OrganizationBrandingNewsItemDto"}}},"required":["items"]},"TeamClientsJoinSetting":{"type":"string","enum":["OPEN","INVITE_ONLY","SUBSCRIPTION_REQUIRED"]},"FreeJoinOptionDto":{"type":"object","properties":{"id":{"type":"string","description":"Product unique identifier","example":"507f1f77bcf86cd799439011"},"name":{"type":"string","description":"Product name/title","example":"Club Free Plan"},"description":{"type":"string","description":"Product description","example":"Free access with basic features"},"hasAutoJoin":{"type":"boolean","description":"Whether this product includes auto-join capability","example":true},"stripeProductId":{"type":"string","description":"Stripe product ID for payment processing","example":"prod_SMcyPrDHt0ROlQ"}},"required":["id","name","description","hasAutoJoin","stripeProductId"]},"OrganizationJoinOptionsResponse":{"type":"object","properties":{"clientsJoinSetting":{"description":"High-level team join setting that controls client access","example":"OPEN","$ref":"#/components/schemas/TeamClientsJoinSetting"},"canJoinDirectly":{"type":"boolean","description":"Whether users can join directly without any requirements (OPEN setting)","example":true},"requiresSubscription":{"type":"boolean","description":"Whether the team requires a subscription to join (SUBSCRIPTION_REQUIRED setting)","example":false},"inviteOnlyMode":{"type":"boolean","description":"Whether the team only allows invited users to join (INVITE_ONLY setting)","example":false},"hasFreePlanWithAutoJoin":{"type":"boolean","description":"Whether the team offers any free plans with auto-join capability","example":true},"freeJoinOptions":{"description":"Available free products that include auto-join capability","type":"array","items":{"$ref":"#/components/schemas/FreeJoinOptionDto"}},"totalProductsAvailable":{"type":"number","description":"Total number of subscription products available (including paid)","example":3}},"required":["clientsJoinSetting","canJoinDirectly","requiresSubscription","inviteOnlyMode","hasFreePlanWithAutoJoin","freeJoinOptions"]},"PlanProgressResponseDto":{"type":"object","properties":{"data":{"type":"object","nullable":true,"description":"A map where keys are position indices (as strings) and values contain completion status, latest completion date, and workout details. Returns `null` when the user has no active plan.","additionalProperties":{"type":"object","properties":{"completed":{"type":"boolean"},"latestCompletionDate":{"type":"string","format":"date-time"},"workoutName":{"type":"string"},"difficulty":{"type":"string"},"duration":{"type":"number"},"categories":{"type":"array","items":{"type":"string"}},"workoutId":{"type":"string"},"positionInPlan":{"type":"number"}}},"example":{"0":{"completed":true,"latestCompletionDate":"2023-07-22T15:30:45.123Z","workoutName":"Full Body HIIT","difficulty":"intermediate","duration":1800000,"categories":["Strength","HIIT","Full Body"],"workoutId":"60f1b3b3b3b3b3b3b3b3b3b3","positionInPlan":0},"1":{"completed":false,"latestCompletionDate":null,"workoutName":"Lower Body Strength","difficulty":"advanced","duration":2400000,"categories":["Strength","Lower Body"],"workoutId":"60f1b3b3b3b3b3b3b3b3b3b4","positionInPlan":1},"2":{"completed":false,"latestCompletionDate":null,"workoutName":"Full Body HIIT","difficulty":"intermediate","duration":1800000,"categories":["Strength","HIIT","Full Body"],"workoutId":"60f1b3b3b3b3b3b3b3b3b3b3","positionInPlan":2}}}},"required":["data"]},"ActivePlanResponseDto":{"type":"object","properties":{"data":{"type":"object","description":"The active workout collection access object or null if no active plan","nullable":true}},"required":["data"]},"StartPlanBody":{"type":"object","properties":{"planId":{"type":"string","description":"The plan ID to start as the active plan.","example":"60f1b3b3b3b3b3b3b3b3b3b3"},"restart":{"type":"boolean","description":"When true, resets the plan start date so only workouts completed after this call count toward progress. When false or omitted and this plan is already active, the existing access is returned unchanged.","example":false},"autoAdapt":{"type":"boolean","description":"Enable automatic next-workout adaptation for this active enrollment.","example":false}},"required":["planId"]},"PlanResponseDto":{"type":"object","properties":{"data":{"type":"object","description":"The workout collection access object"}},"required":["data"]},"UpdateActivePlanSettingsBody":{"type":"object","properties":{"autoAdapt":{"type":"boolean","description":"Enable or disable automatic next-workout adaptation on the active enrollment.","example":true}}},"EndUserProfileDto":{"type":"object","properties":{"email":{"type":"string","description":"User email address"},"firstName":{"type":"string","description":"User first name"},"lastName":{"type":"string","description":"User last name"},"externalUUID":{"type":"string","description":"External unique identifier provided by the API client"},"joinedDate":{"format":"date-time","type":"string","description":"When the user joined the team"},"status":{"type":"string","description":"User membership status","enum":["active","suspended"]},"endUserId":{"type":"string","description":"Internal user ID. Present only when the API key is for this organization and the end user has an active (non-suspended) team membership. Use in enduser-scoped endpoints (e.g. plans, insights).","example":"507f1f77bcf86cd799439011"}},"required":["email","joinedDate","status"]},"EndUserProfileListResponse":{"type":"object","properties":{"links":{"description":"Pagination envelope. Use `links.next` to fetch the next page; `links.total` is the count across all pages and is omitted on endpoints where it is too expensive to compute.","allOf":[{"$ref":"#/components/schemas/PageLinks"}]},"data":{"type":"array","items":{"$ref":"#/components/schemas/EndUserProfileDto"}},"total":{"type":"number","deprecated":true,"description":"Deprecated. Use `links.total` instead. Kept for one minor version for backwards compatibility."}},"required":["links","data","total"]},"EndUserInviteItem":{"type":"object","properties":{"email":{"type":"string","description":"Email address of the user to invite"},"externalUUID":{"type":"string","description":"External unique identifier for this user"},"firstName":{"type":"string","description":"First name of the user"},"lastName":{"type":"string","description":"Last name of the user"}},"required":["email"]},"InviteEndUsersDto":{"type":"object","properties":{"users":{"description":"List of users to invite","type":"array","items":{"$ref":"#/components/schemas/EndUserInviteItem"}},"sendInviteEmail":{"type":"boolean","description":"Optional per-request override for Hyperhuman transactional invite emails. Omit to use the organization Invite emails setting (on by default). `false` skips Hyperhuman invite email for this batch when you send your own. `true` sends even if the organization setting is off. When present, this field wins over the organization setting. Pending invite records are always created either way. Updating an existing pending invite never re-sends email.","example":false}},"required":["users"]},"UserIdentifierDto":{"type":"object","properties":{"email":{"type":"string","description":"Email address of the user"},"externalUUID":{"type":"string","description":"External UUID of the user"}}},"InsightSignalDto":{"type":"object","properties":{"id":{"type":"string","description":"Stable identifier of the detected signal.","example":"streak-at-risk-workout"},"kind":{"type":"string","description":"Kind of detected signal.","enum":["streak_at_risk","personal_best","milestone","day_of_week_pattern","time_of_day_pattern","adherence_trend","pace","correlation","plateau","recovery_debt","cta","ai_pattern"],"example":"streak_at_risk"},"pillar":{"type":"string","description":"Home pillar of the signal. Each signal belongs to exactly one pillar.","enum":["health_pulse","training","recovery","movement","nutrition","body"],"example":"training"},"priority":{"type":"number","description":"Priority (1 = highest). Celebrations are 1, act-now nudges 2, attention items 3, trends 4-5, CTAs 6, AI-proposed patterns 7.","example":2},"label":{"type":"string","description":"Short user-facing text for the signal.","example":"Complete a workout today to keep your 5-day streak alive"},"detail":{"type":"string","description":"Optional supporting evidence.","example":"Current workout streak: 5 days"},"celebration":{"type":"boolean","description":"True for achievements worth celebrating (new best, milestone).","example":false},"isNewToday":{"type":"boolean","description":"True when the signal was triggered by today's data.","example":false},"source":{"type":"string","description":"Signal source. AI-proposed patterns carry lower trust than deterministic ones.","enum":["deterministic","ai"],"example":"deterministic"}},"required":["id","kind","pillar","priority","label","source"]},"InsightPillarDto":{"type":"object","properties":{"type":{"type":"string","description":"The type of insight pillar.","enum":["health_pulse","training","recovery","movement","nutrition","body"],"example":"health_pulse"},"status":{"type":"string","description":"Status indicator for this pillar.","enum":["green","yellow","red"],"example":"green"},"headline":{"type":"string","description":"Headline summarizing the pillar insight (1-2 lines). Does not include pillar type prefix.","example":"82 (+5 vs 7-day). Driver: Sleep."},"action":{"type":"string","description":"Recommended action for this pillar.","example":"Maintain your sleep routine"},"confidence":{"type":"number","description":"Confidence score for this pillar (0-1).","example":0.85},"score":{"type":"number","description":"Score value if applicable (0-100).","example":82},"delta":{"type":"number","description":"Change from baseline/average.","example":5},"deltaDirection":{"type":"string","description":"Direction of change.","enum":["up","down","stable"],"example":"up"},"driver":{"type":"string","description":"Primary driver for health pulse pillar.","enum":["sleep","exercise","body","nutrition","adherence"],"example":"sleep"},"weeklyCompletions":{"type":"number","description":"Number of workouts completed this week.","example":4},"streak":{"type":"number","description":"Current workout streak in days.","example":5},"formScore":{"type":"number","description":"Average form score from AI assessments.","example":78},"formTrend":{"type":"string","description":"Form score trend.","enum":["improving","declining","stable","insufficient-data"],"example":"improving"},"recentCoachingFocus":{"type":"string","description":"Most common coaching feedback.","example":"Keep your knees aligned with your toes"},"isFallback":{"type":"boolean","description":"Indicates if this pillar used fallback data.","example":false},"nutritionScore":{"type":"number","description":"Nutrition score (0-100) for nutrition pillar.","example":72},"caloriesConsumedKcal":{"type":"number","description":"Calories consumed (kcal) for nutrition pillar.","example":1850},"personalBests":{"type":"array","description":"Personal best metrics for this pillar (90-day window).","items":{"type":"object","properties":{"metric":{"type":"string"},"value":{"type":"number"},"label":{"type":"string"}}}},"streaks":{"type":"array","description":"Streaks for this pillar (90-day window).","items":{"type":"object","properties":{"type":{"type":"string"},"value":{"type":"number"},"label":{"type":"string"}}}},"milestones":{"type":"array","description":"Milestones for this pillar (90-day window). Only present on the day a milestone is crossed.","items":{"type":"object","properties":{"type":{"type":"string"},"value":{"type":"number"},"label":{"type":"string"}}}},"insights":{"description":"Detected signals assigned to this pillar (max 3, sorted by priority).","type":"array","items":{"$ref":"#/components/schemas/InsightSignalDto"}}},"required":["type","status","headline","action","confidence"]},"UserDigestResponse":{"type":"object","properties":{"userId":{"type":"string","description":"User ID the digest is for.","example":"63415bf67a9c7000126616c1"},"organizationId":{"type":"string","description":"Organization ID.","example":"63415bf67a9c7000126616c1"},"date":{"format":"date-time","type":"string","description":"Date the digest is for.","example":"2026-01-10T00:00:00.000Z"},"pillars":{"description":"Array of insight pillars (3-5 items).","type":"array","items":{"$ref":"#/components/schemas/InsightPillarDto"}},"todaysFocus":{"type":"string","description":"The single most important action for today.","example":"Complete: Full Body Strength Workout"},"dataCompleteness":{"type":"number","description":"Data completeness score (0-1). Higher means more data sources available.","example":0.75},"generatedAt":{"format":"date-time","type":"string","description":"Timestamp when the digest was generated.","example":"2026-01-10T08:30:00.000Z"},"highlights":{"description":"Top detected signals across all pillars (deterministic patterns, celebrations, CTAs, and AI-proposed extras), sorted by priority.","type":"array","items":{"$ref":"#/components/schemas/InsightSignalDto"}}},"required":["userId","organizationId","date","pillars","todaysFocus","dataCompleteness","generatedAt"]},"PillarDetailResponse":{"type":"object","properties":{"type":{"type":"string","description":"The type of insight pillar.","enum":["health_pulse","training","recovery","movement","nutrition","body"],"example":"health_pulse"},"status":{"type":"string","description":"Status indicator for this pillar.","enum":["green","yellow","red"],"example":"green"},"headline":{"type":"string","description":"Headline summarizing the pillar insight (1-2 lines). Does not include pillar type prefix.","example":"82 (+5 vs 7-day). Driver: Sleep."},"action":{"type":"string","description":"Recommended action for this pillar.","example":"Maintain your sleep routine"},"confidence":{"type":"number","description":"Confidence score for this pillar (0-1).","example":0.85},"score":{"type":"number","description":"Score value if applicable (0-100).","example":82},"delta":{"type":"number","description":"Change from baseline/average.","example":5},"deltaDirection":{"type":"string","description":"Direction of change.","enum":["up","down","stable"],"example":"up"},"driver":{"type":"string","description":"Primary driver for health pulse pillar.","enum":["sleep","exercise","body","nutrition","adherence"],"example":"sleep"},"weeklyCompletions":{"type":"number","description":"Number of workouts completed this week.","example":4},"streak":{"type":"number","description":"Current workout streak in days.","example":5},"formScore":{"type":"number","description":"Average form score from AI assessments.","example":78},"formTrend":{"type":"string","description":"Form score trend.","enum":["improving","declining","stable","insufficient-data"],"example":"improving"},"recentCoachingFocus":{"type":"string","description":"Most common coaching feedback.","example":"Keep your knees aligned with your toes"},"isFallback":{"type":"boolean","description":"Indicates if this pillar used fallback data.","example":false},"nutritionScore":{"type":"number","description":"Nutrition score (0-100) for nutrition pillar.","example":72},"caloriesConsumedKcal":{"type":"number","description":"Calories consumed (kcal) for nutrition pillar.","example":1850},"personalBests":{"type":"array","description":"Personal best metrics for this pillar (90-day window).","items":{"type":"object","properties":{"metric":{"type":"string"},"value":{"type":"number"},"label":{"type":"string"}}}},"streaks":{"type":"array","description":"Streaks for this pillar (90-day window).","items":{"type":"object","properties":{"type":{"type":"string"},"value":{"type":"number"},"label":{"type":"string"}}}},"milestones":{"type":"array","description":"Milestones for this pillar (90-day window). Only present on the day a milestone is crossed.","items":{"type":"object","properties":{"type":{"type":"string"},"value":{"type":"number"},"label":{"type":"string"}}}},"insights":{"description":"Detected signals assigned to this pillar (max 3, sorted by priority).","type":"array","items":{"$ref":"#/components/schemas/InsightSignalDto"}},"lastWorkout":{"type":"object","description":"Last workout information for training pillar."},"nextSession":{"type":"object","description":"Next scheduled session for training pillar."},"bestLever":{"type":"string","description":"Best training lever for training pillar.","enum":["strength","cardio","mobility"]},"sleepScore":{"type":"number","description":"Sleep score for recovery pillar.","example":75},"mainIssue":{"type":"string","description":"Main issue identified for recovery pillar.","example":"Sleep efficiency"},"yesterdayIntensity":{"type":"string","description":"Yesterday's workout intensity for recovery pillar.","enum":["low","moderate","high"]},"activityLevel":{"type":"string","description":"Activity level for movement pillar.","enum":["low","moderate","high"]},"suggestedMinutes":{"type":"number","description":"Suggested movement minutes for movement pillar.","example":20},"cardioTrend":{"type":"string","description":"Cardio trend for movement pillar.","enum":["improving","declining","stable","insufficient-data"]},"bodyScore":{"type":"number","description":"Body score for body pillar.","example":72},"weeklyTrend":{"type":"string","description":"Weekly trend for body pillar.","enum":["improving","declining","stable","insufficient-data"]},"streakDays":{"type":"number","description":"Streak days for body/momentum pillar.","example":7},"biggestLever":{"type":"string","description":"Biggest lever for improvement.","enum":["sleep","nutrition","movement"]},"proteinG":{"type":"number","description":"Protein (g) for nutrition pillar.","example":120},"carbsG":{"type":"number","description":"Carbohydrates (g) for nutrition pillar.","example":200},"fatG":{"type":"number","description":"Fat (g) for nutrition pillar.","example":65},"mealsLoggedToday":{"type":"number","description":"Number of meals/entries logged today for nutrition pillar.","example":6},"nutritionMeals":{"type":"array","description":"Per-entry nutrition breakdown for the day (up to 20 entries). Photo-logged entries include a meal description.","items":{"type":"object","properties":{"at":{"type":"string","format":"date-time"},"caloriesKcal":{"type":"number"},"proteinG":{"type":"number"},"carbsG":{"type":"number"},"fatG":{"type":"number"},"description":{"type":"string"}}}},"nutritionWin":{"type":"string","description":"Positive nutrition behavior identified for nutrition pillar.","example":"Good protein intake (195g)"},"nutritionWatch":{"type":"string","description":"Area to improve for nutrition pillar.","example":"High calorie day – confirm aligned with goal"},"readinessBand":{"type":"string","description":"Readiness band indicating training capacity for today.","enum":["push","maintain","recover"],"example":"maintain"},"readinessMessage":{"type":"string","description":"Short message explaining the readiness recommendation.","example":"Sleep down vs baseline - keep intensity moderate."},"recommendedIntensity":{"type":"string","description":"Recommended workout intensity based on readiness.","enum":["light","moderate","high"],"example":"moderate"},"hrvBand":{"type":"string","description":"HRV status relative to personal baseline.","enum":["low","normal","high"],"example":"normal"},"riskLevel":{"type":"string","description":"Risk level for burnout/overreaching.","enum":["low","moderate","high"],"example":"moderate"},"riskTriggers":{"description":"Factors that triggered the risk flag (max 3).","example":["Sleep trend declining","RPE consistently high"],"type":"array","items":{"type":"string"}},"formCue":{"type":"string","description":"Primary form cue to focus on today.","example":"Keep knees tracking over toes"},"formSuggestion":{"type":"string","description":"Suggested adjustment if form is declining.","example":"Slow tempo + lighter load today"},"repAccuracy":{"type":"number","description":"Average rep accuracy from AI assessments.","example":82},"pacingStatus":{"type":"string","description":"Program pacing status for the current week.","enum":["on_track","behind","ahead"],"example":"on_track"},"pacingMessage":{"type":"string","description":"Short message about program pacing.","example":"3/4 workouts this week. On pace."},"workoutsPlannedThisWeek":{"type":"number","description":"Planned workouts per week based on user profile.","example":4},"workoutsCompletedThisWeek":{"type":"number","description":"Workouts completed this week.","example":3},"currentWeek":{"type":"number","description":"Current week number in the program (1-based).","example":2},"totalWeeks":{"type":"number","description":"Total weeks in the program.","example":8},"why":{"description":"Reasons explaining the recommendation (max 3).","example":["HRV below baseline","Sleep score declining","High intensity yesterday"],"type":"array","items":{"type":"string"}},"alternativeActions":{"description":"Safe alternative actions (max 2).","example":["Do planned workout at moderate intensity","Swap to Mobility + Zone 2"],"type":"array","items":{"type":"string"}}},"required":["type","status","headline","action","confidence"]},"NutritionPhotoEstimateItemDto":{"type":"object","properties":{"name":{"type":"string","description":"Detected food item name","example":"Grilled chicken breast"},"estimatedPortion":{"type":"string","description":"Estimated portion size","example":"150 g"},"caloriesKcal":{"type":"number","description":"Estimated calories in kcal","example":248},"proteinG":{"type":"number","description":"Estimated protein in grams","example":46},"carbsG":{"type":"number","description":"Estimated carbohydrates in grams","example":0},"fatG":{"type":"number","description":"Estimated fat in grams","example":5}},"required":["name"]},"NutritionPhotoTotalsDto":{"type":"object","properties":{"caloriesKcal":{"type":"number","description":"Calories in kcal","example":522},"proteinG":{"type":"number","description":"Protein in grams","example":53},"carbsG":{"type":"number","description":"Carbohydrates in grams","example":56},"fatG":{"type":"number","description":"Fat in grams","example":7}},"required":["caloriesKcal","proteinG","carbsG","fatG"]},"NutritionPhotoEstimateDto":{"type":"object","properties":{"isFood":{"type":"boolean","description":"Whether the photo shows food","example":true},"confidence":{"type":"number","description":"Confidence of the macro estimate (0-1)","example":0.86},"mealDescription":{"type":"string","description":"Plain-language description of the detected meal","example":"Grilled chicken breast with white rice and mixed salad"},"items":{"description":"Per-item food breakdown","type":"array","items":{"$ref":"#/components/schemas/NutritionPhotoEstimateItemDto"}},"totals":{"description":"Estimated macro totals for the meal","allOf":[{"$ref":"#/components/schemas/NutritionPhotoTotalsDto"}]}},"required":["isFood","confidence","mealDescription","items","totals"]},"AnalyzeNutritionPhotoData":{"type":"object","properties":{"pendingLogId":{"type":"string","description":"Pending log id to pass to the confirm endpoint","example":"665f1b2a9c7000126616c1aa"},"expiresAt":{"format":"date-time","type":"string","description":"Expiry of the pending log (1 hour after analysis)","example":"2026-06-12T13:24:00.000Z"},"estimate":{"$ref":"#/components/schemas/NutritionPhotoEstimateDto"}},"required":["pendingLogId","expiresAt","estimate"]},"AnalyzeNutritionPhotoResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AnalyzeNutritionPhotoData"}},"required":["data"]},"NutritionPhotoTotalsOverrideDto":{"type":"object","properties":{"caloriesKcal":{"type":"number","description":"Corrected calories in kcal","minimum":0,"example":600},"proteinG":{"type":"number","description":"Corrected protein in grams","minimum":0,"example":45},"carbsG":{"type":"number","description":"Corrected carbohydrates in grams","minimum":0,"example":70},"fatG":{"type":"number","description":"Corrected fat in grams","minimum":0,"example":12}}},"ConfirmNutritionPhotoLogBody":{"type":"object","properties":{"totals":{"description":"Optional corrected totals to log instead of the AI estimate. Items and description stay as estimated.","allOf":[{"$ref":"#/components/schemas/NutritionPhotoTotalsOverrideDto"}]}}},"ConfirmNutritionPhotoLogData":{"type":"object","properties":{"logged":{"description":"Values that were logged","allOf":[{"$ref":"#/components/schemas/NutritionPhotoTotalsDto"}]},"dayTotals":{"type":"object","description":"Day's running totals after this log","properties":{"caloriesConsumedKcal":{"type":"number","example":1290},"proteinG":{"type":"number","example":98},"carbsG":{"type":"number","example":132},"fatG":{"type":"number","example":41}}},"nutritionScore":{"type":"object","description":"Nutrition score for the day (0-100), null when not computable","nullable":true,"example":78},"mealDescription":{"type":"string","description":"Detected meal description (persisted on the nutrition entry)","example":"Grilled chicken breast with white rice and mixed salad"},"items":{"description":"Per-item food breakdown (persisted on the nutrition entry)","type":"array","items":{"$ref":"#/components/schemas/NutritionPhotoEstimateItemDto"}}},"required":["logged","dayTotals","nutritionScore","mealDescription","items"]},"ConfirmNutritionPhotoLogResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ConfirmNutritionPhotoLogData"}},"required":["data"]},"OrganizationLogNutritionBody":{"type":"object","properties":{"date":{"type":"string","description":"Date for the log entry (ISO 8601 or YYYY-MM-DD). Defaults to today.","example":"2026-08-05"},"caloriesKcal":{"type":"number","description":"Calories in kcal","minimum":0,"example":450},"proteinG":{"type":"number","description":"Protein in grams","minimum":0,"example":25},"carbsG":{"type":"number","description":"Carbohydrates in grams","minimum":0,"example":50},"fatG":{"type":"number","description":"Fat in grams","minimum":0,"example":15},"externalId":{"type":"string","description":"Stable partner id for this meal entry. Re-posting the same externalId replaces the previous contribution instead of adding a duplicate (safe to retry), and enables DELETE by externalId.","maxLength":120,"example":"partner-meal-5521"},"source":{"type":"string","description":"Provenance label for the pushed data (e.g. your app name). Surfaces in dataSources.","maxLength":50,"example":"AcmeHealthApp"}}},"OrganizationLogNutritionData":{"type":"object","properties":{"logged":{"description":"Values that were logged by this call","allOf":[{"$ref":"#/components/schemas/NutritionPhotoTotalsDto"}]},"dayTotals":{"type":"object","description":"Day's running totals after this log","properties":{"caloriesConsumedKcal":{"type":"number","example":1290},"proteinG":{"type":"number","example":98},"carbsG":{"type":"number","example":132},"fatG":{"type":"number","example":41}}},"nutritionScore":{"type":"object","description":"Nutrition score for the day (0-100), null when not computable","nullable":true,"example":78},"externalId":{"type":"object","description":"The externalId this entry was stored with, null when none was provided.","nullable":true,"example":"partner-meal-5521"}},"required":["logged","dayTotals","nutritionScore","externalId"]},"OrganizationLogNutritionResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/OrganizationLogNutritionData"}},"required":["data"]},"ActivityHealthDataEntryDto":{"type":"object","properties":{"dataType":{"type":"string","description":"Type of health data carried by this entry.","enum":["activity","sleep","steps","body_metrics","heart_rate","hydration","oxygenation","scores"],"example":"activity"},"externalId":{"type":"string","description":"Stable partner id for the record - idempotency and correction key. Required for activity entries.","maxLength":120,"example":"run-8842"},"recordedAt":{"type":"string","description":"Event time (ISO 8601). Determines the calendar day the data lands on for day-scoped types. Defaults to ingestion time. Must not be in the future and at most 90 days in the past.","example":"2026-08-05T22:45:00.000Z"},"source":{"type":"string","description":"Provenance label for the pushed data (e.g. your app or device name). Surfaces in dataSources.","maxLength":50,"example":"AcmeHealthApp"},"startAt":{"type":"string","description":"Activity start time (ISO 8601). Required.","example":"2026-08-05T07:30:00.000Z"},"endAt":{"type":"string","description":"Activity end time (ISO 8601). Derived from durationSeconds when omitted.","example":"2026-08-05T08:15:00.000Z"},"activityType":{"type":"string","description":"Activity type label (free-form). Common values: Running, Cycling, Walking, Swimming, Hiking, Yoga, Strength Training, HIIT, Rowing. Omit when unclassified. Swim-specific fields apply only to swimming sessions.","example":"Running"},"durationSeconds":{"type":"number","description":"Total duration in seconds","minimum":0,"example":2700},"distanceMeters":{"type":"number","description":"Distance in meters","minimum":0,"example":8200},"steps":{"type":"number","description":"Steps during the activity","minimum":0,"example":7900},"activeCaloriesKcal":{"type":"number","description":"Active calories in kcal","minimum":0,"example":512},"hrAvg":{"type":"number","description":"Average heart rate (bpm)","minimum":0,"example":148},"hrMax":{"type":"number","description":"Max heart rate (bpm)","minimum":0,"example":176},"hrMin":{"type":"number","description":"Min heart rate (bpm)","minimum":0,"example":92},"hrResting":{"type":"number","description":"Resting heart rate (bpm)","minimum":0,"example":58},"paceAvgMinPerKm":{"type":"number","description":"Average pace (min/km). Derived from distance/duration when omitted.","minimum":0,"example":5.5},"paceMaxMinPerKm":{"type":"number","description":"Fastest split pace (min/km)","minimum":0,"example":4.9},"speedAvgMps":{"type":"number","description":"Average speed (m/s)","minimum":0,"example":3.1},"speedMaxMps":{"type":"number","description":"Max speed (m/s)","minimum":0,"example":4.4},"cadenceAvgRpm":{"type":"number","description":"Average cadence (rpm)","minimum":0,"example":86},"cadenceMaxRpm":{"type":"number","description":"Max cadence (rpm)","minimum":0,"example":102},"lowIntensitySeconds":{"type":"number","description":"Seconds at low intensity","minimum":0,"example":300},"moderateIntensitySeconds":{"type":"number","description":"Seconds at moderate intensity","minimum":0,"example":900},"vigorousIntensitySeconds":{"type":"number","description":"Seconds at vigorous intensity","minimum":0,"example":1500},"elevationGainMeters":{"type":"number","description":"Elevation gain in meters","minimum":0,"example":120},"elevationLossMeters":{"type":"number","description":"Elevation loss in meters","minimum":0,"example":95},"floorsClimbed":{"type":"number","description":"Floors climbed","minimum":0,"example":12},"swimDistanceMeters":{"type":"number","description":"Swim distance in meters (pool swims)","minimum":0,"example":1500},"swimLaps":{"type":"number","description":"Number of swim laps","minimum":0,"example":30},"swimStrokes":{"type":"number","description":"Number of swim strokes","minimum":0,"example":620},"poolLengthMeters":{"type":"number","description":"Pool length in meters","minimum":0,"example":25}},"required":["dataType","startAt"]},"SleepHealthDataEntryDto":{"type":"object","properties":{"dataType":{"type":"string","description":"Type of health data carried by this entry.","enum":["activity","sleep","steps","body_metrics","heart_rate","hydration","oxygenation","scores"],"example":"sleep"},"externalId":{"type":"string","description":"Stable partner id for the record - idempotency and correction key. Re-posting the same (dataType, externalId) updates the entry instead of duplicating it. Required for activity entries; day-scoped types default to a per-day key (\"day-YYYY-MM-DD\") when omitted.","maxLength":120,"example":"partner-record-1234"},"recordedAt":{"type":"string","description":"Event time (ISO 8601). Determines the calendar day the data lands on for day-scoped types. Defaults to ingestion time. Must not be in the future and at most 90 days in the past.","example":"2026-08-05T22:45:00.000Z"},"source":{"type":"string","description":"Provenance label for the pushed data (e.g. your app or device name). Surfaces in dataSources.","maxLength":50,"example":"AcmeHealthApp"},"sleepScore":{"type":"number","description":"Sleep score (0-100)","minimum":0,"maximum":100,"example":82},"sleepEfficiency":{"type":"number","description":"Sleep efficiency (1-100). Used as sleep score fallback when sleepScore is omitted.","minimum":0,"maximum":100,"example":91},"hrvRmssd":{"type":"number","description":"HRV RMSSD in milliseconds","minimum":0,"example":46},"hrvSdnn":{"type":"number","description":"HRV SDNN in milliseconds","minimum":0,"example":52},"hrAvg":{"type":"number","description":"Average heart rate during sleep (bpm)","minimum":0,"example":54},"hrResting":{"type":"number","description":"Resting heart rate (bpm)","minimum":0,"example":52},"hrMax":{"type":"number","description":"Max heart rate during sleep (bpm)","minimum":0,"example":74},"hrMin":{"type":"number","description":"Min heart rate during sleep (bpm)","minimum":0,"example":47}},"required":["dataType"]},"StepsHealthDataEntryDto":{"type":"object","properties":{"dataType":{"type":"string","description":"Type of health data carried by this entry.","enum":["activity","sleep","steps","body_metrics","heart_rate","hydration","oxygenation","scores"],"example":"steps"},"externalId":{"type":"string","description":"Stable partner id for the record - idempotency and correction key. Re-posting the same (dataType, externalId) updates the entry instead of duplicating it. Required for activity entries; day-scoped types default to a per-day key (\"day-YYYY-MM-DD\") when omitted.","maxLength":120,"example":"partner-record-1234"},"recordedAt":{"type":"string","description":"Event time (ISO 8601). Determines the calendar day the data lands on for day-scoped types. Defaults to ingestion time. Must not be in the future and at most 90 days in the past.","example":"2026-08-05T22:45:00.000Z"},"source":{"type":"string","description":"Provenance label for the pushed data (e.g. your app or device name). Surfaces in dataSources.","maxLength":50,"example":"AcmeHealthApp"},"steps":{"type":"number","description":"Accumulated steps for the day","minimum":0,"example":10412}},"required":["dataType","steps"]},"BodyMetricsHealthDataEntryDto":{"type":"object","properties":{"dataType":{"type":"string","description":"Type of health data carried by this entry.","enum":["activity","sleep","steps","body_metrics","heart_rate","hydration","oxygenation","scores"],"example":"body_metrics"},"externalId":{"type":"string","description":"Stable partner id for the record - idempotency and correction key. Re-posting the same (dataType, externalId) updates the entry instead of duplicating it. Required for activity entries; day-scoped types default to a per-day key (\"day-YYYY-MM-DD\") when omitted.","maxLength":120,"example":"partner-record-1234"},"recordedAt":{"type":"string","description":"Event time (ISO 8601). Determines the calendar day the data lands on for day-scoped types. Defaults to ingestion time. Must not be in the future and at most 90 days in the past.","example":"2026-08-05T22:45:00.000Z"},"source":{"type":"string","description":"Provenance label for the pushed data (e.g. your app or device name). Surfaces in dataSources.","maxLength":50,"example":"AcmeHealthApp"},"weightKg":{"type":"number","description":"Body weight in kilograms","minimum":0,"example":78.4},"heightCm":{"type":"number","description":"Height in centimeters","minimum":0,"example":181},"bmi":{"type":"number","description":"Body mass index. Derived from weightKg/heightCm when omitted.","minimum":0,"example":23.9}},"required":["dataType"]},"HeartRateHealthDataEntryDto":{"type":"object","properties":{"dataType":{"type":"string","description":"Type of health data carried by this entry.","enum":["activity","sleep","steps","body_metrics","heart_rate","hydration","oxygenation","scores"],"example":"heart_rate"},"externalId":{"type":"string","description":"Stable partner id for the record - idempotency and correction key. Re-posting the same (dataType, externalId) updates the entry instead of duplicating it. Required for activity entries; day-scoped types default to a per-day key (\"day-YYYY-MM-DD\") when omitted.","maxLength":120,"example":"partner-record-1234"},"recordedAt":{"type":"string","description":"Event time (ISO 8601). Determines the calendar day the data lands on for day-scoped types. Defaults to ingestion time. Must not be in the future and at most 90 days in the past.","example":"2026-08-05T22:45:00.000Z"},"source":{"type":"string","description":"Provenance label for the pushed data (e.g. your app or device name). Surfaces in dataSources.","maxLength":50,"example":"AcmeHealthApp"},"hrvRmssd":{"type":"number","description":"HRV RMSSD in milliseconds","minimum":0,"example":44},"hrvSdnn":{"type":"number","description":"HRV SDNN in milliseconds","minimum":0,"example":49},"hrAvg":{"type":"number","description":"Average heart rate (bpm)","minimum":0,"example":64},"hrResting":{"type":"number","description":"Resting heart rate (bpm)","minimum":0,"example":55},"hrMax":{"type":"number","description":"Max heart rate (bpm)","minimum":0,"example":132},"hrMin":{"type":"number","description":"Min heart rate (bpm)","minimum":0,"example":48}},"required":["dataType"]},"HydrationHealthDataEntryDto":{"type":"object","properties":{"dataType":{"type":"string","description":"Type of health data carried by this entry.","enum":["activity","sleep","steps","body_metrics","heart_rate","hydration","oxygenation","scores"],"example":"hydration"},"externalId":{"type":"string","description":"Stable partner id for the record - idempotency and correction key. Re-posting the same (dataType, externalId) updates the entry instead of duplicating it. Required for activity entries; day-scoped types default to a per-day key (\"day-YYYY-MM-DD\") when omitted.","maxLength":120,"example":"partner-record-1234"},"recordedAt":{"type":"string","description":"Event time (ISO 8601). Determines the calendar day the data lands on for day-scoped types. Defaults to ingestion time. Must not be in the future and at most 90 days in the past.","example":"2026-08-05T22:45:00.000Z"},"source":{"type":"string","description":"Provenance label for the pushed data (e.g. your app or device name). Surfaces in dataSources.","maxLength":50,"example":"AcmeHealthApp"},"waterIntakeMl":{"type":"number","description":"Water intake in milliliters","minimum":0,"example":2100}},"required":["dataType","waterIntakeMl"]},"OxygenationHealthDataEntryDto":{"type":"object","properties":{"dataType":{"type":"string","description":"Type of health data carried by this entry.","enum":["activity","sleep","steps","body_metrics","heart_rate","hydration","oxygenation","scores"],"example":"oxygenation"},"externalId":{"type":"string","description":"Stable partner id for the record - idempotency and correction key. Re-posting the same (dataType, externalId) updates the entry instead of duplicating it. Required for activity entries; day-scoped types default to a per-day key (\"day-YYYY-MM-DD\") when omitted.","maxLength":120,"example":"partner-record-1234"},"recordedAt":{"type":"string","description":"Event time (ISO 8601). Determines the calendar day the data lands on for day-scoped types. Defaults to ingestion time. Must not be in the future and at most 90 days in the past.","example":"2026-08-05T22:45:00.000Z"},"source":{"type":"string","description":"Provenance label for the pushed data (e.g. your app or device name). Surfaces in dataSources.","maxLength":50,"example":"AcmeHealthApp"},"spo2AvgPct":{"type":"number","description":"Average blood oxygen saturation (percent)","minimum":0,"maximum":100,"example":97}},"required":["dataType","spo2AvgPct"]},"ScoresHealthDataEntryDto":{"type":"object","properties":{"dataType":{"type":"string","description":"Type of health data carried by this entry.","enum":["activity","sleep","steps","body_metrics","heart_rate","hydration","oxygenation","scores"],"example":"scores"},"externalId":{"type":"string","description":"Stable partner id for the record - idempotency and correction key. Re-posting the same (dataType, externalId) updates the entry instead of duplicating it. Required for activity entries; day-scoped types default to a per-day key (\"day-YYYY-MM-DD\") when omitted.","maxLength":120,"example":"partner-record-1234"},"recordedAt":{"type":"string","description":"Event time (ISO 8601). Determines the calendar day the data lands on for day-scoped types. Defaults to ingestion time. Must not be in the future and at most 90 days in the past.","example":"2026-08-05T22:45:00.000Z"},"source":{"type":"string","description":"Provenance label for the pushed data (e.g. your app or device name). Surfaces in dataSources.","maxLength":50,"example":"AcmeHealthApp"},"overallHealthScore":{"type":"number","description":"Partner-computed overall health score (0-100)","minimum":0,"maximum":100,"example":79},"physicalScore":{"type":"number","description":"Partner-computed physical/activity score (0-100)","minimum":0,"maximum":100,"example":74},"sleepScore":{"type":"number","description":"Partner-computed sleep score (0-100)","minimum":0,"maximum":100,"example":85},"bodyScore":{"type":"number","description":"Partner-computed body score (0-100)","minimum":0,"maximum":100,"example":81},"nutritionScore":{"type":"number","description":"Partner-computed nutrition score (0-100)","minimum":0,"maximum":100,"example":68}},"required":["dataType"]},"LogHealthDataBody":{"type":"object","properties":{"entries":{"type":"array","description":"Health data entries to ingest (max 50 per request). Each entry is processed independently (best-effort batch): failures are reported per entry in the response, valid entries are still applied.","minItems":1,"maxItems":50,"items":{"oneOf":[{"$ref":"#/components/schemas/ActivityHealthDataEntryDto"},{"$ref":"#/components/schemas/SleepHealthDataEntryDto"},{"$ref":"#/components/schemas/StepsHealthDataEntryDto"},{"$ref":"#/components/schemas/BodyMetricsHealthDataEntryDto"},{"$ref":"#/components/schemas/HeartRateHealthDataEntryDto"},{"$ref":"#/components/schemas/HydrationHealthDataEntryDto"},{"$ref":"#/components/schemas/OxygenationHealthDataEntryDto"},{"$ref":"#/components/schemas/ScoresHealthDataEntryDto"}],"discriminator":{"propertyName":"dataType","mapping":{"activity":"#/components/schemas/ActivityHealthDataEntryDto","sleep":"#/components/schemas/SleepHealthDataEntryDto","steps":"#/components/schemas/StepsHealthDataEntryDto","body_metrics":"#/components/schemas/BodyMetricsHealthDataEntryDto","heart_rate":"#/components/schemas/HeartRateHealthDataEntryDto","hydration":"#/components/schemas/HydrationHealthDataEntryDto","oxygenation":"#/components/schemas/OxygenationHealthDataEntryDto","scores":"#/components/schemas/ScoresHealthDataEntryDto"}}},"example":[{"dataType":"activity","externalId":"run-8842","source":"AcmeHealthApp","activityType":"Running","startAt":"2026-08-05T07:30:00.000Z","endAt":"2026-08-05T08:15:00.000Z","durationSeconds":2700,"distanceMeters":8200,"steps":7900,"activeCaloriesKcal":512,"hrAvg":148,"hrMax":176,"paceAvgMinPerKm":5.5},{"dataType":"sleep","recordedAt":"2026-08-05T08:00:00.000Z","source":"AcmeHealthApp","sleepScore":82,"sleepEfficiency":91,"hrvRmssd":46,"hrResting":52},{"dataType":"steps","recordedAt":"2026-08-05T21:00:00.000Z","source":"AcmeHealthApp","steps":10412},{"dataType":"body_metrics","recordedAt":"2026-08-05T07:00:00.000Z","source":"AcmeHealthApp","weightKg":78.4,"heightCm":181},{"dataType":"heart_rate","recordedAt":"2026-08-05T21:00:00.000Z","source":"AcmeHealthApp","hrvRmssd":44,"hrAvg":64,"hrResting":55},{"dataType":"hydration","recordedAt":"2026-08-05T21:00:00.000Z","source":"AcmeHealthApp","waterIntakeMl":2100},{"dataType":"oxygenation","recordedAt":"2026-08-05T21:00:00.000Z","source":"AcmeHealthApp","spo2AvgPct":97},{"dataType":"scores","recordedAt":"2026-08-05T22:00:00.000Z","source":"AcmeHealthApp","overallHealthScore":79,"physicalScore":74,"sleepScore":85,"bodyScore":81,"nutritionScore":68}]}},"required":["entries"]},"HealthDataEntryResultDto":{"type":"object","properties":{"index":{"type":"number","description":"Position of the entry in the request entries array","example":0},"dataType":{"type":"string","description":"Data type of the entry","example":"sleep"},"externalId":{"type":"object","description":"Resolved idempotency key: the provided externalId, or the day-derived default for day-scoped types. Null when the entry was rejected before a key could be resolved.","nullable":true,"example":"day-2026-08-05"},"status":{"type":"string","description":"Outcome for this entry: created (new record), updated (idempotent upsert of an existing key), or rejected.","enum":["created","updated","rejected"],"example":"created"},"reason":{"type":"string","description":"Machine-readable failure reason. Only present when status is rejected.","example":"Entry timestamp cannot be in the future"}},"required":["index","dataType","externalId","status"]},"LogHealthDataSummaryDto":{"type":"object","properties":{"total":{"type":"number","description":"Total entries in the request","example":3},"succeeded":{"type":"number","description":"Entries applied (created or updated)","example":2},"failed":{"type":"number","description":"Entries rejected","example":1}},"required":["total","succeeded","failed"]},"LogHealthDataData":{"type":"object","properties":{"results":{"description":"Per-entry outcome, in request order","type":"array","items":{"$ref":"#/components/schemas/HealthDataEntryResultDto"}},"summary":{"$ref":"#/components/schemas/LogHealthDataSummaryDto"}},"required":["results","summary"]},"LogHealthDataResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/LogHealthDataData"}},"required":["data"]},"CurrentApiStatsDto":{"type":"object","properties":{"currentHour":{"type":"string","description":"Current hour timestamp (ISO 8601 format)","example":"2023-11-06T14:00:00Z"},"currentHourRequests":{"type":"number","description":"Number of requests made in the current hour","example":45},"totalDayRequests":{"type":"number","description":"Total number of requests made today","example":234},"currentDate":{"type":"string","description":"Current date (YYYY-MM-DD format)","example":"2023-11-06"}},"required":["currentHour","currentHourRequests","totalDayRequests","currentDate"]},"RateLimitsDto":{"type":"object","properties":{"hourly":{"type":"object","description":"Hourly rate limit from subscription entitlement","example":1000,"nullable":true},"daily":{"type":"object","description":"Daily rate limit from subscription entitlement","example":15000,"nullable":true}}},"OrganizationStatsResponse":{"type":"object","properties":{"organizationId":{"type":"string","description":"The unique identifier of the organization","example":"63415bf67a9c7000126616c1"},"organizationName":{"type":"string","description":"The name of the organization","example":"My Fitness Company"},"currentStats":{"description":"Current API usage statistics","allOf":[{"$ref":"#/components/schemas/CurrentApiStatsDto"}]},"rateLimits":{"description":"Rate limits from subscription entitlement","allOf":[{"$ref":"#/components/schemas/RateLimitsDto"}]},"timestamp":{"type":"string","description":"Response timestamp (ISO 8601 format)","example":"2023-11-06T14:30:00Z"}},"required":["organizationId","organizationName","currentStats","rateLimits","timestamp"]},"StartConversationBody":{"type":"object","properties":{"organizationId":{"type":"string","description":"Organization ID - use \"default\" to use the user's default organization","example":"default"},"initialMessage":{"type":"string","description":"Initial message to start the conversation","example":"What exercises should I do for chest?","minLength":1,"maxLength":2000},"userEmail":{"type":"string","description":"User email address to identify the end user","example":"user@example.com"},"userExternalUUID":{"type":"string","description":"External unique identifier for the end user","example":"user-12345"}},"required":["organizationId","initialMessage"]},"ChatConversationDto":{"type":"object","properties":{"id":{"type":"string","description":"Conversation ID"},"title":{"type":"string","description":"Conversation title"},"messageCount":{"type":"number","description":"Number of messages in conversation"},"lastMessageAt":{"format":"date-time","type":"string","description":"Last message timestamp"},"createdAt":{"format":"date-time","type":"string","description":"Conversation creation timestamp"}},"required":["id","messageCount","createdAt"]},"ChatMessageDto":{"type":"object","properties":{"id":{"type":"string","description":"Message ID"},"role":{"type":"string","description":"Message role","enum":["user","assistant"]},"content":{"type":"string","description":"Message content"},"createdAt":{"format":"date-time","type":"string","description":"Message creation timestamp"},"metadata":{"type":"object","description":"Message metadata (reasoning, topics, nutritionLogged, contentPreview, pendingAction, confirmedResult)"},"status":{"type":"string","description":"Message delivery status","enum":["pending","delivered","failed"]}},"required":["id","role","content","createdAt","status"]},"ChatConversationResponse":{"type":"object","properties":{"conversation":{"$ref":"#/components/schemas/ChatConversationDto"},"response":{"$ref":"#/components/schemas/ChatMessageDto"}},"required":["conversation","response"]},"PaginationDto":{"type":"object","properties":{"page":{"type":"number","description":"Current page number"},"limit":{"type":"number","description":"Items per page"},"total":{"type":"number","description":"Total number of items"},"totalPages":{"type":"number","description":"Total number of pages"}},"required":["page","limit","total","totalPages"]},"ChatConversationsResponse":{"type":"object","properties":{"conversations":{"type":"array","items":{"$ref":"#/components/schemas/ChatConversationDto"}},"pagination":{"$ref":"#/components/schemas/PaginationDto"}},"required":["conversations","pagination"]},"ChatMessagesResponse":{"type":"object","properties":{"messages":{"type":"array","items":{"$ref":"#/components/schemas/ChatMessageDto"}},"pagination":{"$ref":"#/components/schemas/PaginationDto"}},"required":["messages","pagination"]},"SendMessageBody":{"type":"object","properties":{"organizationId":{"type":"string","description":"Organization ID - use \"default\" to use the user's default organization","example":"default"},"content":{"type":"string","description":"Message content","example":"What exercises should I do for chest?","minLength":1,"maxLength":2000},"userEmail":{"type":"string","description":"User email address to identify the end user","example":"user@example.com"},"userExternalUUID":{"type":"string","description":"External unique identifier for the end user","example":"user-12345"}},"required":["organizationId","content"]},"SendMessageResponse":{"type":"object","properties":{"userMessage":{"description":"The user message that was sent","allOf":[{"$ref":"#/components/schemas/ChatMessageDto"}]},"assistantMessage":{"description":"The AI assistant response","allOf":[{"$ref":"#/components/schemas/ChatMessageDto"}]},"conversation":{"description":"Updated conversation information","allOf":[{"$ref":"#/components/schemas/ChatConversationDto"}]}},"required":["userMessage","assistantMessage","conversation"]},"ConfirmActionBody":{"type":"object","properties":{"pendingActionId":{"type":"string","description":"Pending action ID from assistantMessage.metadata.pendingAction.id","example":"507f1f77bcf86cd799439011"},"organizationId":{"type":"string","description":"Organization ID - use \"default\" to use the user's default organization","example":"default"},"userEmail":{"type":"string","description":"User email address to identify the end user","example":"user@example.com"},"userExternalUUID":{"type":"string","description":"External unique identifier for the end user","example":"user-12345"}},"required":["pendingActionId","organizationId"]},"NutritionOverviewLoggedDto":{"type":"object","properties":{"caloriesKcal":{"type":"number"},"proteinG":{"type":"number"},"carbsG":{"type":"number"},"fatG":{"type":"number"}},"required":["caloriesKcal","proteinG","carbsG","fatG"]},"NutritionOverviewDayTotalsDto":{"type":"object","properties":{"caloriesConsumedKcal":{"type":"number"},"proteinG":{"type":"number"},"carbsG":{"type":"number"},"fatG":{"type":"number"}},"required":["caloriesConsumedKcal","proteinG","carbsG","fatG"]},"NutritionOverviewDto":{"type":"object","properties":{"logged":{"$ref":"#/components/schemas/NutritionOverviewLoggedDto"},"dayTotals":{"$ref":"#/components/schemas/NutritionOverviewDayTotalsDto"},"nutritionScore":{"type":"object","nullable":true}},"required":["logged","dayTotals","nutritionScore"]},"ConfirmActionResponseDto":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"},"error":{"type":"string"},"nutritionOverview":{"description":"Present when action was log_nutrition and success is true","allOf":[{"$ref":"#/components/schemas/NutritionOverviewDto"}]},"instructionForReply":{"type":"string","description":"Instruction for displaying the nutrition reply (log_nutrition only)"},"adaptedWorkout":{"description":"On-the-fly adapted workout (adapt_workout). Render and store locally.","allOf":[{"$ref":"#/components/schemas/WorkoutAdaptationResponseDto"}]},"generatedWorkout":{"description":"On-the-fly generated workout (generate_workout). Render and store locally.","allOf":[{"$ref":"#/components/schemas/WorkoutGenerationResponseDto"}]},"adaptedProgram":{"description":"On-the-fly adapted program (adapt_program). Render and store locally.","allOf":[{"$ref":"#/components/schemas/PlanAdaptationResponseDto"}]},"generatedProgram":{"description":"On-the-fly generated program (generate_program). Same shape as POST /v1/orgs/{orgId}/plans/generate. Render and store locally.","allOf":[{"$ref":"#/components/schemas/PlanGenerationResponseDto"}]}},"required":["success"]}}}}