{
  "openapi": "3.0.1",
  "info": {
    "title": "Tennis Scraper — Flashscore, SofaScore & TennisExplorer Data",
    "description": "Scrape tennis from Flashscore, SofaScore and TennisExplorer in one Actor — fixtures, live and finished matches, per-match statistics, point-by-point, odds with opening price and line movement, player profiles, head-to-head and ATP/WTA rankings. Pick a source and mode, or paste any URL.",
    "version": "0.0",
    "x-build-id": "cYvN0y4HNxVWwo0uT"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/memo23~flashscore-sofascore-tennis-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-memo23-flashscore-sofascore-tennis-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/memo23~flashscore-sofascore-tennis-scraper/runs": {
      "post": {
        "operationId": "runs-sync-memo23-flashscore-sofascore-tennis-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/memo23~flashscore-sofascore-tennis-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-memo23-flashscore-sofascore-tennis-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": {
          "source": {
            "title": "Data source",
            "enum": [
              "tennisexplorer",
              "flashscore",
              "sofascore",
              "all"
            ],
            "type": "string",
            "description": "Which site to read. Flashscore returns a whole day of matches in one request and needs no proxy — the cheapest option for fixtures and results. SofaScore carries the depth (50+ per-match statistics, point-by-point, odds line movement, ATP/WTA rankings, player bios) and needs no proxy either. TennisExplorer has the per-bookmaker odds history and needs no proxy. \"All sources\" runs all three and splits the item budget evenly between them. Flashscore covers the fixtures, results and matchDetails modes only. In rankings mode it reads the table from TennisExplorer instead; in players, h2h and searchPlayers the run fails. SofaScore has no h2h mode, so that combination fails too.",
            "default": "tennisexplorer"
          },
          "mode": {
            "title": "Mode",
            "enum": [
              "fixtures",
              "results",
              "matchDetails",
              "players",
              "h2h",
              "rankings",
              "searchPlayers"
            ],
            "type": "string",
            "description": "What this run scrapes. `fixtures` = upcoming matches with odds (today by default), `results` = finished matches with scores and closing odds (yesterday by default), `matchDetails` = deep per-match records including per-bookmaker odds history, `players` = full player profiles, `h2h` = head-to-head records, `rankings` = ATP/WTA ranking tables (current or historical), `searchPlayers` = find players and their slugs by name.",
            "default": "fixtures"
          },
          "startUrls": {
            "title": "TennisExplorer URLs (optional — overrides Mode)",
            "type": "array",
            "description": "Any tennisexplorer.com URLs: `/matches/`, `/next/`, `/results/`, `/match-detail/?id=…`, `/player/{slug}/`, `/mutual/{a}/{b}/`, `/ranking/…` or `/list-players/…`. Each URL is auto-classified and routed to the right parser. Leave empty to use Mode instead.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "tourType": {
            "title": "Tour / discipline",
            "enum": [
              "all",
              "atp-single",
              "wta-single",
              "atp-double",
              "wta-double"
            ],
            "type": "string",
            "description": "Which tournaments to include: both tours, or a single tour, singles or doubles.",
            "default": "all"
          },
          "dateFrom": {
            "title": "Date from (YYYY-MM-DD)",
            "type": "string",
            "description": "First day to scrape. Defaults: fixtures = today, results = yesterday. Fixtures for past dates are automatically served from the results pages."
          },
          "dateTo": {
            "title": "Date to (YYYY-MM-DD)",
            "type": "string",
            "description": "Last day, inclusive. Defaults to Date from (a single day). Ranges are capped at 62 days per run."
          },
          "matchIds": {
            "title": "Match IDs",
            "type": "array",
            "description": "Numeric match ids (e.g. `3290771`) or full `/match-detail/?id=…` URLs. Get ids from fixtures/results rows (`matchId` field) or from any TennisExplorer match link. The run fails if this list is empty in matchDetails mode.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "includeOddsHistory": {
            "title": "Include odds history (line movement)",
            "type": "boolean",
            "description": "Keep the full per-bookmaker odds movement — every price change with timestamp plus the opening price — on matchDetails rows, across all four markets (Home/Away, Over/Under, Asian Handicap, Correct Score). Turn off for lighter rows with current + opening odds only.",
            "default": true
          },
          "includeRecentForm": {
            "title": "Include recent form & mutual matches",
            "type": "boolean",
            "description": "Keep the recent-matches blocks (each player's last matches and their mutual meetings) on matchDetails rows.",
            "default": true
          },
          "includePredictionMarkets": {
            "title": "Add Polymarket & Kalshi match-winner prices",
            "type": "boolean",
            "description": "Adds a `predictionMarkets` block to each singles match that has an open Polymarket or Kalshi match-winner market: both players' prices on each venue (0 to 1, so 0.62 means 62%), the bookmakers' win probability with their margin removed when the row carries odds, and the gap between the two. Most prediction-market tennis is ITF and Challenger. Doubles and matches without an open market get `predictionMarkets: null`. Markets close once a match settles, so results runs rarely match.",
            "default": false
          },
          "playerSlugs": {
            "title": "Player slugs or URLs",
            "type": "array",
            "description": "For the players mode: slugs like `djokovic` or full `/player/…` URLs. Find slugs with the searchPlayers mode. The run fails if this list is empty in players mode.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "h2hPairs": {
            "title": "Head-to-head pairs",
            "type": "array",
            "description": "For the h2h mode. One pair per line: `djokovic vs alcaraz-5ab70`, `djokovic, alcaraz-5ab70` or a full `/mutual/…/…/` URL. The run fails if this list is empty in h2h mode.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "searchQuery": {
            "title": "Player search query",
            "type": "string",
            "description": "For the searchPlayers mode: part of a player's name, case-insensitive (e.g. `alcaraz`). Returns matching players with their slugs and current rank for both tours. The run fails if this is empty in searchPlayers mode."
          },
          "rankingTour": {
            "title": "Ranking table",
            "enum": [
              "atp-men",
              "wta-women"
            ],
            "type": "string",
            "description": "Which ranking to walk in rankings mode.",
            "default": "atp-men"
          },
          "rankingDate": {
            "title": "Ranking snapshot date (YYYY-MM-DD)",
            "type": "string",
            "description": "Historical weekly snapshot to read (Mondays). Leave empty for the latest ranking. TennisExplorer keeps weekly snapshots going back years."
          },
          "maxItems": {
            "title": "Maximum results",
            "minimum": 1,
            "type": "integer",
            "description": "Global cap on dataset rows for the run. You are billed per row, so this is your spend guard.",
            "default": 200
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "minimum": 1,
            "type": "integer",
            "description": "Parallel page fetches. 10 is a good default; raise it for large matchDetails batches.",
            "default": 10
          },
          "proxy": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "All three sources answer over a direct connection, so no proxy is used unless you configure one here."
          },
          "sofaMaxTournaments": {
            "title": "SofaScore: max tournaments per day",
            "minimum": 1,
            "maximum": 200,
            "type": "integer",
            "description": "Caps the SofaScore day fan-out. Its schedule needs one call to list a day's tournaments and then one call per tournament, so an unbounded day costs around 88 requests. Ignored by the other sources.",
            "default": 20
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}