{
  "openapi": "3.0.1",
  "info": {
    "title": "ProCyclingStats Scraper: Results & Riders",
    "description": "Scrape ProCyclingStats race and stage results (rank, rider, team, age, UCI and PCS points, time), rider profiles with specialty points and the PCS world ranking. Export CSV, Excel, JSON or XML. No login or API key. Cloudflare handled with residential proxy.",
    "version": "0.1",
    "x-build-id": "hn3ai38MX8IbeoggO"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/recordsdata~procyclingstats-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-recordsdata-procyclingstats-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/recordsdata~procyclingstats-scraper/runs": {
      "post": {
        "operationId": "runs-sync-recordsdata-procyclingstats-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/recordsdata~procyclingstats-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-recordsdata-procyclingstats-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "raceName": {
            "title": "Race name",
            "type": "string",
            "description": "Race to look up by name, for example Paris-Roubaix, Tour de France, Giro d'Italia or Liège-Bastogne-Liège. Use it with Season (year). If the name does not match a ProCyclingStats race page directly, the actor checks the ProCyclingStats search once. Leave empty when you use URLs, teams, riders or rankings."
          },
          "year": {
            "title": "Season (year)",
            "minimum": 1903,
            "maximum": 2100,
            "type": "integer",
            "description": "Season of the race, for example 2025. Leave empty for the latest edition that has results."
          },
          "resultScope": {
            "title": "Result scope",
            "enum": [
              "winnersOnly",
              "finalClassification",
              "stageWinners",
              "allStages"
            ],
            "type": "string",
            "description": "How much of the race to return. Winner only is one row per race. Final classification is the full finishing order of a one-day race or the final general classification of a stage race. Stage winners is one row per stage. All stages returns the full result of every stage, one page per stage.",
            "default": "finalClassification"
          },
          "classification": {
            "title": "Stage-race classification",
            "enum": [
              "gc",
              "points",
              "kom",
              "youth"
            ],
            "type": "string",
            "description": "Which final classification to return for a stage race when the scope is Winner only or Final classification: general classification, points, mountains or youth. One-day races ignore it.",
            "default": "gc"
          },
          "stage": {
            "title": "Single stage number",
            "minimum": 0,
            "maximum": 40,
            "type": "integer",
            "description": "Return the result of one stage of a stage race, for example 21 for the last stage of the Tour de France. 0 means off (the Result scope decides). One-day races ignore it.",
            "default": 0
          },
          "raceContent": {
            "title": "Race content",
            "enum": [
              "results",
              "startlist"
            ],
            "type": "string",
            "description": "Results returns who finished where. Startlist returns the riders entered in the race with bib number and team, before or after the race. Startlist rows are listed under the startlist record type.",
            "default": "results"
          },
          "raceUrls": {
            "title": "Race page URLs",
            "type": "array",
            "description": "ProCyclingStats race pages to scrape, one per line. A result page, a stage page, a final classification page or a startlist page works, for example procyclingstats.com/race/tour-de-france/2025/stage-21 or procyclingstats.com/race/paris-roubaix/2025/startlist. A race page without a page name, such as procyclingstats.com/race/paris-roubaix/2025, follows the Result scope above. Team, rider and ranking URLs are also accepted here.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "teamUrls": {
            "title": "Team URLs, slugs or names",
            "type": "array",
            "description": "Teams whose season roster you want, one rider per row with the rider's current PCS rank, career points, age and specialty. Use URLs such as procyclingstats.com/team/uae-team-emirates-xrg-2025, slugs with the season such as uae-team-emirates-xrg-2025, or a team name such as UAE Team Emirates - XRG (the Season field picks the year, default current year).",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "riderUrls": {
            "title": "Rider URLs, slugs or names",
            "type": "array",
            "description": "Rider profiles to scrape (nationality, birth date, height, weight, specialty points, current and all-time PCS rank), as slugs like tadej-pogacar, full URLs like procyclingstats.com/rider/mathieu-van-der-poel, or plain names like Wout van Aert. A rider that PCS does not know returns one free error row.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "rankingType": {
            "title": "Ranking table",
            "enum": [
              "none",
              "pcs-individual",
              "pcs-teams",
              "pcs-nations",
              "uci-individual",
              "uci-teams",
              "women-pcs-individual",
              "women-uci-individual"
            ],
            "type": "string",
            "description": "Which ProCyclingStats or UCI ranking table to return. Rider tables list 100 riders per page and the actor reads as many pages as Max ranking rows needs. Team and nation tables come whole. Ranking rows are billed as ranking rows.",
            "default": "none"
          },
          "rankingNation": {
            "title": "Ranking nation filter",
            "type": "string",
            "description": "Keep only riders of one nation in a rider ranking, with the 2-letter ProCyclingStats nation code, for example be, fr, co or us. Leave empty for all nations.",
            "default": ""
          },
          "maxRankingRows": {
            "title": "Max ranking rows",
            "minimum": 1,
            "maximum": 2500,
            "type": "integer",
            "description": "How many ranking positions to keep when a ranking table is selected, from 1 to 2500.",
            "default": 100
          },
          "includeRankings": {
            "title": "PCS individual ranking (legacy switch)",
            "type": "boolean",
            "description": "Kept for existing integrations: switching it on is the same as choosing the PCS ranking: riders table above. Use Ranking table for the other tables.",
            "default": false
          },
          "maxItems": {
            "title": "Max Items",
            "minimum": 1,
            "maximum": 1000000,
            "type": "integer",
            "description": "Maximum number of rows to return across race results, startlists, team riders, rider profiles and ranking rows. Free users are limited to 10 rows (preview); paid users up to 1,000,000.",
            "default": 10
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "ProCyclingStats sits behind Cloudflare, so Apify RESIDENTIAL proxy is on by default because it is the most reliable. Datacenter proxy also worked in our tests but can be challenged more often.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "RESIDENTIAL"
              ]
            }
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}