Exercise API docs

Everything you need to show HEPonDemand exercises in your product. No key yet? Get a free sandbox key.

Downloads: OpenAPI 3.1 file · Postman collection · License

Quickstart

  1. Get a key. Test keys start with hod_test_ and see 20 sample exercises with watermarked pictures. Live keys start with hod_live_ and see the whole library. Keep keys on your server, never in an app or web page. If your servers have fixed IP addresses, ask us to limit your live keys to them, so a leaked key doesn't work anywhere else.
  2. Make a call.
    curl https://hepondemand.com/api/v1/exercises?body_region=knee&per_page=5 \
      -H "Authorization: Bearer $HOD_API_KEY"
  3. Show an exercise. Use name, steps, cautions and default_dosage. Show images[].thumbnail_url in lists and full_url on detail screens, with alt_text, and show disclosure with every AI-generated picture and disclaimer with every exercise.
  4. Stay in sync. Store what you need for up to 30 days. Refresh with updated_since, or on Growth with /changes, which also tells you what was removed.
const res = await fetch("https://hepondemand.com/api/v1/exercises/clamshell", {
  headers: { Authorization: `Bearer ${process.env.HOD_API_KEY}` },
});
const { data } = await res.json();
console.log(data.name, data.steps, data.default_dosage);

Endpoints

Base URL: https://hepondemand.com/api/v1. Every response is JSON except the PDF. Lists return { data, page, per_page, total, has_more }; single items return { data }.

EndpointWhat it returnsPlans
GET /exercisesList and search. Filters: body_region, condition, equipment, position, movement, specialty, difficulty, q, updated_since. Paged with page and per_page (max 100).All
GET /exercises/{id}One exercise, by id or slug.All
GET /programsReady-made programs by condition (filter: condition).All
GET /programs/{id}One program with its exercises, in order, with dosage.All
GET /taxonomyEvery filter value, with slugs and names.All
GET /changes?since=Exercises updated or removed since a time, oldest first. Page with next_cursor.Growth, Platform
…?include=videosOn /exercises and /exercises/{id}: adds each exercise's videos (signed links that play in a video tag). Without it, nothing changes.Growth, Platform
GET /exercises/{id}/handout.pdfA print-ready patient handout for one exercise.Growth, Platform

Filters take comma-separated slugs from /taxonomy and match any of them, e.g. ?body_region=knee,hip&equipment=none. difficulty is easy, moderate or hard. updated_since takes an ISO 8601 date or date-time.

Pictures

Picture links are signed and expire after about a day (expires_at), and stay the same for an hour so they cache well. Don't store the links: fetch the exercise again for fresh ones. Each picture has ai_generated and, when true, a disclosure you must show with it: “Illustration generated with AI and reviewed by a licensed clinician.”

Limits and headers

  • About 10 requests a second per key. Over that you get 429 rate_limited with Retry-After: 1.
  • A monthly quota by plan (calendar month, UTC). Only successful calls count. Over it you get 429 quota_exceeded with Retry-After set to when it resets.
  • Every response has X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (Unix seconds), plus X-Api-Mode (test or live).
  • Picture links don't count toward the quota.

Errors

Errors look like { "error": { "code": "not_found", "message": "Exercise not found" } }.

StatusCodeMeaning
400invalid_requestA query parameter is missing or not valid. The message names it.
401unauthorizedNo key, or the key is wrong, revoked or expired.
403account_suspendedThe account is suspended (usually a failed payment), cancelled, or not paid yet.
403ip_not_allowedYour account limits live keys to approved server addresses, and this request came from another one.
403plan_requiredYour plan doesn't include this endpoint (change feed, handout PDFs and videos need Growth).
404not_foundNo such exercise or program, or not one your key can see.
429rate_limitedMore than 10 requests a second on one key. Wait for Retry-After (1 second).
429quota_exceededThis month's calls are used up. Retry-After says when the quota resets.
500server_errorSomething went wrong on our side. Try again shortly.
503api_disabledThe API is temporarily closed.

Display rules

  • Show the content only inside the product named on your account.
  • Keep the AI picture disclosure and the clinical disclaimer: “For use under the direction of a licensed clinician. Not medical advice.”
  • Starter: show the credit in each exercise's attribution field.
  • No bulk export, resale or AI training. See the license.

Changelog

2026-11-06

  • Optional server address allow-list: live keys can be limited to your servers' IP addresses (new 403 ip_not_allowed).

2026-11-05

  • Exercise videos (Growth and up): add include=videos to /exercises or /exercises/{id}. Without it, responses are unchanged.

2026-11-04

  • First version (v1): exercises, programs, taxonomy, change feed, handout PDFs.
  • Signed picture links in thumbnail and full sizes, each labelled AI-generated.
  • Test keys (Sandbox) and live keys, monthly quotas and a per-key burst limit.

v1 only ever gains fields and endpoints; nothing is renamed or removed. Questions? Contact us.