{
  "openapi": "3.0.1",
  "info": {
    "title": "Sporting Life Scraper - Racecards, Results & Odds API",
    "description": "Scrape Sporting Life horse racing: racecards, results, runners, weights, official ratings, Timeform commentary, bookmaker odds, tote payouts, and horse, jockey and trainer profiles. UK, Ireland, France and USA. No login, no API key, no proxy.",
    "version": "0.1",
    "x-build-id": "ZdYWLNVGOavi9hrcy"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/parseforge~sporting-life-racing-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-parseforge-sporting-life-racing-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/parseforge~sporting-life-racing-scraper/runs": {
      "post": {
        "operationId": "runs-sync-parseforge-sporting-life-racing-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/parseforge~sporting-life-racing-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-parseforge-sporting-life-racing-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": {
          "dateFrom": {
            "title": "Date from",
            "pattern": "^$|^\\d{4}-\\d{2}-\\d{2}$",
            "type": "string",
            "description": "First race day to collect, as YYYY-MM-DD. Racecards are published about five days ahead and results go back to early 2005. Leave both dates empty to scrape today.\n\nExample: 2026-08-24"
          },
          "dateTo": {
            "title": "Date to",
            "pattern": "^$|^\\d{4}-\\d{2}-\\d{2}$",
            "type": "string",
            "description": "Last race day to collect, as YYYY-MM-DD, inclusive. Leave empty to use the same day as Date from.\n\nExample: 2026-08-26"
          },
          "startUrls": {
            "title": "Sporting Life URLs",
            "type": "array",
            "description": "Any sportinglife.com racing URL: a racecard, a result, a race-day listing, or a horse, jockey, or trainer profile. Each one is recognised automatically.\n\nExamples:\n- https://www.sportinglife.com/racing/racecards/2026-08-26/catterick/racecard/934971/berber-leather-maiden-stakes\n- https://www.sportinglife.com/racing/results/2026-08-24\n- https://www.sportinglife.com/racing/profiles/horse/em-four/1165390",
            "items": {
              "type": "string"
            }
          },
          "raceIds": {
            "title": "Race IDs",
            "type": "array",
            "description": "Numeric Sporting Life race IDs to fetch in full, without going through a race-day listing.\n\nExample: 934971",
            "items": {
              "type": "string"
            }
          },
          "horseIds": {
            "title": "Horse IDs",
            "type": "array",
            "description": "Numeric horse IDs. Each one returns a profile row with pedigree, career record, full form, and upcoming entries.\n\nExample: 1165390",
            "items": {
              "type": "string"
            }
          },
          "jockeyIds": {
            "title": "Jockey IDs",
            "type": "array",
            "description": "Numeric jockey IDs. Each one returns a profile row with recent rides, strike rate, and upcoming bookings.\n\nExample: 29850",
            "items": {
              "type": "string"
            }
          },
          "trainerIds": {
            "title": "Trainer IDs",
            "type": "array",
            "description": "Numeric trainer IDs. Each one returns a profile row with recent runners, strike rate, and upcoming entries.\n\nExample: 197",
            "items": {
              "type": "string"
            }
          },
          "outputMode": {
            "title": "Row shape",
            "enum": [
              "runners",
              "races",
              "meetings"
            ],
            "type": "string",
            "description": "What one dataset row represents. Runner is the flat, spreadsheet-friendly shape and the default.",
            "default": "runners"
          },
          "maxItems": {
            "title": "Maximum rows",
            "minimum": 1,
            "maximum": 1000000,
            "type": "integer",
            "description": "Total rows to write in this run. Free Apify plans return a 10-row preview."
          },
          "racesPerDay": {
            "title": "Races per race day",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "Cap the races taken from each day's card so one busy Saturday cannot use up the whole run. Leave empty to take every race that passes the filters."
          },
          "countries": {
            "title": "Countries",
            "type": "array",
            "description": "Keep only meetings in these countries. Matches the country name or its short code, case-insensitive.\n\nAvailable: England, Scotland, Wales, Eire, Northern Ireland, France, United States, plus other international cards the feed carries.",
            "items": {
              "type": "string"
            }
          },
          "courses": {
            "title": "Courses",
            "type": "array",
            "description": "Keep only these racecourses. Full or partial name, case-insensitive.\n\nExamples:\n- Ascot\n- Newmarket\n- Cheltenham",
            "items": {
              "type": "string"
            }
          },
          "surfaces": {
            "title": "Surfaces",
            "type": "array",
            "description": "Keep only races run on these surfaces.",
            "items": {
              "type": "string",
              "enum": [
                "TURF",
                "ALLWEATHER",
                "POLYTRACK",
                "FIBRESAND",
                "TAPETA",
                "DIRT",
                "SAND"
              ],
              "enumTitles": [
                "Turf",
                "All-weather",
                "Polytrack",
                "Fibresand",
                "Tapeta",
                "Dirt",
                "Sand"
              ]
            }
          },
          "raceClasses": {
            "title": "Race classes",
            "type": "array",
            "description": "Keep only these British race classes. Class 1 is the highest. Irish, French, and US races usually carry no class.",
            "items": {
              "type": "string",
              "enum": [
                "1",
                "2",
                "3",
                "4",
                "5",
                "6",
                "7"
              ],
              "enumTitles": [
                "Class 1",
                "Class 2",
                "Class 3",
                "Class 4",
                "Class 5",
                "Class 6",
                "Class 7"
              ]
            }
          },
          "raceStages": {
            "title": "Race stages",
            "type": "array",
            "description": "Keep only races at these stages. DORMANT is an upcoming race, OFF is running, WEIGHEDIN and RESULT are settled.",
            "items": {
              "type": "string",
              "enum": [
                "DORMANT",
                "OFF",
                "WEIGHEDIN",
                "RESULT",
                "ABANDONED"
              ],
              "enumTitles": [
                "Upcoming (DORMANT)",
                "Running (OFF)",
                "Weighed in",
                "Result",
                "Abandoned"
              ]
            }
          },
          "handicapFilter": {
            "title": "Handicaps",
            "enum": [
              "any",
              "handicap",
              "nonHandicap"
            ],
            "type": "string",
            "description": "Keep handicaps only, non-handicaps only, or both.",
            "default": "any"
          },
          "raceNameContains": {
            "title": "Race name contains any of",
            "type": "array",
            "description": "Keep only races whose name contains at least one of these terms. Case-insensitive.\n\nExamples:\n- Hurdle\n- Chase\n- Group 1\n- Maiden",
            "items": {
              "type": "string"
            }
          },
          "goingContains": {
            "title": "Going contains any of",
            "type": "array",
            "description": "Keep only races whose going description contains at least one of these terms. Case-insensitive.\n\nExamples:\n- Good to Firm\n- Soft\n- Standard",
            "items": {
              "type": "string"
            }
          },
          "minRunners": {
            "title": "Minimum declared runners",
            "minimum": 1,
            "maximum": 100,
            "type": "integer",
            "description": "Drop races with fewer declared runners than this."
          },
          "maxRunners": {
            "title": "Maximum declared runners",
            "minimum": 1,
            "maximum": 100,
            "type": "integer",
            "description": "Drop races with more declared runners than this."
          },
          "minPrize": {
            "title": "Minimum winner's prize",
            "minimum": 0,
            "type": "number",
            "description": "Drop races whose first-place prize is below this. The number is in the race's own currency (GBP, EUR, or USD), which is reported as prizeCurrency."
          },
          "timeFrom": {
            "title": "Earliest race time",
            "pattern": "^$|^\\d{1,2}:\\d{2}$",
            "type": "string",
            "description": "Keep only races off at or after this local course time, as HH:MM.\n\nExample: 14:00"
          },
          "timeTo": {
            "title": "Latest race time",
            "pattern": "^$|^\\d{1,2}:\\d{2}$",
            "type": "string",
            "description": "Keep only races off at or before this local course time, as HH:MM.\n\nExample: 18:30"
          },
          "horseNameContains": {
            "title": "Horse name contains any of",
            "type": "array",
            "description": "Keep only runners whose horse name contains at least one of these terms. Case-insensitive.",
            "items": {
              "type": "string"
            }
          },
          "trainerNameContains": {
            "title": "Trainer name contains any of",
            "type": "array",
            "description": "Keep only runners from trainers whose name contains at least one of these terms. Case-insensitive.\n\nExample: Appleby",
            "items": {
              "type": "string"
            }
          },
          "jockeyNameContains": {
            "title": "Jockey name contains any of",
            "type": "array",
            "description": "Keep only runners ridden by jockeys whose name contains at least one of these terms. Case-insensitive.\n\nExample: Moore",
            "items": {
              "type": "string"
            }
          },
          "ownerNameContains": {
            "title": "Owner name contains any of",
            "type": "array",
            "description": "Keep only runners whose owner name contains at least one of these terms. Case-insensitive.\n\nExample: Godolphin",
            "items": {
              "type": "string"
            }
          },
          "minOfficialRating": {
            "title": "Minimum official rating",
            "minimum": 0,
            "maximum": 200,
            "type": "integer",
            "description": "Drop runners rated below this by the handicapper. Unrated horses are dropped when this is set."
          },
          "maxOfficialRating": {
            "title": "Maximum official rating",
            "minimum": 0,
            "maximum": 200,
            "type": "integer",
            "description": "Drop runners rated above this by the handicapper."
          },
          "minAge": {
            "title": "Minimum horse age",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Drop runners younger than this, in years."
          },
          "maxAge": {
            "title": "Maximum horse age",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Drop runners older than this, in years."
          },
          "minOddsDecimal": {
            "title": "Minimum decimal odds",
            "minimum": 1,
            "maximum": 1000,
            "type": "number",
            "description": "Drop runners priced shorter than this, in decimal odds including the stake. Accepts decimals: 3.5 means 5/2 or bigger."
          },
          "maxOddsDecimal": {
            "title": "Maximum decimal odds",
            "minimum": 1,
            "maximum": 1000,
            "type": "number",
            "description": "Drop runners priced longer than this, in decimal odds including the stake. Accepts decimals: 6.5 means 11/2 or shorter."
          },
          "favouritesOnly": {
            "title": "Favourites only",
            "type": "boolean",
            "description": "Keep only the favourite in each race. Sporting Life flags the favourite only once a race has run, so on an upcoming card the shortest price in the race is used instead. Joint favourites all match. Verified to agree with the flag on every settled race tested.",
            "default": false
          },
          "finishPositions": {
            "title": "Finish outcome",
            "type": "array",
            "description": "For settled races, keep only runners with these outcomes. Leave empty to keep every runner.",
            "items": {
              "type": "string",
              "enum": [
                "winner",
                "placed",
                "unplaced",
                "nonFinisher"
              ],
              "enumTitles": [
                "Winners",
                "Placed",
                "Unplaced finishers",
                "Non-finishers (fell, pulled up, unseated)"
              ]
            }
          },
          "includeNonRunners": {
            "title": "Include non-runners",
            "type": "boolean",
            "description": "Keep withdrawn horses as rows, flagged with isNonRunner. Off by default so the dataset holds only horses that actually take part.",
            "default": false
          },
          "includeBookmakerOdds": {
            "title": "Bookmaker odds",
            "type": "boolean",
            "description": "Add live prices from every bookmaker Sporting Life carries, plus the best available price and its bookmaker, to each runner. One extra request per race. Firms price up on the morning of the race: before that they answer SP and no price is returned or billed, and once a race is settled the market is gone.",
            "default": false
          },
          "includeHorseForm": {
            "title": "Horse form history",
            "type": "boolean",
            "description": "Add each horse's previous runs as a nested form array: date, course, distance, going, position, weight, official rating, starting price, and the in-running comment.",
            "default": false
          },
          "includePedigree": {
            "title": "Pedigree",
            "type": "boolean",
            "description": "Add sire, dam, damsire, and coat colour to each runner. Costs one profile request per horse, so it makes big runs noticeably slower.",
            "default": false
          },
          "includeFutureEntries": {
            "title": "Upcoming entries",
            "type": "boolean",
            "description": "Add the races each horse is already entered for, with date, course, distance, and race name. Reads the horse profile, so it costs one request per horse and shares that request with Pedigree.",
            "default": false
          },
          "includeVideos": {
            "title": "Race replay",
            "type": "boolean",
            "description": "Add the race replay and its caption. Racing TV courses return a direct MP4 in replayUrl; At The Races courses return only a host-less provider path in replayStreamPath, which is reported but never billed.",
            "default": false
          },
          "includeLastYearsWinners": {
            "title": "Last year's winners",
            "type": "boolean",
            "description": "Add the previous runnings' winners of the same race, with trainer, jockey, weight carried, and starting price.",
            "default": false
          },
          "includeTipsterNaps": {
            "title": "Tipster naps table",
            "type": "boolean",
            "description": "Also write the naps table: every national tipster's nap of the day with their running wins, losses, and profit to level stakes.",
            "default": false
          },
          "includeArticles": {
            "title": "Tips and news articles",
            "type": "boolean",
            "description": "Also write Sporting Life's racing tips and news articles with title, author, snippet, and publish date.",
            "default": false
          },
          "maxConcurrency": {
            "title": "Parallel requests",
            "minimum": 1,
            "maximum": 40,
            "type": "integer",
            "description": "How many race cards to fetch at once. The default suits every run; lower it only if you are routing through a slow proxy.",
            "default": 12
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "Optional. The site does not block datacenter traffic, so leaving this off costs you nothing and saves the proxy line on your bill.",
            "default": {
              "useApifyProxy": false
            }
          }
        }
      },
      "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
                  }
                }
              },
              "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}