ProCyclingStats APIprocyclingstats.com ↗
Extract race results, team lists, and all-time victory rankings from ProCyclingStats. 3 endpoints covering stage races, one-day classics, and pro cycling teams.
What is the ProCyclingStats API?
The ProCyclingStats API provides 3 endpoints for accessing professional cycling data including detailed race results, team rosters by year, and all-time career victory rankings. The get_race_results endpoint returns a full finishing list with rank, rider name, team, time, and UCI points for any stage or one-day race. Teams and rider statistics are available through the remaining two endpoints.
curl -X GET 'https://api.parse.bot/scraper/cf66e8e3-c65a-4b3e-b418-c826000f01c2/get_race_results?url=race%2Ftour-de-france%2F2024%2Fstage-1' \ -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 procyclingstats-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.procyclingstats_api import ProCyclingStats
client = ProCyclingStats()
# Get race results for a Tour de France stage
race = client.raceresults.get(url="race/tour-de-france/2024/stage-1")
print(race.metadata.race_name, race.metadata.distance, race.metadata.departure, race.metadata.arrival)
for finisher in race.results[:5]:
print(finisher.rank, finisher.rider_name, finisher.team_name, finisher.resolved_time)
# List all professional teams for 2024
for team in client.teams.list(year="2024"):
print(team.team_name, team.country)
# Get all-time victory ranking
for rider in client.riders.list():
print(rider.rank, rider.rider_name, rider.victories)
Extract detailed race metadata and results for a specific event (stage or one-day race). Returns race information such as date, distance, departure/arrival cities, and a full list of finishing positions with rider names, teams, times, and UCI points. The url parameter is the path portion on ProCyclingStats (e.g. 'race/tour-de-france/2024/stage-1' or 'race/milano-sanremo/2024'). Metadata fields vary by race type; results are ordered by finishing position.
| Param | Type | Description |
|---|---|---|
| urlrequired | string | The race URL path on ProCyclingStats (e.g. 'race/tour-de-france/2024/stage-1' or 'race/milano-sanremo/2024'). |
{
"type": "object",
"fields": {
"results": "array of finishing positions, each with rank, rider_name, rider_url, team_name, uci_points, time, and resolved_time",
"metadata": "object containing race details such as date, distance, departure, arrival, classification, profile_score, avg_speed_winner, and race_name"
},
"sample": {
"data": {
"results": [
{
"rank": "1",
"time": "5:07:22",
"rider_url": "https://www.procyclingstats.com/rider/romain-bardet",
"team_name": "Team dsm-firmenich PostNL",
"rider_name": "Bardet Romain",
"uci_points": "210",
"resolved_time": "5:07:22"
},
{
"rank": "2",
"time": ",,",
"rider_url": "https://www.procyclingstats.com/rider/frank-van-den-broek",
"team_name": "Team dsm-firmenich PostNL",
"rider_name": "van den Broek Frank",
"uci_points": "150",
"resolved_time": "5:07:22"
}
],
"metadata": {
"date": "29 June 2024",
"arrival": "Rimini",
"distance": "206 km",
"departure": "Firenze",
"race_name": "2024 » 111thTour de France(2.UWT)",
"start_time": "12:40",
"profile_score": "176",
"classification": "2.UWT",
"avg_speed_winner": "40.213 km/h"
}
},
"status": "success"
}
}About the ProCyclingStats API
Race Results
The get_race_results endpoint accepts a url parameter pointing to any race path on ProCyclingStats — for example race/tour-de-france/2024/stage-1 for a stage or race/milano-sanremo/2024 for a one-day classic. The response includes a metadata object with fields such as date, distance, departure, arrival, classification, profile_score, and avg_speed_winner. The results array contains one entry per finisher, each carrying rank, rider_name, rider_url, team_name, uci_points, time, and resolved_time (elapsed time converted to a comparable format).
Teams and Victory Rankings
The get_all_teams endpoint accepts an optional year parameter (e.g. '2024') and returns an array of WorldTour and ProTeam entries, each with team_name and a two-letter country code. This is useful for building year-over-year team directories or filtering results by nation.
The get_victory_ranking endpoint takes no inputs and returns the top 100 riders ranked by all-time career victory count. Each entry includes rank, rider_name, and victories. The list is sorted descending by victory count and reflects cumulative career totals, not a single-season view.
The ProCyclingStats API is a managed, monitored endpoint for procyclingstats.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when procyclingstats.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 procyclingstats.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 live race tracker that displays finishing positions, times, and UCI points for each stage of a Grand Tour.
- Populate a cycling statistics dashboard with all-time career victory leaders using the
get_victory_rankingresponse fields. - Generate year-over-year team composition reports by querying
get_all_teamsfor multiple seasons. - Filter race results by team to analyse a squad's collective performance across a monument classic.
- Map departure and arrival cities from race metadata to visualise route geography across a season.
- Compare
profile_scoreandavg_speed_winnerfields across stages to identify the hardest races in a calendar year. - Build a UCI points tracker by aggregating
uci_pointsper rider across multiple race result responses.
| 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 ProCyclingStats have an official developer API?+
What does the `get_race_results` endpoint return for time fields, and how does `resolved_time` differ from `time`?+
time field contains the raw time string as recorded in the results (e.g. a gap like '+0:32' for riders behind the winner). The resolved_time field converts that into an absolute elapsed time, making it easier to sort or compare finishers without manually parsing gap notation.