TechnologyBlogscareerleadershipcontact us
HEMSCap logo

Exercise Engine Docs

IntroductionAuthenticationExercise ObjectsPortal RedirectsAPI EndpointsZero-Angle OverviewZero-Angle Table (Front)Zero-Angle Table (Right)Zero-Angle Table (Left)

3.3. Exercise API Endpoints

Base URL: https://api.platform.hemscap.com

A. Exercise Lifecycle Management

POST

A.1. Create Exercise

/api/platform/portal/info-swagger/exercise/create

Summary: Initializes a new, empty exercise document. It generates a unique exerciseKey, sets the version to 1, assigns the standing posture, and binds ownership to the authenticated user.

interface CreateExerciseDtoIn {
  title: string;
  description: string;
}

interface CreateExerciseDtoOut {
  exerciseKey: string;
}

async function createExercise(payload: CreateExerciseDtoIn): Promise<CreateExerciseDtoOut> {
  const response = await fetch(`https://api.platform.hemscap.com/api/platform/portal/info-swagger/exercise/create`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', /* Authorization: Bearer <TOKEN> */ },
    body: JSON.stringify(payload)
  });
  return await response.json();
}
GET

A.2. Get My Exercises

/api/platform/portal/info-swagger/exercise/me

Summary: Returns a paginated and filtered list of exercises exclusively owned by the authenticated user.

type CameraType = 'left' | 'front' | 'right';
type PostureType = 'standing' | 'sitting' | 'sleeping1' | 'sleeping2';
type ExerciseTypeFilter = 'face' | 'distance' | 'range_of_motion';
type PushTimelineMode = 'pose-changed' | 'fps';

interface ExerciseFilterDtoIn {
  label?: string;
  offset?: number;
  limit?: number;
  camera?: CameraType;
  posture?: PostureType;
  exerciseType?: ExerciseTypeFilter;
  targetJoint?: Array<string> | string;
  pushTimelineMode?: PushTimelineMode;
}

async function getMyExercises(filters: ExerciseFilterDtoIn): Promise<[any[], number]> {
  const query = new URLSearchParams(filters as any).toString();
  const response = await fetch(`https://api.platform.hemscap.com/api/platform/portal/info-swagger/exercise/me?${query}`);
  return await response.json();
}
GET

A.3. Get Exercise

/api/platform/portal/info-swagger/exercise/{exerciseKey}

Summary: Fetches the full exercise document.

Logic & Rules:
  • Ownership: Validates ownership. Returns 404 Not Found if the user does not own the exercise.
  • AppToken Behavior: If requested via an AppToken, the label and description fields are stripped from the response.
interface ExerciseDocument {
  exerciseKey: string;
  label?: string;         // Omitted if requested via AppToken
  description?: string;   // Omitted if requested via AppToken
  cameras: Record<string, any>;
  version: number;
  posture: string;
  authUserId: number;
  options?: any;
}

async function getExercise(exerciseKey: string): Promise<Partial<ExerciseDocument>> {
  const response = await fetch(`https://api.platform.hemscap.com/api/platform/portal/info-swagger/exercise/${exerciseKey}`);
  return await response.json();
}
POST

A.4. Append (Clone) Exercise

/api/platform/portal/info-swagger/exercise/append-exercise/{exerciseKey}

Summary: Clones an existing exercise and assigns ownership of the new clone to the authenticated user.

async function appendExercise(exerciseKey: string): Promise<string> {
  const response = await fetch(`https://api.platform.hemscap.com/api/platform/portal/info-swagger/exercise/append-exercise/${exerciseKey}`, {
    method: 'POST'
  });
  return await response.text();
}
DELETE

A.5. Delete My Exercise

/api/platform/portal/info-swagger/exercise/{exerciseKey}

Summary: Permanently deletes the specified exercise. Only the owner can perform this action.

async function deleteExercise(exerciseKey: string): Promise<void> {
  const response = await fetch(`https://api.platform.hemscap.com/api/platform/portal/info-swagger/exercise/${exerciseKey}`, {
    method: 'DELETE',
    headers: { /* Authorization: Bearer <TOKEN> */ }
  });
  if (!response.ok) {
    throw new Error('Failed to delete exercise');
  }
}

B. Search & Metadata

GET

B.1. Search Exercises

/api/platform/portal/info-swagger/exercise/search

Summary: Searches globally across the exercise engine using filters like posture, camera, or target joints.

async function searchExercises(filters: ExerciseFilterDtoIn): Promise<[any[], number]> {
  const query = new URLSearchParams(filters as any).toString();
  const response = await fetch(`https://api.platform.hemscap.com/api/platform/portal/info-swagger/exercise/search?${query}`);
  return await response.json();
}
GET

B.2. Get Exercise Info

/api/platform/portal/info-swagger/exercise/{exerciseKey}/info

Summary: Returns lightweight metadata (primary camera, pose count, and model type) without loading the full exercise document.

interface GetInfoDtoOut {
  camera?: 'left' | 'front' | 'right';
  posesCount: number;
  model?: string;
}

async function getExerciseInfo(exerciseKey: string): Promise<GetInfoDtoOut> {
  const response = await fetch(`https://api.platform.hemscap.com/api/platform/portal/info-swagger/exercise/${exerciseKey}/info`);
  return await response.json();
}

C. Media Management (Images)

GET

C.1. Get Image by Pose

/api/platform/portal/info-swagger/exercise/get-image-by-pose/{exerciseKey}/{poseId}

Summary: Retrieves the contour image buffer for a specific pose index on the exercise's primary camera.

async function getImageByPose(exerciseKey: string, poseId: number): Promise<Blob> {
  const response = await fetch(`https://api.platform.hemscap.com/api/platform/portal/info-swagger/exercise/get-image-by-pose/${exerciseKey}/${poseId}`);
  if (!response.ok) throw new Error('Failed to fetch image');
  return await response.blob();
}
GET

C.2. Get Pose Image (Specific Camera Angle)

/api/platform/portal/info-swagger/exercise/get-pose-image/{exerciseKey}/{cameraMode}/{poseId}

Summary: Fetches the contour image for a specific camera angle and pose ID. Returns an exercise-version header.

type CameraMode = 'front' | 'left' | 'right';

async function getPoseImage(exerciseKey: string, cameraMode: CameraMode, poseId: number): Promise<Blob> {
  const response = await fetch(`https://api.platform.hemscap.com/api/platform/portal/info-swagger/exercise/get-pose-image/${exerciseKey}/${cameraMode}/${poseId}`);
  if (!response.ok) throw new Error('Image not found');
  return await response.blob();
}
POST

C.3. Publish Custom Animation/Video

/api/platform/portal/info-swagger/exercise/{exerciseKey}/publish-movie

Summary: Uploads a custom video or animation (typically .webm format) to serve as the instructional media for the specified exercise. Max file size is 10MB.

async function publishMovie(exerciseKey: string, videoFile: File): Promise<{ url: string, key: string }> {
  const formData = new FormData();
  formData.append('file', videoFile);

  const response = await fetch(`https://api.platform.hemscap.com/api/platform/portal/info-swagger/exercise/${exerciseKey}/publish-movie`, {
    method: 'POST',
    // Authorization headers omitted for brevity
    body: formData
  });
  
  if (!response.ok) throw new Error('Upload failed');
  return await response.json();
}
GET

C.4. Stream/Retrieve Exercise Video

/api/platform/portal/info-swagger/exercise/{exerciseKey}/get-movie

Summary: Retrieves the published video for an exercise. The endpoint supports HTTP range requests (byte-serving) enabling seeking, scrubbing, and smooth playback directly in html video players.

Playback Implementation Note: Because this endpoint returns a direct media stream, you can use the URL directly in the src attribute of an HTML <video> element. It handles long-term caching and proper MIME types (video/webm) automatically. If no video exists, it returns a 404 Not Found.
<!-- Usage in HTML/React -->
<video controls>
  <source 
    src="https://api.platform.hemscap.com/api/platform/portal/info-swagger/exercise/{exerciseKey}/get-movie" 
    type="video/webm" 
  />
</video>
HEMSCap logo representing SOAP Note generation service

HEMSCap

contact@hemscap.net

about us

  • our team
  • contact us

legal

  • privacy policy
  • terms & conditions
  • cookie setting

platforms

  • pivotalPT
  • HildaCoach
  • geniusPT

who we serve

  • individuals
  • healthcare systems
  • clinics
  • physical therapists
HIPAA Compliance certification badge indicating HEMSCap's commitment to healthcare data security© 2026 HEMSCap All rights reserved