Skip to main content

workoutx-sdk — WorkoutX Fitness & Exercise API SDK for Python

PyPI version Python versions license

The official Python SDK for the WorkoutX API — 1,300+ exercises with form GIFs, a workout generator, supplement intelligence, and AI body-scan analysis, all behind one simple key. A modern Python ExerciseDB alternative for fitness apps.

🔑 Get a free API key · 🌐 workoutxapp.com · 📚 API docs

Covers exercises, GIFs, workout generator, supplements, Body Scan, account, and billing in one client. Python 3.8+. Only depends on certifi (for reliable TLS across platforms).

Install

pip install workoutx-sdk

Quick start

from workoutx import WorkoutX

wx = WorkoutX(
    api_key="wx_your_key_here",   # exercises / gifs / workout / supplements
    scan_token="eyJ...",           # body scan (optional)
)

# Exercises
page    = wx.exercises.list(limit=20)
by_id   = wx.exercises.get("0001")
lunges  = wx.exercises.by_name("lunges")
similar = wx.exercises.similar("0001")
alts    = wx.exercises.alternatives("0001", equipment="dumbbell")

# GIFs
data = wx.gifs.get("0001")          # bytes
src  = wx.gif_url("0001")           # URL for <img>

# Workout & supplements
workout = wx.workout.generate(goal="hypertrophy", days=4)
stack   = wx.supplements.stack(goal="cut")

# Body Scan
credits = wx.scan.credits()
history = wx.scan.history(limit=10)

# Account & billing
login    = wx.auth.login("u@x.com", "•••")   # token cached for scan/auth/billing
me       = wx.auth.me()
keys     = wx.auth.list_keys()
sub      = wx.billing.status()
checkout = wx.billing.checkout("pro", "yearly")   # -> {"url": ...} to redirect to Stripe

Authentication

Product Resources Credential
Exercises exercises, gifs, workout, supplements api_key (wx_...)
Body Scan / Account / Billing scan.*, auth.*, billing.* Bearer JWT

auth, scan, and billing share the same Bearer token — a successful auth.login() caches it, so later scan.* / billing.* calls work without re-supplying credentials. Google OAuth (/v1/auth/google) is a browser-redirect flow and is intentionally not wrapped.

For Body Scan, pass a ready token or let the SDK log in for you:

WorkoutX(api_key=key, scan_token="eyJ...")                       # ready token
WorkoutX(api_key=key, scan_email="u@x.com", scan_password="•")   # auto-login

Avoiding the "name as ID" 404

exercises.get(id) needs an exact numeric ID (IDs have gaps). For names, use by_name, or the resolver that tries an ID then falls back to a name search:

ex = wx.exercises.find("lunges")   # dict | None

API v2

wx.v2 is the new exercise catalog: 1,900+ movements as 2,700+ clips (male and female models are separate exercises, linked by counterpartId), with 720p MP4 media at 30 fps. The API key is always sent in the X-WorkoutX-Key header.

Media links are signed and expire after about 24 hours: store exercise ids, never media URLs, and call fresh_media(id) when you display an exercise. It reuses the links of every exercise the SDK has already received (from list, get, similar, alternatives, workout.generate and workout.program) until they are close to expiry, and only then makes a request. Parameters keep the API's camelCase names (weightKg, bodyFocus, avoidJoints, daysPerWeek).

# Catalog. lang: en, tr, de, es, fr, zh-SG, zh-HK (filters stay English)
page    = wx.v2.list(body_part="chest", model="female", lang="de")
bench   = wx.v2.get("ex_SAWOOH", lang="tr")    # Barbell Bench Press
from_v1 = wx.v2.legacy("0025")                 # v1 id -> v2 exercise

# Similar exercises, alternatives and calories
similar = wx.v2.similar("ex_SAWOOH", limit=5)  # {exerciseId, model, total, limit, offset, results}
for ex in similar["results"]:
    print(ex["name"], ex["score"])             # full v2 exercises, best first
alts = wx.v2.alternatives("ex_SAWOOH", equipment="dumbbell", model="any")
kcal = wx.v2.calories("ex_SAWOOH", weightKg=80, minutes=20)   # kcal["totalKcal"]

# Workout sessions (lists are sent comma-separated)
session = wx.v2.workout.generate(
    goal="muscle_gain", duration=45, equipment="home",  # or ["dumbbell", "bench"]; presets gym, home, bodyweight
    split="upper", avoidJoints=["shoulder"], format="superset", model="female",
)
for step in session["warmup"]["items"]:
    print(step["exercise"]["name"], step["durationSeconds"])
for x in session["exercises"]:
    # block "C1" + "C2" = a superset; role: main, secondary, accessory, core, conditioning, mobility
    links = wx.v2.fresh_media(x["exercise"]["id"])  # no request: cached from generate()
    print(x["block"], x["exercise"]["name"], x["sets"], x.get("reps") or f'{x["durationSeconds"]}s',
          x.get("rir"), x["cue"], links and links["mp4"])

# Multi-week programs: exercises reference exerciseLibrary by id
program = wx.v2.workout.program(goal="strength", weeks=12, daysPerWeek=4, seed="plan-1")
library = {e["id"]: e for e in program["exerciseLibrary"]}
for week in program["program"]:
    for day in week["days"]:
        for x in day["exercises"]:
            print(week["week"], week["phase"], day["weekday"], library[x["exerciseId"]]["name"], x["sets"], x.get("reps"))

# Supplements (take v2 exercise ids)
supps = wx.v2.supplements.list(goal="strength", evidence="strong")
picks = wx.v2.supplements.for_exercise("ex_SAWOOH", limit=3)
stack = wx.v2.supplements.stack(goal="muscle_gain", level="essential")

A session (workout.generate) has a summary, a warmup (with rampUp sets before the first main lift), exercises and a cooldown. Each exercise has a block ("A", "B", "C1"/"C2" for a superset), role, movement pattern, sets, reps or durationSeconds, restSeconds, rir, tempo, load, a form cue, a rationale and light alternatives (no media: wx.v2.get(id) them when the user swaps). Circuits add circuit timing and rounds. goal takes muscle_gain, strength, fat_loss, endurance, mobility or general_fitness; duration is 15 to 120 minutes; avoidJoints takes knee, shoulder, lumbar_spine, elbow, wrist, hip, ankle; format is auto, straight, superset or circuit.

A program (workout.program, 2 to 16 weeks, seed for a repeatable plan) has a schedule, a progressionModel, blocks with deload weeks, weeklyVolume per muscle group, the session templates (sessions) and the weeks (program). Their exercises are light references by exerciseId; each exercise appears once, with media, in exerciseLibrary, and fresh_media reuses those links. Programs take no split, bodyFocus or exclude.

Feature Plans
similar, alternatives, calories all plans
Joint & Rehab filters on list (jointFocus, intensityLevel, movementTag) Growth, Scale (legacy Ultra)
workout.generate, supplements.* except stack Growth, Scale (legacy Pro, Ultra)
workout.program, supplements.stack Scale (legacy Ultra)

On a plan without the feature, the call raises WorkoutXError with status 403; e.body["requiredPlan"] names the cheapest plan that has it.

Error handling

from workoutx import WorkoutXError

try:
    wx.exercises.get("nope")
except WorkoutXError as e:
    e.status        # 404
    e.code          # "Not Found"
    e.tip           # hint from API, when present
    e.is_not_found  # plus is_auth_error, is_rate_limited

Transient failures (429, 5xx, network) are retried automatically with backoff, honoring Retry-After.

Development

pip install -e ".[test]"
pytest          # 44 offline unit tests (no network)

About WorkoutX

WorkoutX is a developer-first fitness API — a modern ExerciseDB alternative that bundles everything you need to build workout, training, and health apps behind a single key:

  • 🏋️ 1,300+ exercises with animated form GIFs, target & secondary muscles, equipment, and step-by-step instructions
  • 🧠 Workout generator and multi-week training programs
  • 💊 Supplement intelligence — recommended stacks per goal and per exercise
  • 📸 AI Body Scan — body-fat %, measurements, and composition from photos
  • 🔌 Clean REST API with official SDKs for JavaScript, Python, Flutter, and Swift

Official SDKs

License

MIT

Metadata

Release files for workoutx-sdk 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for workoutx-sdk 0.2.0
File Size Uploaded Provenance
workoutx_sdk-0.2.0.tar.gz 25.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for workoutx-sdk 0.2.0
File Interpreter ABI Platform
workoutx_sdk-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 46.6 kB

Release files / workoutx_sdk-0.2.0.tar.gz

Download URL workoutx_sdk-0.2.0.tar.gz
Size 25.7 kB
Tags Source
SHA-256 checksum
How to use checksums
65b60f4a863ac415fa28595afb9a51044c521a3c9e0d14110b42510aa8f29f5e
BLAKE2b-256 checksum
How to use checksums
8a167bc4c1b393a159a56c799ba36b80e1fe4855812a1bf3b98bdb551190ff9e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Release files / workoutx_sdk-0.2.0-py3-none-any.whl

Download URL workoutx_sdk-0.2.0-py3-none-any.whl
Size 20.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d7b0c9f9e76201554fcfea657b9007cb192d0d7c85cb72f7aae69090a64cfcd8
BLAKE2b-256 checksum
How to use checksums
6e6d568832ca3b5d4d05d75b1c69eec6396065a2dfac1d826424612d9873d0bb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Security for workoutx-sdk 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page