{
  "openapi": "3.0.1",
  "info": {
    "title": "Tennis Abstract Scraper: Player Stats & Match Results",
    "description": "Tennis Abstract scraper: one row per match (date, tournament, surface, round, opponent, score, rankings, serve and return stats) plus a player summary with win % by surface. ATP and WTA. New-match alerts in Slack, Discord or Telegram. No login; unknown players are free.",
    "version": "1.0",
    "x-build-id": "XoDNJ3Vo6NiaGTDfO"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/accountable_eel~tennis-abstract-stats-lookup/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-accountable_eel-tennis-abstract-stats-lookup",
        "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/accountable_eel~tennis-abstract-stats-lookup/runs": {
      "post": {
        "operationId": "runs-sync-accountable_eel-tennis-abstract-stats-lookup",
        "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/accountable_eel~tennis-abstract-stats-lookup/run-sync": {
      "post": {
        "operationId": "run-sync-accountable_eel-tennis-abstract-stats-lookup",
        "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",
        "required": [
          "players"
        ],
        "properties": {
          "players": {
            "title": "Players",
            "type": "array",
            "description": "One player per line: the first and last name (\"Novak Djokovic\", \"Iga Swiatek\"; accents and hyphens are fine) or a tennisabstract.com player link. ATP and WTA players both work.. Plan on about 25 seconds per player; players the run has no time for come back as free \"not checked\" rows. Accepted formats: Novak Djokovic, Iga Swiatek, Felix Auger-Aliassime, https://www.tennisabstract.com/cgi-bin/player.cgi?p=CarlosAlcaraz. You're only charged for the ones we actually find — a miss costs nothing.",
            "items": {
              "type": "string"
            }
          },
          "since": {
            "title": "Only matches on or after (YYYY-MM-DD)",
            "type": "string",
            "description": "Optional. Keeps matches dated on or after this day (Tennis Abstract dates a tournament by its start date). Applied after the fetch. Leave empty for every match the site holds. The player summary counts only these matches.",
            "default": ""
          },
          "surface": {
            "title": "Surface",
            "enum": [
              "any",
              "hard",
              "clay",
              "grass",
              "carpet"
            ],
            "type": "string",
            "description": "Keeps only matches on this surface. Applied after the fetch; the player summary then covers that surface only.",
            "default": "any"
          },
          "maxMatchesPerPlayer": {
            "title": "Most match rows per player",
            "type": "integer",
            "description": "Newest first. About 20 recent matches come for every player; players whose history file is current go back further (up to ~140 matches). 0 returns only the player summary row. Each match row is billed at the match-row price.",
            "default": 50
          },
          "includePlayerSummary": {
            "title": "Add a player summary row",
            "type": "boolean",
            "description": "One extra row per player: rank, country, win % overall and by surface over the matches in the sample. Billed at the player-row price.",
            "default": true
          },
          "deltaMode": {
            "title": "Track players across runs",
            "type": "boolean",
            "description": "Turns the actor into a match monitor. Each run compares every player's matches with the previous run and fills in \"New since last check\", the change type and the number of new matches. Schedule it daily and combine with \"Only return new matches\" and \"Send alerts to\".",
            "default": false
          },
          "deltaName": {
            "title": "Watchlist name (optional)",
            "type": "string",
            "description": "Leave empty and one is derived from your filters. Type your own name to keep one memory across changes, or to run several independent watchlists.",
            "default": ""
          },
          "alertOnChangeOnly": {
            "title": "Only return new matches",
            "type": "boolean",
            "description": "With monitoring on, a player with no new match writes no row and is not billed; a player with new matches returns only those matches (and the summary row). The first check of a player returns everything as the baseline.",
            "default": false
          },
          "skipFirstRun": {
            "title": "Seed silently (no rows on the first check)",
            "type": "boolean",
            "description": "The first check of a player has nothing to compare with. Turn this on to remember it without returning or billing it, so alerts start from the second check.",
            "default": false
          },
          "notifyUrl": {
            "title": "Send alerts to (Discord or Slack webhook, Telegram bot link, or any URL)",
            "type": "string",
            "description": "Optional. After a player is billed, one message lists that player's new matches (date, round, tournament, opponent, score) with a Tennis Abstract link. Discord or Slack: paste the channel's webhook URL. Telegram: https://api.telegram.org/bot<token>/sendMessage?chat_id=<chat id>. Any other URL receives JSON. Messages are free, and a failed message never fails the run (the row's notifyErrors says why). Stored encrypted, never logged or written to the results."
          },
          "notifyFormat": {
            "title": "Message format",
            "enum": [
              "auto",
              "discord",
              "slack",
              "telegram",
              "json"
            ],
            "type": "string",
            "description": "Leave on 'Detect from the link': discord.com links get Discord messages, hooks.slack.com Slack, api.telegram.org Telegram, anything else JSON. Pick one only to override that.",
            "default": "auto"
          },
          "maxNotificationsPerRun": {
            "title": "Most alert messages per run",
            "type": "integer",
            "description": "Up to 100. After this, one \"more alerts\" message says the rest are in the run's dataset. 0 sends only that one message.",
            "default": 20
          },
          "testRun": {
            "title": "Try it first — only process the first 5",
            "type": "boolean",
            "description": "Turn this on to test your input on a small sample before running the full list. Turn it off to process everything.",
            "default": false
          },
          "onlyFound": {
            "title": "Hide rows with no result",
            "type": "boolean",
            "description": "Only keep rows where something was actually found. Misses are always free, whether or not you show them here.",
            "default": false
          },
          "includeKeywords": {
            "title": "Only keep rows containing",
            "type": "array",
            "description": "Optional. Only keep results that mention at least one of these words (e.g. a job title, a city, a product name). Leave empty to keep everything.",
            "items": {
              "type": "string"
            }
          },
          "excludeKeywords": {
            "title": "Skip rows containing",
            "type": "array",
            "description": "Optional. Drop any result that mentions one of these words. Leave empty to skip nothing.",
            "items": {
              "type": "string"
            }
          },
          "maxResults": {
            "title": "Stop after this many results",
            "minimum": 1,
            "type": "integer",
            "description": "Optional. Stop the run once this many results have been found — useful for a quick, cheap sample. Leave blank for no limit."
          },
          "columns": {
            "title": "Which columns do you want?",
            "type": "array",
            "description": "Choose which pieces of information to include in each result row. All are included by default.",
            "items": {
              "type": "string",
              "enum": [
                "rowType",
                "player",
                "tour",
                "country",
                "birthYear",
                "hand",
                "currentRank",
                "peakRank",
                "eloRating",
                "eloRank",
                "matchesPlayed",
                "wins",
                "losses",
                "winPct",
                "sampleFrom",
                "sampleTo",
                "hardMatches",
                "hardWinPct",
                "clayMatches",
                "clayWinPct",
                "grassMatches",
                "grassWinPct",
                "carpetMatches",
                "carpetWinPct",
                "historyDepth",
                "date",
                "tournament",
                "surface",
                "level",
                "round",
                "result",
                "opponent",
                "opponentCountry",
                "score",
                "bestOf",
                "playerRank",
                "opponentRank",
                "minutes",
                "aces",
                "doubleFaults",
                "servePoints",
                "aceRatePct",
                "doubleFaultRatePct",
                "firstServeInPct",
                "firstServeWonPct",
                "secondServeWonPct",
                "breakPointsSaved",
                "breakPointsFaced",
                "returnPointsWonPct",
                "dominanceRatio",
                "source",
                "isNewMatch",
                "playerUrl",
                "checkedAt",
                "changeType",
                "newMatchCount",
                "daysSincePrevious",
                "notifyErrors"
              ],
              "enumTitles": [
                "Row type",
                "Player",
                "Tour",
                "Country",
                "Birth year",
                "Plays",
                "Current rank",
                "Peak rank",
                "Elo rating",
                "Elo rank",
                "Matches in sample",
                "Wins",
                "Losses",
                "Win %",
                "Sample from",
                "Sample to",
                "Hard-court matches",
                "Hard-court win %",
                "Clay matches",
                "Clay win %",
                "Grass matches",
                "Grass win %",
                "Carpet matches",
                "Carpet win %",
                "History depth",
                "Date",
                "Tournament",
                "Surface",
                "Level",
                "Round",
                "Result",
                "Opponent",
                "Opponent country",
                "Score",
                "Best of",
                "Player rank",
                "Opponent rank",
                "Minutes",
                "Aces",
                "Double faults",
                "Serve points",
                "Ace %",
                "Double fault %",
                "First serve in %",
                "First serve points won %",
                "Second serve points won %",
                "Break points saved",
                "Break points faced",
                "Return points won %",
                "Dominance ratio",
                "Source",
                "New since last check",
                "Tennis Abstract link",
                "Checked at",
                "Change since last check",
                "New matches",
                "Days since last check",
                "Alert errors"
              ]
            },
            "default": [
              "rowType",
              "player",
              "tour",
              "country",
              "birthYear",
              "hand",
              "currentRank",
              "peakRank",
              "eloRating",
              "eloRank",
              "matchesPlayed",
              "wins",
              "losses",
              "winPct",
              "sampleFrom",
              "sampleTo",
              "hardMatches",
              "hardWinPct",
              "clayMatches",
              "clayWinPct",
              "grassMatches",
              "grassWinPct",
              "carpetMatches",
              "carpetWinPct",
              "historyDepth",
              "date",
              "tournament",
              "surface",
              "level",
              "round",
              "result",
              "opponent",
              "opponentCountry",
              "score",
              "bestOf",
              "playerRank",
              "opponentRank",
              "minutes",
              "aces",
              "doubleFaults",
              "servePoints",
              "aceRatePct",
              "doubleFaultRatePct",
              "firstServeInPct",
              "firstServeWonPct",
              "secondServeWonPct",
              "breakPointsSaved",
              "breakPointsFaced",
              "returnPointsWonPct",
              "dominanceRatio",
              "source",
              "isNewMatch",
              "playerUrl",
              "checkedAt",
              "changeType",
              "newMatchCount",
              "daysSincePrevious",
              "notifyErrors"
            ]
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "minimum": 1,
            "maximum": 1,
            "type": "integer",
            "description": "Parallel requests. Keep conservative — this target has no browser fallback, so getting blocked costs more than slow-and-steady.",
            "default": 1
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Apify Proxy config. Residential recommended for anti-bot-sensitive targets.",
            "default": {
              "useApifyProxy": true
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}