What you will build
A fitness GPT is a custom ChatGPT (or any LLM assistant) that answers training questions using real exercise data instead of whatever the model happens to remember. In this guide you connect a Custom GPT to the WorkoutX Exercise API through GPT Actions, so it can look up exercises by body part, pull step-by-step instructions, form tips and a video demonstration (media.mp4 with a poster image) for any exercise, suggest alternatives for the equipment a user has, and generate a complete workout session with one call.
The same setup works for a custom GPT workout generator, an AI fitness chatbot inside your own app, or an agent built on Claude or another model with tool calling. The API does the data work; the model handles the conversation.
- Exercise lookup: 1,900+ exercises with body part, target muscle, equipment, instructions, form tips and a 720p MP4 animation.
- Structured workouts:
/v2/workout/generatereturns a warm-up, exercises in blocks (straight sets, supersets or a circuit) with sets, reps, rest, effort, a short rationale, swap suggestions and a video for each, and a cool-down. It is a rule-based engine, so the model never has to invent the programming. - Conversational follow-ups:
/v2/exercises/{id}/alternativesanswers "I don't have a barbell, what else?", and/v2/exercises/{id}/similaranswers "what's like this one?"
Which plan do you need?
Exercise lookup endpoints (search, by ID, similar, alternatives and calories) work on every plan, including Free (500 requests in total, 30 requests/minute, up to 10 results per request, watermarked video previews, no credit card). The AI Workout Generator (/v2/workout/generate) requires Growth ($39/month) or Scale ($79/month). The multi-week program generator (/v2/workout/program) is Scale only. Legacy Pro and Ultra subscribers keep the features they have. See pricing for all limits. Calling a plan-gated endpoint with a lower-tier key returns 403.
Step 1 — Create your API key
Register on the WorkoutX Developer Portal and copy your key (it starts with wx_). Every request goes to the base URL https://api.workoutxapp.com/v2 and authenticates with the X-WorkoutX-Key header (v2 rejects keys in the URL). Test your key before wiring up the GPT:
curl 'https://api.workoutxapp.com/v2/exercises?bodyPart=chest&limit=5' \
-H "X-WorkoutX-Key: wx_your_key_here"
Step 2 — Add a Custom GPT Action
In ChatGPT, open the GPT editor, go to Configure → Actions → Create new action. Set Authentication to API Key, auth type Custom, header name X-WorkoutX-Key, and paste your key. Then paste a schema. The minimal OpenAPI 3 spec below covers four real endpoints and is enough for a useful fitness GPT:
openapi: 3.1.0
info:
title: WorkoutX Exercise API
version: "1.0"
servers:
- url: https://api.workoutxapp.com
paths:
/v2/exercises:
get:
operationId: searchExercises
summary: Find exercises by body part, target muscle, equipment or name
parameters:
- name: bodyPart
in: query
schema:
type: string
enum: [back, cardio, chest, lower arms, lower legs, neck,
shoulders, upper arms, upper legs, waist]
- name: target
in: query
description: Target muscle, e.g. pectorals, quads, glutes
schema: { type: string }
- name: equipment
in: query
description: e.g. body weight, dumbbell, barbell, band
schema: { type: string }
- name: name
in: query
schema: { type: string }
- name: limit
in: query
schema: { type: integer, default: 10 }
/v2/exercises/{id}:
get:
operationId: getExerciseById
summary: Get one exercise with instructions, tips and media links
parameters:
- name: id
in: path
required: true
description: A v2 exercise id, e.g. ex_WOZL6H
schema: { type: string }
/v2/exercises/{id}/alternatives:
get:
operationId: getExerciseAlternatives
summary: Same target muscle, different equipment
parameters:
- name: id
in: path
required: true
schema: { type: string }
- name: equipment
in: query
description: Equipment the user has, ranked first, e.g. dumbbell
schema: { type: string }
/v2/workout/generate:
get:
operationId: generateWorkout
summary: Generate a structured workout session (Growth and Scale plans)
parameters:
- name: goal
in: query
schema:
type: string
enum: [muscle_gain, strength, fat_loss, endurance, mobility,
general_fitness]
- name: duration
in: query
description: Minutes, warm-up and cool-down included
schema: { type: integer, minimum: 15, maximum: 120, default: 45 }
- name: level
in: query
schema: { type: string, enum: [beginner, intermediate, advanced] }
- name: split
in: query
schema:
type: string
enum: [full_body, full_body_b, full_body_c, upper, upper_b,
lower, lower_b, push, push_b, pull, pull_b, legs,
legs_b, core, conditioning, mobility]
- name: equipment
in: query
description: >-
Comma-separated, e.g. dumbbell,bench, or a preset: home,
bodyweight, gym. Body weight is always included.
schema: { type: string }
- name: avoidJoints
in: query
description: >-
Comma-separated joints to protect: knee, shoulder,
lumbar_spine, elbow, wrist, hip, ankle
schema: { type: string }
- name: format
in: query
schema:
type: string
enum: [auto, straight, superset, circuit]
default: auto
- name: model
in: query
description: Which model the exercise videos show
schema: { type: string, enum: [male, female], default: male }
components:
schemas: {}
securitySchemes:
WorkoutXKey:
type: apiKey
in: header
name: X-WorkoutX-Key
security:
- WorkoutXKey: []
Want more endpoints (similar exercises, calories, multi-week programs, supplements)? Add them the same way from the v2 endpoint list in the API docs. More actions give the GPT more options, but a trimmed spec with clear summary lines usually leads to more reliable action selection.
Plan note: if your key is on Free or Starter, remove generateWorkout from the schema so the GPT doesn't call an endpoint that will return 403.
Step 3 — Paste a ready system prompt
Put this in the GPT's Instructions field. It tells the model when to call each action and how to present the results:
You are a friendly strength and conditioning assistant.
Always use the WorkoutX actions for exercise data. Never invent exercises.
When a user asks for a workout:
1. Ask for goal, time available, experience level and equipment if missing,
and whether any joint (knee, shoulder, lower back...) needs care.
2. Call generateWorkout with goal, duration, level and equipment, plus
avoidJoints when they mentioned a joint (lower back = lumbar_spine).
3. Present the warm-up (warmup.items), then the exercises in block order:
sets x reps (or seconds), rest and reps in reserve (rir). Blocks with the
same letter (C1, C2) are a superset; in a circuit give the rounds.
Add each exercise's rationale in a few words, then the cool-down
(cooldown.items) and any notes.
4. If the user wants to swap an exercise, offer its alternatives and call
getExerciseById for the one they pick.
When a user asks how to do an exercise:
- Call getExerciseById (or searchExercises to find it) and summarise
the instructions in 3-5 short steps. Show the media.poster image and
link media.mp4 so they can check their form.
When a user cannot use a piece of equipment:
- Call getExerciseAlternatives with the exercise id and the equipment
they have.
If an action returns 429, tell the user the limit was reached and to try
again shortly. If it returns 403, explain the feature needs a higher plan.
Remind users you are not a medical professional when they mention pain or injury:
avoidJoints is general guidance, not medical advice.
Add a few conversation starters such as "Build me a 30-minute beginner fat-loss workout with dumbbells", "A 45-minute leg day that's easy on my knees" or "How do I do a Romanian deadlift?" and test in the preview pane. You should see ChatGPT ask to call the WorkoutX action, then render a structured session.
Step 4 — The same idea for Claude and other LLMs
You don't need ChatGPT to build an AI fitness chatbot. Claude, and most modern LLM APIs, support tool (function) calling: you describe a tool with a JSON schema, the model returns a tool call with arguments, your server calls WorkoutX, and you pass the JSON result back. A tool definition for the workout generator looks like this:
{
"name": "generate_workout",
"description": "Generate a structured workout session (warm-up, exercises in blocks with sets/reps/rest/effort and swap alternatives, cool-down) via the WorkoutX API. Requires a Growth or Scale key.",
"input_schema": {
"type": "object",
"properties": {
"goal": { "type": "string", "enum": ["muscle_gain", "strength", "fat_loss", "endurance", "mobility", "general_fitness"] },
"duration": { "type": "integer", "minimum": 15, "maximum": 120 },
"level": { "type": "string", "enum": ["beginner", "intermediate", "advanced"] },
"equipment": { "type": "string", "description": "Comma-separated equipment, or a preset: home, bodyweight, gym" },
"avoidJoints": { "type": "string", "description": "Comma-separated: knee, shoulder, lumbar_spine, elbow, wrist, hip, ankle" },
"format": { "type": "string", "enum": ["auto", "straight", "superset", "circuit"] },
"model": { "type": "string", "enum": ["male", "female"] }
},
"required": ["goal", "level"]
}
}
And the server side that executes it keeps your key out of the client:
// Your server runs the tool call the model asks for
async function runTool(name, input) {
if (name === "generate_workout") {
const qs = new URLSearchParams(input).toString();
const res = await fetch(`https://api.workoutxapp.com/v2/workout/generate?${qs}`, {
headers: { "X-WorkoutX-Key": process.env.WORKOUTX_KEY }
});
if (res.status === 429) return { error: "rate_limited", retry: true };
const w = await res.json();
// Every exercise is a full record; send the model a compact version to save tokens
return {
goal: w.goal, format: w.format, minutes: w.estimatedDurationMinutes, notes: w.notes,
warmup: w.warmup.items.map((i) => `${i.exercise.name} ${i.durationSeconds}s`),
exercises: w.exercises.map((x) => ({
block: x.block, name: x.exercise.name, sets: x.sets, rounds: x.rounds,
reps: x.reps, seconds: x.durationSeconds, restSeconds: x.restSeconds, rir: x.rir,
why: x.rationale, swaps: x.alternatives.map((a) => a.name), poster: x.exercise.media?.poster,
})),
cooldown: w.cooldown.items.map((i) => `${i.exercise.name} ${i.durationSeconds}s`),
};
}
}
Define similar tools for exercise search (/v2/exercises), exercise by ID (/v2/exercises/{id}) and alternatives (/v2/exercises/{id}/alternatives), and reuse the system prompt from Step 3. The field names differ slightly between providers (for example input_schema vs parameters), but the pattern is identical. For a deeper walkthrough of the generator endpoint, see our AI workout generator API guide.
Production tips
- Cache exercise lookups. Exercise records change rarely. Cache by ID and body part on your server so repeat questions don't spend quota, but keep cached media links for less than a day: they expire after 24–25 hours.
- Show the animation. Every exercise includes a
media.mp4animation and amedia.posterimage. Showing it next to the instructions is the single biggest trust upgrade for a fitness chatbot. - Handle 429 gracefully. Rate limits and monthly quotas return
429 Too Many Requests. Read theX-RateLimit-RemainingandX-Quota-Remainingheaders, back off, and have the assistant tell the user to retry instead of failing silently. - Use
seedfor reproducible plans. Passing the sameseedto/v2/workout/generatelets a user come back to "the same workout as yesterday". - Pass joint limits, not diagnoses. When a user mentions a sore knee or lower back, send
avoidJointsand let the engine choose gentler exercises. It is general guidance, not medical advice, and the assistant should say so. - Localize. Add
lang(tr, de, es, fr, zh-SG, zh-HK; English by default) to any v2 call, including the workout generator, so the assistant can answer with translated exercise names and instructions. Filters still take English values. - Keep keys server-side. GPT Actions store the key for you; in your own app, proxy requests through a backend.
Frequently asked questions
Can I build a Custom GPT that uses an exercise API?
Yes. Create an Action in the GPT editor, set API Key authentication with the custom header X-WorkoutX-Key, and paste an OpenAPI schema for the WorkoutX v2 endpoints you want (this guide includes a ready one). Every v2 endpoint is listed in the API docs at https://workoutxapp.com/docs.html.
Which WorkoutX plan do I need for a custom GPT workout generator?
Exercise lookup endpoints (search, by ID, similar, alternatives, calories) work on every plan, including Free. The /v2/workout/generate endpoint (AI Workout Generator) requires the Growth ($39/month) or Scale ($79/month) plan, and the multi-week /v2/workout/program endpoint (Workout Programs) requires Scale. Legacy Pro and Ultra subscribers keep the features they have.
Does this work with Claude or other LLMs, not just ChatGPT?
Yes. Any model that supports tool or function calling can use the same endpoints. Describe each endpoint as a tool with a JSON schema, execute the call on your server with the X-WorkoutX-Key header, and return the JSON result to the model.
How do I show exercise demonstrations in the chatbot?
Every WorkoutX v2 exercise includes a media object with an mp4 animation and a poster image. In your own app, play the mp4 muted and looping next to the instructions; in ChatGPT, have the assistant show the poster and link the video. The links expire after 24–25 hours, so fetch the exercise again instead of reusing old links.
What happens when my fitness GPT hits the rate limit?
The API returns HTTP 429 when a per-minute rate limit or monthly quota is exceeded. Cache repeat lookups, watch the X-RateLimit-Remaining and X-Quota-Remaining response headers, and have the assistant ask the user to retry shortly.
Give your GPT real exercise data
Get a free API key in under a minute, test the lookup endpoints, and upgrade to Growth when you want AI workout generation.