Whatsonzwift APIwhatsonzwift.com ↗
Access Zwift workout collections, training plans, interval details, TSS scores, intensity zones, and scheduled group workout events via the What's on Zwift API.
What is the Whatsonzwift API?
The What's on Zwift API exposes 4 endpoints covering Zwift's full workout library, training plan schedules, and live group workout events. Use get_workout_details to retrieve per-workout interval steps, duration, TSS scores, and time-in-zone breakdowns across Z1–Z6, or call get_group_workouts to pull currently scheduled group events with start times, routes, and category groupings.
No input parameters required.
curl -X GET 'https://api.parse.bot/scraper/1dc2ef3e-37ee-433b-ba24-cd7877d6d894/get_all_collections' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace whatsonzwift-com-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
from parse_apis.whats_on_zwift_api import WhatsOnZwift, Collection, WorkoutSummary, Workout, GroupEvent, CollectionType
zwift = WhatsOnZwift()
# List all collections and filter to training plans
for collection in zwift.collections.list():
if collection.type == CollectionType.PLAN:
print(collection.name, collection.slug)
break
# Get a specific collection and browse its workouts
build_me_up = zwift.collections.get(slug="build-me-up")
for workout_summary in build_me_up.workouts.list():
print(workout_summary.name, workout_summary.duration, workout_summary.tss)
# Get full workout details from a summary
first_workout = next(iter(build_me_up.workouts.list()))
workout = first_workout.details(collection_slug="build-me-up")
print(workout.title, workout.duration, workout.tss)
for step in workout.steps:
print(step)
# Browse scheduled group events
for event in zwift.groupevents.list(limit=5):
print(event.name, event.world, event.route, event.start_time_utc)
List all workout collections, training plans, and legacy collections available on Zwift. Returns an array of collection objects classified by type (collection, plan, or legacy_collection). Each entry includes a slug usable as input to get_collection_details.
No input parameters required.
{
"type": "object",
"fields": {
"collections": "array of collection objects with name, url, slug, and type"
},
"sample": {
"data": {
"collections": [
{
"url": "https://whatsonzwift.com/workouts/10-12wk-ftp-builder",
"name": "10 12Wk Ftp Builder",
"slug": "10-12wk-ftp-builder",
"type": "collection"
},
{
"url": "https://whatsonzwift.com/workouts/build-me-up",
"name": "Build Me Up",
"slug": "build-me-up",
"type": "plan"
}
]
},
"status": "success"
}
}About the Whatsonzwift API
Workout Collections and Training Plans
get_all_collections returns every workout collection and training plan listed on whatsonzwift.com as an array of objects, each carrying a name, url, slug, and type field — where type is one of collection, plan, or legacy_collection. The slug values feed directly into get_collection_details, which returns the full list of workouts within that collection, including per-workout duration, tss, and week fields. Plans that follow a weekly structure populate the weeks array; unstructured collections leave it empty.
Individual Workout Data
get_workout_details takes two required parameters — workout_slug and collection_slug — and returns the deepest level of workout data available: a steps array describing each interval in sequence, a zones object mapping Z1 through Z6 to time spent in each, plus tss, duration, title, and description. This makes it straightforward to reconstruct a full workout profile or compare intensity distribution across workouts within a plan.
Scheduled Group Workouts
get_group_workouts returns all currently scheduled group workout events, with each event object including event_id, name, world, route, start_time_utc, duration, tss, groups, and sport. The total field gives the count of events in the response. Event data reflects what is upcoming on Zwift today and in the near future — it is not a historical archive.
The Whatsonzwift API is a managed, monitored endpoint for whatsonzwift.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when whatsonzwift.com changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official whatsonzwift.com API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Build a Zwift training plan browser that displays week-by-week workout schedules using
weeksandworkoutmetadata fromget_collection_details. - Calculate average TSS across all workouts in a collection to compare training load between plans.
- Render interval charts for individual workouts using the ordered
stepsarray and Z1–Z6zonesdata fromget_workout_details. - Surface upcoming group workout events filtered by
sportorworldfor a Zwift companion app. - Identify workouts in a given duration range by filtering the
durationfield across all workouts in a collection. - Compare intensity zone distributions across workouts within a training plan to analyze volume vs. threshold focus.
- Display a daily event schedule with start times and routes by polling
get_group_workoutsfor thestart_time_utcandroutefields.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does Zwift have an official developer API?+
What does `get_group_workouts` return, and how current is the event data?+
get_group_workouts returns events scheduled for today and the near future, including event_id, name, world, route, start_time_utc, duration, tss, groups, and sport. It reflects the current event schedule as listed on whatsonzwift.com — it is not a historical log of past events.Does `get_workout_details` return power targets or watt values for each interval?+
steps array describes each interval as a string (e.g. readable descriptions of effort and duration) rather than raw watt or percentage-of-FTP values. Structured numeric power data per step is not currently exposed. You can fork this API on Parse and revise it to add an endpoint that extracts numeric intensity targets if that field is present in the source.Can I filter group workout events by world, sport, or group category through the API?+
get_group_workouts returns all upcoming events in a single response with world, sport, and groups fields on each event object. Filtering is not done server-side — the full list is returned and filtering must be applied client-side. The API does not currently support query parameters to narrow results at the request level. You can fork it on Parse and revise to add filter parameters if needed.Are Zwift routes, map data, or rider profile information covered by this API?+
route field within group workout events. Standalone route data, map details, and rider profiles are not covered. You can fork this API on Parse and revise it to add a route-focused endpoint.