CheckMotion API v2

Build with motion intelligence.

Production API documentation for pose extraction, sport detection, movement metrics, performance ratings, coaching reports, and grounded follow-up chat.

Production base URL

https://api-v2.checkmotion.app

HTTPS only · JSON responses · Bearer authentication

On this page

Overview

CheckMotion runs compute-heavy video analysis as a sequence of durable jobs. Start with sport detection or pose extraction, poll the returned job, then pass completed job IDs into downstream analysis endpoints.

1. Submit

Upload a video or provide an HTTPS video URL. The API immediately returns a job ID.

2. Poll

Read the corresponding job endpoint until its status becomes COMPLETED or FAILED.

3. Compose

Use completed job IDs as prerequisites for metrics, ratings, reports, or the full pipeline.

Stable machine-readable output

The language field localizes human-facing labels and narrative text. Property names, IDs, status values, and taxonomy identifiers remain stable.

Authentication

Every endpoint except the health check requires an API key. Create or rotate your key in your CheckMotion account, then send it as a Bearer token.

Shell
curl 'https://api-v2.checkmotion.app/health'

curl 'https://api-v2.checkmotion.app/analysis/jobs/JOB_ID' \
  --header 'Authorization: Bearer cm_live_YOUR_API_KEY'

Keep keys server-side

Never expose an API key in browser JavaScript, mobile bundles, logs, or source control. Route calls through your backend.

Use HTTPS

API requests and remote video URLs must use HTTPS. Treat a leaked key as compromised and rotate it immediately.

Quickstart

This example uploads a tennis clip, receives an asynchronous job, and fetches its localized result.

1. Start sport detection

cURL
curl --request POST 'https://api-v2.checkmotion.app/analysis/detect-sport' \
  --header 'Authorization: Bearer cm_live_YOUR_API_KEY' \
  --header 'Accept: application/json' \
  --form 'video=@"./serve.mp4"' \
  --form 'language=en'

2. Save the accepted job

202 response
{
  "jobId": "124f09f3-b66d-4d3e-96f4-cd9ae84415dc",
  "status": "PENDING"
}

3. Poll until complete

cURL
curl 'https://api-v2.checkmotion.app/analysis/jobs/124f09f3-b66d-4d3e-96f4-cd9ae84415dc' \
  --header 'Authorization: Bearer cm_live_YOUR_API_KEY'
Completed response
{
  "jobId": "124f09f3-b66d-4d3e-96f4-cd9ae84415dc",
  "status": "COMPLETED",
  "result": {
    "sport": "tennis",
    "sportLabel": "Tennis",
    "confidence": 0.94,
    "activityStatus": "resolved",
    "movement": {
      "id": "tennis:serve",
      "type": "serve",
      "label": "Serve",
      "confidence": 0.88
    },
    "taxonomyVersion": "checkmotion-activity-taxonomy/1.0"
  }
}

Async jobs

Long-running work uses a consistent lifecycle. Your integration should persist job IDs and tolerate repeat polling.

PENDING

Accepted and waiting for capacity.

PROCESSING

The analysis is currently running.

COMPLETED

The result is ready to consume.

FAILED

The job ended with an error.

Idempotent submission

Supply your own UUID in X-CheckMotion-Job-ID. Reusing that ID returns the existing job instead of creating duplicate work—useful when safely retrying a timed-out request.
Client-assigned job ID
curl --request POST 'https://api-v2.checkmotion.app/videos/keypoints' \
  --header 'Authorization: Bearer cm_live_YOUR_API_KEY' \
  --header 'X-CheckMotion-Job-ID: 124f09f3-b66d-4d3e-96f4-cd9ae84415dc' \
  --form 'video=@"./movement.mp4"'

Endpoint reference

All routes are relative to the production base URL. Analysis routes use the analysis job endpoints; pose routes use the general job endpoints.

  • POST/videos/keypointsStart pose extraction
  • GET/jobs/{job_id}Get a pose job
  • GET/jobs/{job_id}/videoStream the job video
  • DELETE/jobs/{job_id}Delete a pose job
  • POST/analysis/detect-sportDetect sport and movement
  • POST/analysis/generate-detailed-metricsGenerate detailed metrics
  • POST/analysis/rate-performanceRate the performance
  • POST/analysis/generate-reportGenerate a coaching report
  • GET/analysis/jobs/{job_id}Get an analysis job
  • DELETE/analysis/jobs/{job_id}Delete an analysis job
  • POST/analysis/fullStart the complete pipeline
  • GET/analysis/full/{job_id}Get a full-analysis job
  • POST/analysis/chatAsk a report-grounded question

Pose extraction

Extract time-aligned pose keypoints from an uploaded recording or a remotely hosted video.

POST/videos/keypoints

Start pose extraction

Send either a multipart video file or a videoUrl, but not both. Remote URLs are validated and must resolve to an allowed HTTPS location.

Remote video
curl --request POST 'https://api-v2.checkmotion.app/videos/keypoints' \
  --header 'Authorization: Bearer cm_live_YOUR_API_KEY' \
  --form 'videoUrl=https://example.com/private-upload/movement.mp4'
GET/jobs/{job_id}

Read pose status and output

Poll this route for pose jobs. Completed responses include the extracted keypoint data. The authorized video-stream route is intended for controlled server-side playback; delete removes the stored job and its associated assets.

Sport detection & localization

Identify the sport and, when evidence is sufficient, resolve the movement against CheckMotion’s versioned activity taxonomy.

POST/analysis/detect-sport

Detect sport and movement

Input

Multipart video upload or videoUrl, plus an optional BCP 47-style language such as en or de-AT.

Output

Canonical sport and movement identifiers, localized labels, confidence values, resolution status, and taxonomy version.

Do not branch on labels

Build application logic with canonical values such as sport and movement.id. Localized labels are presentation strings and may vary by language.

Movement analysis

Combine completed pose and sport jobs to calculate movement-specific metrics, then create a performance rating from those metrics.

POST/analysis/generate-detailed-metrics

Generate detailed metrics

cURL
curl --request POST 'https://api-v2.checkmotion.app/analysis/generate-detailed-metrics' \
  --header 'Authorization: Bearer cm_live_YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "keypointJobId": "POSE_JOB_ID",
    "sportDetectionJobId": "SPORT_JOB_ID",
    "language": "en"
  }'
POST/analysis/rate-performance

Rate performance

cURL
curl --request POST 'https://api-v2.checkmotion.app/analysis/rate-performance' \
  --header 'Authorization: Bearer cm_live_YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "detailedMetricsJobId": "METRICS_JOB_ID",
    "language": "en"
  }'

Prerequisites must be complete

Submit downstream work only after every referenced job reports COMPLETED. A pending, failed, missing, or incompatible prerequisite returns a structured error.

For server-owned orchestration, POST /analysis/full accepts a video together with explicit keypoint and sport-detection job IDs, while GET /analysis/full/{job_id} returns the pipeline state.

Reports & coaching chat

Turn structured analysis into coach-friendly feedback, then let users ask bounded follow-up questions grounded in the completed report.

POST/analysis/generate-report

Generate a coaching report

cURL
curl --request POST 'https://api-v2.checkmotion.app/analysis/generate-report' \
  --header 'Authorization: Bearer cm_live_YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "sportDetectionJobId": "SPORT_JOB_ID",
    "detailedMetricsJobId": "METRICS_JOB_ID",
    "performanceRatingJobId": "RATING_JOB_ID",
    "language": "en"
  }'
POST/analysis/chat

Ask a grounded question

Chat is synchronous and intentionally bounded. Provide the completed report context and conversation state required by the schema; responses stay focused on the analyzed movement rather than acting as a general-purpose assistant.

Errors & recovery

HTTP status codes communicate the broad outcome. Error bodies add a stable category and context your integration can use for recovery or support.

400 Bad Request

Malformed input, invalid combination, or failed validation.

401 Unauthorized

Missing, invalid, or revoked API key.

404 Not Found

The requested job does not exist or is unavailable to the key.

409 Conflict

The current job or prerequisite state cannot satisfy the request.

422 Unprocessable Entity

A typed request field does not match the endpoint schema.

429 Too Many Requests

The key has exceeded its current request allowance.

500 Server Error

An unexpected processing failure occurred.

503 Unavailable

A required analysis dependency is temporarily unavailable.
Prerequisite error
{
  "detail": {
    "error": "A prerequisite job has not completed",
    "error_type": "prerequisite_not_ready",
    "error_details": {
      "job_id": "POSE_JOB_ID",
      "status": "PROCESSING"
    }
  }
}

Retry transient 429, 500, and 503 responses with exponential backoff and jitter. Do not automatically retry validation or authentication failures without changing the request.

Ready to integrate?

Create your key and run the quickstart.

Need architecture or volume guidance? The CheckMotion team can help.