REST API Tutorial for Fitness Apps:
From Zero to Your First Workout Endpoint
A ground-up REST API tutorial written for fitness enthusiasts and bodybuilders who want to build their own workout tools — no prior API experience required. By the end you'll fetch a real exercise list, filter by muscle group, and play a video demonstration.
verified Published by the WorkoutX team — builders of the exercise API used by fitness app developers. Learn more
REST APIs let your fitness app request exercise data over HTTP instead of hand-entering it. This tutorial covers getting a free API key, making your first authenticated request, listing exercises by muscle group, and playing video demonstrations — using plain JavaScript and the WorkoutX API v2.
What Is a REST API, Really?
If you've searched for a "rest api tutorial for fitness enthusiasts" or a "rest api tutorial for bodybuilders," you've probably already tried building a workout app with a hardcoded list of exercises — and hit the wall every developer hits: maintaining that list by hand doesn't scale. A REST API solves this by putting the data on a server you can query whenever you need it.
REST stands for Representational State Transfer — a set of conventions for structuring web requests. In practice, it means: you send an HTTP request to a URL (called an endpoint), you include an API key to prove who you are, and the server sends back structured data, almost always JSON. That's the entire mental model you need before writing code.
Prerequisites
- Basic JavaScript (variables, functions,
fetch) — no framework required - A code editor and a way to run a local HTML file or Node script
- A free WorkoutX API key — registration takes about 30 seconds and needs no credit card
Free tier is enough to follow along. WorkoutX's free plan includes 500 requests in total and 30 requests/minute — far more than this tutorial uses.
Step 1 — Get an API Key
Every request to the WorkoutX API needs to identify itself with an API key, sent in a custom header called X-WorkoutX-Key. Register a free account, copy your key from the dashboard, and keep it somewhere safe — treat it like a password.
// Store your key somewhere you won't commit to Git
const API_KEY = "wx_your_api_key_here";
const BASE_URL = "https://api.workoutxapp.com/v2";
Security note: Never hardcode your key in client-side code you ship publicly. For a real app, proxy requests through your own backend so the key stays server-side. Always send the key in the header: the v2 API rejects a key in the URL (?api-key=) with a 400.
Step 2 — Make Your First Request
The simplest possible call is a request to list exercises. Open a blank HTML file or a Node script and try this:
async function getExercises() {
const res = await fetch(`${BASE_URL}/exercises?limit=10`, {
headers: { "X-WorkoutX-Key": API_KEY }
});
if (!res.ok) {
throw new Error(`Request failed: ${res.status}`);
}
const data = await res.json();
console.log(data);
// { total: 2700+, limit: 10, offset: 0, results: [ { id, name, bodyPart, target, equipment, media, ... }, ... ] }
}
getExercises();
Run it and you'll get back a JSON object with four fields: total (how many exercises match overall), limit and offset (which page you got), and results (the actual array of exercise objects). This wrapper pattern shows up on every list endpoint in the API — get comfortable with it early. Exercise ids look like ex_WOZL6H.
Step 3 — Filter by Muscle Group
For a bodybuilding-focused app, filtering by target muscle or body part is usually the first real feature you need. WorkoutX exposes this as a query parameter:
async function getExercisesByBodyPart(bodyPart) {
const url = `${BASE_URL}/exercises?bodyPart=${encodeURIComponent(bodyPart)}`;
const res = await fetch(url, {
headers: { "X-WorkoutX-Key": API_KEY }
});
return res.json();
}
// Valid body parts include: Back, Chest, Shoulders, Upper Arms,
// Lower Arms, Upper Legs, Lower Legs, Waist, Cardio, Neck
const chest = await getExercisesByBodyPart("Chest");
console.log(`Found ${chest.total} chest exercises`);
const chestExercises = chest.results; // the first page (10 by default)
Each exercise object includes target (the specific muscle, e.g. "pectorals") in addition to the broader bodyPart category, so you can build a two-level filter — body part first, then specific muscle (?bodyPart=Chest&target=Pectorals) — exactly like a gym app's exercise picker. Compound lifts like the barbell bench press and barbell deadlift are good ones to sanity-check your filter against, since they're staples in almost every catalog.
Step 4 — Render a Video Demonstration
Every exercise object includes a media object with an mp4 animation (600×720, 30 fps) and a poster image. This is the feature that turns a plain data list into something people actually use — instead of reading text instructions, users watch the movement.
function renderExerciseCard(exercise) {
const card = document.createElement("div");
card.className = "exercise-card";
card.innerHTML = `
<video src="${exercise.media.mp4}" poster="${exercise.media.poster}"
autoplay loop muted playsinline></video>
<h3>${exercise.name}</h3>
<p>${exercise.bodyPart} · ${exercise.target} · ${exercise.equipment}</p>
`;
return card;
}
const container = document.getElementById("exercise-list");
chestExercises.forEach(ex => {
container.appendChild(renderExerciseCard(ex));
});
The video needs muted and playsinline to autoplay on mobile browsers, and loop to repeat. A clip is typically 100–300 KB, but on long lists show the poster first and start each video as it scrolls into view. The media links expire after 24–25 hours, so save exercise ids in your database, never the URLs, and read fresh links from the response when you show an exercise.
Step 5 — Add Calorie Estimates
For bodybuilders and general fitness enthusiasts tracking training volume, calorie burn is a common addition. WorkoutX exposes a calorie endpoint, on every plan, that factors in bodyweight and duration:
async function estimateCalories(exerciseId, weightKg, minutes) {
const url = `${BASE_URL}/exercises/${exerciseId}/calories?weightKg=${weightKg}&minutes=${minutes}`;
const res = await fetch(url, { headers: { "X-WorkoutX-Key": API_KEY } });
return res.json();
// { id, name, weightKg, minutes, met, baseKcalPerMin, kcalPerMin, totalKcal, note }
}
const burn = await estimateCalories(chestExercises[0].id, 82, 20);
console.log(`~${burn.totalKcal} kcal burned`);
Common Mistakes to Avoid
- Forgetting the API key header. A missing or misspelled
X-WorkoutX-Keyheader returns a 401 — check the exact header name first when debugging auth errors. - Not handling non-200 responses. Always check
res.okbefore callingres.json(); error responses still return a JSON body, but with an error message instead of exercise data. - Calling the API on every keystroke. If you add search, debounce user input by 300ms before firing a request — this alone can cut your request volume by 80%+.
- Fetching everything at once. Use
limitandoffsetfor pagination instead of trying to pull the full 1,900+ exercise catalog in one call.limitis capped at 10 on Free, 100 on Starter and 200 on other plans. - Saving media URLs. The
medialinks expire after 24–25 hours. Store the exercise id and get fresh links from the exercise response or/exercises/{id}/media. - Shipping the API key in a public client bundle. For a production mobile or web app, route requests through your own backend so the key never appears in browser dev tools or a decompiled APK.
What you learned: How REST APIs work end to end — authentication with an API key, fetching and filtering data, handling pagination, and rendering media (looping MP4 video) — using the free WorkoutX exercise API as a real working example.
Free API key — start building in 30 seconds
500 free requests · 1,900+ exercises · 720p video animations · No credit card