Liquipedia Scraper - Esports Tournaments & Teams avatar

Liquipedia Scraper - Esports Tournaments & Teams

Pricing

from $2.00 / 1,000 esports records

Go to Apify Store
Liquipedia Scraper - Esports Tournaments & Teams

Liquipedia Scraper - Esports Tournaments & Teams

Extract structured esports tournaments, teams, players, transfers, brackets and match schedules from Liquipedia across 80+ game wikis. Prize pools, rosters, final standings and results as typed JSON, not raw HTML. Reads only the official MediaWiki API. $0.002 per record plus $0.001 per run.

Pricing

from $2.00 / 1,000 esports records

Rating

0.0

(0)

Developer

Andy Besos

Andy Besos

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

This Liquipedia Scraper turns Liquipedia esports wiki pages into clean, typed JSON. Point it at tournaments, teams, or players on any of 80+ game wikis — Dota 2, Counter-Strike, League of Legends, Valorant, Rocket League, Overwatch, Apex Legends, Rainbow Six, StarCraft II, Mobile Legends and the rest — and get back prize pools as numbers, dates as ISO dates, rosters as arrays, final standings showing which team finished in which place, roster transfers, playoff brackets, and the upcoming match schedule with exact UTC kickoff times. Not raw HTML you still have to parse.

You do not need a Liquipedia account, an API key, a browser, or a proxy. The Actor reads only Liquipedia's official MediaWiki API, stays inside the published rate limits, and attaches the CC-BY-SA 3.0 attribution you need to republish the data.

Why use this Liquipedia scraper?

  • Structured fields, not an HTML dump. prizePoolUsd is a number, startDate and endDate are YYYY-MM-DD strings, series, organizers, sponsors and venues are arrays. Other Liquipedia scrapers hand you the rendered page body and leave the infobox parsing to you.
  • Tournaments, players, and teams in one Actor, on one schema. A tournament record carries its full participants array — every team with its players, coaches, and the qualifier path it came through — plus prizeDistribution per placement. A player record carries teamHistory as a dated timeline, plus externalIds for Steam, FACEIT, ESEA, ESL and GamersClub. A team record carries staff, region, founding dates, and socials.
  • Final standings and match results. Turn on standings and each tournament gains a standings array — place, participant, prize money, circuit points — including shared placements such as 5-6. Turn on matches and you also get every match on the page with opponents, date, best-of, and a derived score.
  • Roster transfers, as a feed or as history. Every move comes back as its own row: the date, the players involved with their countries, the team left, the team joined, the roles on each side, and the sources Liquipedia cites. Take the live feed for a daily transfer watch, or point pages at the quarterly archives — Transfers/2025/1st Quarter and its siblings back to 2006 — and pull hundreds of historical moves per page at full speed.
  • The match schedule, with real kickoff times. The ticker is the only place Liquipedia publishes an exact instant, and this Actor returns it as UTC. Scheduled, live and just-finished matches, each with both opponents, the tournament, the best-of, and the score once it exists.
  • Brackets and head-to-head. Playoff brackets come back with their layout, every slot, and the round names the editors wrote — even on the wikis whose results live in the database, where the shape of the bracket is all the page holds. Head-to-head records are derived from the matches you scraped, one object per side with the series and maps it won, plus which tournaments they met in.
  • Career results and prize money. Turn on career results and a player or team profile gains its total winnings, recent placements with prize money and opponents, and individual awards.
  • Change monitoring built in. Every record is tagged new, updated, unchanged, or removed, and updated records list exactly which fields moved in changedFields. Schedule it and you have a roster-move and prize-pool watcher instead of a one-off export.
  • Whole categories in one run. Give it Tournaments, Players, or 2024 Tournaments and it enumerates the category and scrapes every article in it, following continuation automatically.
  • It accepts the input you already have. Full URLs, wiki:Page Title, wiki/Page Title, bare titles, underscores, URL encoding, and index.php?title= links all normalize to the same page. Liquipedia redirects are resolved, so The International 2024 finds The International/2024 on its own.
  • Honest nulls. A match that has not started reports no score rather than the ticker's placeholder 0 : 0, and some Liquipedia values — Valve's live-updated prize pools, for example — are computed by the wiki at render time and simply are not present in the page source. This Actor returns null and names the field in unresolvedFields instead of inventing a number.

Reliability comes from the access path. Liquipedia's API Terms of Use state that automated access to rendered HTML pages is not permitted, and those pages sit behind a bot challenge. This Actor never touches them. It uses the MediaWiki API with an identifying User-Agent, gzip, a reused connection, and one request every 2.1 seconds — the documented limit. Requests are batched 50 pages at a time, temporary errors retry with backoff that honours Retry-After, and one failing wiki never aborts the others: the run fails only if every wiki fails.

Pricing

This Actor uses the pay-per-event model. You pay $0.001 per run plus $0.002 per record — that is $2.00 per 1,000 records. There are no separate platform usage, proxy, or compute charges.

Records in a runTotal cost
1$0.003
100$0.201
1,000$2.001
10,000$20.001

For comparison: in our 21 August 2026 review of every Liquipedia scraper returned by Apify Store search, the highest-traffic one charged $0.016 per result ($16.00 per 1,000) and returned unparsed HTML. Prices change — check the current figures before relying on this comparison.

How to use this Actor

Set wiki to the game wiki you want, then either list pages or give a category or a search term.

The wiki is the first path segment of any Liquipedia URL: https://liquipedia.net/dota2/... is dota2, https://liquipedia.net/counterstrike/... is counterstrike.

Every one of these is an accepted pages entry:

  • ESL One/Birmingham/2024 — a page title on the selected wiki
  • https://liquipedia.net/dota2/ESL_One/Birmingham/2024 — a full page URL, which carries its own wiki
  • counterstrike:Natus Vincere — a wiki prefix and a title
  • valorant/TenZ — the same, with a slash
  • The International 2024 — a redirect, resolved automatically to The International/2024

Scrape a few specific pages across two wikis:

{
"wiki": "dota2",
"pages": [
"ESL One/Birmingham/2024",
"https://liquipedia.net/counterstrike/Natus_Vincere",
"valorant/TenZ"
],
"maxPagesPerWiki": 0
}

Scrape every tournament on the Counter-Strike wiki, capped at 500 pages:

{
"wiki": "counterstrike",
"category": "Tournaments",
"entityTypes": ["tournament"],
"maxPagesPerWiki": 500
}

Find and scrape pages by search term:

{
"wiki": "valorant",
"search": "Champions 2024",
"maxPagesPerWiki": 25
}

Because Liquipedia allows one API request every two seconds and this Actor fetches 50 pages per request, roughly 1,400 pages per minute is the practical ceiling. A 500-page category run takes well under a minute.

What is in the page, and what is not

Liquipedia keeps two kinds of data. Most of it is written in the page source and comes back at full speed — 50 pages per API request. The rest Liquipedia assembles from its own database when a page renders, and reading that costs a heavier API call its terms limit to one request per 30 seconds. Every one of those is opt-in, so you decide what a run spends its time on.

OptionWhat you getCost
includeMatchesMatches on the page: opponents, date, best-of, derived scoreFree
includeBracketsPlayoff bracket layout, every slot, round namesFree
includeHeadToHeadDerived head-to-head records between everyone who metFree
Transfer archives in pagesHundreds of historical transfers per pageFree
includeStandingsFinal placement table with prize money and points30 s per tournament
includeTransferFeedThe wiki's latest roster moves30 s per wiki
includeMatchTickerUpcoming, live and finished matches with UTC kickoff30 s per wiki
includeResultsCareer winnings, placements and awards on a profile30 s per profile

The Actor reads the platform's own run deadline and stops asking for rendered pages while it still has time to write what it already collected, so a run cannot time out mid-lookup and lose everything. Raise the run timeout when you want more of them: allow about 30 seconds each.

Final standings

"standings": [
{ "place": "1", "participant": "Team Falcons", "usdPrize": 300000, "points": 6400 },
{ "place": "2", "participant": "BetBoom Team", "usdPrize": 175000, "points": 4800 },
{ "place": "5-6", "participant": "Team Liquid", "usdPrize": 57500, "points": 2240 },
{ "place": "5-6", "participant": "G2 x iG", "usdPrize": 57500, "points": 2240 }
]

Shared placements such as 5-6 are repeated for every team that spans them, so each row stands on its own.

Transfers

One record per move, from either source, on one schema:

{
"entityType": "transfer",
"date": "2025-03-28",
"dateIsExact": true,
"players": [{ "name": "TA2000", "country": "kz" }, { "name": "lorenof", "country": "ua" }],
"fromTeam": "Chimera Esports",
"toTeam": "Virtus.pro",
"toRole": null,
"references": ["https://t.me/chimera_esports/616"],
"transferSource": "wikitext"
}

A row that moves a whole roster stays one row, with every player in players. A missing side means what it says: fromTeam: null is a player joining from no team, toTeam: null is one becoming a free agent — never an invented team name. When Liquipedia only knows the month, dateIsExact is false and dateRaw keeps the original 2025-03-??.

For a daily transfer watch, set includeTransferFeed and a stable monitorId. For bulk history, put the archives in pages instead — they are free and far larger:

{
"wiki": "counterstrike",
"pages": ["Transfers/2025/1st Quarter", "Transfers/2024/4th Quarter"],
"maxPagesPerWiki": 0
}

Match schedule

{
"entityType": "match",
"scheduledAt": "2026-08-22T02:00:00.000Z",
"finished": false,
"opponents": [
{ "name": "TSpirit", "page": "Team Spirit", "score": null, "winner": false },
{ "name": "Liquid", "page": "Team Liquid", "score": null, "winner": false }
],
"score": null,
"bestOf": 3,
"tournament": "TI 2026 - Main Event",
"tournamentPage": "The International/2026/Main Event"
}

An unplayed match reports score: null. The ticker prints 0 : 0 before kickoff, and passing that on as a result would put a fabricated draw in your dataset.

Brackets

"brackets": [{
"bracketId": "zgZcb3UKXx",
"layout": "Bracket/4U4L2DSL1D",
"source": "wikitext",
"nodeCount": 10,
"nodes": [
{ "key": "R2M1", "round": 2, "matchNumber": 1, "roundLabel": "Upper Bracket Semifinals",
"match": { "opponents": ["team falcons", "tundra esports"], "score": [1, 2], "winner": "tundra esports" } }
]
}]

Round names come from the headings the editors wrote above each group. Empty slots are kept rather than dropped, so on wikis that store their results in the database you still get the shape of the bracket. A bracket embedded only as {{ShowBracket}} is listed with source: "liquipediadb" and no slots — that way "this event had no bracket" stays distinguishable from "the bracket is not in the page source".

Match results in the page source

includeMatches costs no extra requests, but how much is there depends on the wiki:

WikiWhat you getscoreSource
Dota 2, OverwatchOpponents, date, best-of, and a score derived from per-map winnersmap-winners
Counter-StrikeOpponents, date, and a score derived from per-side round countsround-totals
Valorant, League of LegendsNothing — these wikis transclude matches from the database, so their pages carry only empty placeholders

Every match names how its score was worked out in scoreSource, and decidedMatchCount tells you how many of a tournament's matches actually resolved to a winner. A match that cannot be decided returns score: null and winner: null rather than a guess. Drawn matches, which are normal in best-of-two group stages, also return no winner. Where the page carries no matches, includeMatchTicker still gives you the schedule and the finished results.

Head-to-head

includeHeadToHead adds one record per pair of opponents that met in the matches this run parsed:

{
"entityType": "headtohead",
"name": "BetBoom Team vs Team Falcons",
"opponents": [
{ "name": "BetBoom Team", "seriesWon": 0, "mapsWon": 1 },
{ "name": "Team Falcons", "seriesWon": 1, "mapsWon": 4 }
],
"seriesPlayed": 2,
"drawnSeries": 1,
"firstMatchDate": "2024-04-22",
"lastMatchDate": "2024-04-28",
"tournaments": ["ESL One Birmingham 2024"],
"sourcePages": ["ESL One/Birmingham/2024"],
"derivedFrom": "matches on the pages scraped in this run"
}

A derived record has no page of its own, so pageUrl is null and sourceUrls lists every page that contributed to it — that is what you attribute under CC-BY-SA 3.0.

Liquipedia's own head-to-head pages are database queries the API does not expose, so these are computed from what you scraped — scrape a whole season and you get that season's head-to-head table. Every record says so in derivedFrom and lists the tournaments it covers.

Monitor new, updated, and removed records

Run the Actor on a schedule with a stable monitorId and it compares each run against the previous one for that ID.

changeTypeMeaning
newThe page appeared in this selection for the first time.
updatedA field changed since the last run. changedFields names them.
unchangedThe page is still there and identical.
removedA page that was present before is no longer in the selection. Emitted once.

This is what makes roster moves, staff changes, and prize-pool updates visible: when a player signs elsewhere, their record comes back updated with changedFields: ["currentTeam", "teamHistory"].

Watch a set of teams for roster changes every morning:

{
"wiki": "counterstrike",
"pages": ["Natus Vincere", "G2 Esports", "Team Vitality", "FaZe Clan"],
"maxPagesPerWiki": 0,
"monitorId": "cs-orgs",
"onlyChangesSince": "2026-08-01T00:00:00.000Z"
}

With onlyChangesSince set, the dataset holds only what actually moved, so a quiet day costs one record's worth of nothing. Keep wiki, pages, entityTypes, and maxPagesPerWiki stable across runs that share a monitor ID — they define the set being compared, so changing them makes pages look added or removed.

API example

Run the Actor and get the records back in one call:

curl -X POST "https://api.apify.com/v2/acts/clintsa~liquipedia-scraper/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"wiki": "dota2",
"pages": ["ESL One/Birmingham/2024"],
"maxPagesPerWiki": 1
}'

Input options

FieldTypeDescription
wikistringRequired. Liquipedia game wiki, such as dota2 or counterstrike. Used for bare titles and for category and search discovery.
pagesarrayPage URLs or titles to scrape. Leave empty when using category or search.
categorystringEnumerate a Liquipedia category on the selected wiki, such as Tournaments, Teams, or Players.
searchstringFull-text search on the selected wiki; matching pages are scraped in relevance order.
entityTypesarrayKeep only tournament, player, team, transfer, match, headtohead, or other records. Empty keeps everything.
includeMatchesbooleanAdd a matches array to tournaments. Costs no extra requests; coverage varies by wiki.
includeBracketsbooleanAdd a brackets array with layout, slots and round names. Costs no extra requests.
includeStandingsbooleanAdd a standings array with final placements. One extra API call per tournament, limited to one per 30 seconds.
maxStandingsLookupsintegerCap on standings lookups per run. Default 8, which fits the 300-second default timeout.
includeHeadToHeadbooleanAdd derived head-to-head records for every pair that met in this run's matches. Costs no extra requests.
includeTransferFeedbooleanAdd the wiki's latest roster moves as one record each. One 30-second call per wiki.
transferFeedPagestringPage the transfer feed is read from. Default Portal:Transfers.
includeMatchTickerbooleanAdd upcoming, live and finished matches with UTC kickoff times. One 30-second call per wiki.
matchTickerPagestringPage the match ticker is read from. Default Liquipedia:Matches.
includeResultsbooleanAdd career winnings, placements and awards to player and team records. One 30-second call per profile.
maxResultLookupsintegerCap on career-result lookups per run. Default 4.
maxPagesPerWikiintegerCap on pages fetched per wiki. 0 means no cap.
includeWikitextbooleanAdd the page's raw wikitext to each record as wikitext.
contactEmailstringOptional contact address added to the API User-Agent, as Liquipedia's terms ask for.
monitorIdstringNamespace for change tracking. Same value means same monitor.
onlyChangesSincestringISO timestamp; return only records that changed since then.
requestDelayMillisintegerExtra pacing. The 2,100 ms floor required by Liquipedia always applies.
useApifyProxybooleanOptional network fallback. Normally unnecessary.
proxyConfigurationobjectProxy settings, used only when useApifyProxy is enabled.
startUrlsarrayCompatibility alias merged into pages.

Output

One record per page. A tournament looks like this (abridged):

{
"entityType": "tournament",
"itemId": "dota2:ESL One/Birmingham/2024",
"wiki": "dota2",
"pageTitle": "ESL One/Birmingham/2024",
"name": "ESL One Birmingham 2024",
"tickerName": "ESL One Birmingham",
"series": ["ESL One", "ESL Pro Tour"],
"organizers": ["ESL Gaming"],
"sponsors": ["Intel Arc", "Predator", "DHL", "Qiddiya", "Monster Energy"],
"eventType": "Offline",
"tier": "1",
"startDate": "2024-04-22",
"endDate": "2024-04-28",
"prizePoolUsd": 1000000,
"teamCount": 12,
"country": "United Kingdom",
"city": "Birmingham",
"venues": ["Resorts World Arena"],
"patch": "7.35d",
"prizeDistribution": [
{ "place": "1", "usdPrize": 300000, "points": 6400, "percentage": null, "computed": false },
{ "place": "5-6", "usdPrize": 57500, "points": 2240, "percentage": null, "computed": false }
],
"participants": [
{
"team": "Gaimin Gladiators",
"players": ["dyrachyo", "Quinn", "Ace", "tOfu", "Seleri"],
"coaches": ["Cy-"],
"qualifier": "EPT Leaderboard"
}
],
"participantCount": 12,
"previousEditions": ["ESL One/Kuala Lumpur/2023", "DreamLeague/Season 22"],
"unresolvedFields": [],
"website": "https://www.esl-one.com/birmingham/",
"socials": { "twitter": "ESLDota2", "twitch": "esl_dota2" },
"pageUrl": "https://liquipedia.net/dota2/ESL_One/Birmingham/2024",
"license": "CC-BY-SA 3.0",
"changeType": "new",
"scrapedAt": "2026-08-21T12:00:00.000Z"
}

Player records add handle, realName, nativeName, birthDate, country, status, roles, currentTeam, a dated teamHistory, and externalIds — plus totalWinningsUsd, results and awards when career results are enabled. Team records add location, region, founders, ceo, managers, coaches, analysts, and inGameLeader. Transfers, ticker matches and head-to-head pairings arrive as their own records, shown above. Five dataset views are provided: Esports records, Tournaments, Transfers, Match schedule, and Changes.

Every run also writes a SUMMARY record to the key-value store with the number of wikis requested and succeeded, pages fetched, records exported, a breakdown by record type, and the change counts, plus how many rendered lookups the run spent.

Use cases

  • Build an esports results and prize-money database across several games without writing a wikitext parser.
  • Watch a set of organizations for roster moves and staff changes, and alert on changedFields.
  • Track prize pools and tier assignments across a circuit to size sponsorship or betting markets.
  • Populate a fantasy-esports or tipping product with tournament dates, participants, and rosters.
  • Feed a research dataset on player careers using dated teamHistory timelines across 80+ titles.
  • Enrich a CRM of teams and organizations with regions, staff, socials, and founding dates.
  • Run a daily transfer watch across several games and alert on every new roster move.
  • Drive a schedule or notification product from the match ticker's exact UTC kickoff times.
  • Build head-to-head tables for a whole season by scraping its tournaments in one run.

FAQ

Do I need a Liquipedia account or API key? No. This Actor uses Liquipedia's public MediaWiki API, which needs no authentication. You do not need the separate LiquipediaDB API key either.

Which games are supported? All of them. Any wiki hosted on liquipedia.net works by name, including Dota 2, Counter-Strike, League of Legends, Valorant, Rocket League, Overwatch, Apex Legends, Rainbow Six, StarCraft II, Mobile Legends, Call of Duty, Fortnite, PUBG, Halo, Smash, Chess and more than seventy others. A newly launched wiki works the day it appears.

Is scraping Liquipedia allowed? Liquipedia publishes API Terms of Use that permit automated access through the MediaWiki API and forbid it against rendered HTML pages. This Actor only uses the API, sends an identifying User-Agent, and respects the one-request-per-two-seconds limit. Content is licensed CC-BY-SA 3.0, and every record carries pageUrl, license, and licenseUrl so you can attribute it correctly.

Why is prizePoolUsd null for some tournaments? Two reasons, and in both the Actor tells you rather than guessing.

Some events publish their prize pool in a local currency only — LCK lists ₩375,000,000 and LEC €80,000, with no dollar figure. Those come back as prizePoolLocal: 375000000 with localCurrency: "krw", and prizePoolUsd stays null. Reading the local number as dollars would report a $375-million prize pool for a tournament that pays out a fraction of that, so the Actor never does it. Convert with your own exchange rate if you need one comparable column.

A few events, notably Valve's, compute the prize pool from a separate page or a live counter, so the number is not in the page source at all. The field name then appears in unresolvedFields, and affected prizeDistribution entries are flagged computed: true with their percentage filled in where published.

How fast can it scrape? About 1,400 pages per minute. Liquipedia allows one request every two seconds, and the Actor asks for 50 pages per request.

Can it get final standings and match results? Yes, both are optional fields. Enable includeStandings for the placement table — which team finished where, with prize money and points. Because Liquipedia renders that table from its own database, it needs a heavier API call that its terms limit to one request per 30 seconds, so use it on a shortlist rather than a whole category. Enable includeMatches for the matches on the page; that costs nothing extra, but Valorant and League of Legends pages carry no match data at all, and each match reports how its score was derived in scoreSource. For those wikis, includeMatchTicker gives you the schedule and results anyway.

Can it track roster transfers? Yes, two ways. includeTransferFeed returns the wiki's latest moves as one record each — combine it with a stable monitorId and a schedule for a daily transfer watch. For history, put the quarterly archives such as Transfers/2025/1st Quarter into pages: those are read from the page source, so they are free, fast, and go back to 2006.

Do I need the LiquipediaDB API key for any of this? No. Everything described here comes from the public MediaWiki API. LiquipediaDB is a separate, key-gated API with an hourly request quota; this Actor does not use it, so nothing you run here depends on a key of yours.

How do I get only what changed? Set a stable monitorId and schedule the run. Add onlyChangesSince with an ISO timestamp to drop unchanged records from the dataset entirely.

Limitations and responsible use

The optional fields that read rendered pages — standings, transfer feed, match ticker, career results — each cost about 30 seconds, so a single run collects a shortlist of them rather than a whole category. Match data from the page source is missing entirely on Valorant and League of Legends, where the ticker is the way to get results. Head-to-head records are derived from the matches in your own run, not from Liquipedia's complete history. A career-results lookup returns the placements the profile page itself lists; request the /Results subpage for the full history. Per-map detail beyond the score is not returned. Anything Liquipedia computes at render time and this Actor cannot resolve is reported as null with the field named in unresolvedFields, never approximated. Data on subpages, such as separate qualifier or group-stage pages, is only returned if you request those pages.

Liquipedia is a community-edited wiki. A record reflects what editors have published as of lastEditedAt, not verified fact, and coverage varies a lot between large and small game wikis. An updated record means the page text changed; it does not by itself prove a transfer happened.

Content is licensed under CC-BY-SA 3.0. If you republish it, attribute Liquipedia using the pageUrl on each record and keep derivative works under the same licence. Please keep your usage within Liquipedia's API Terms of Use, cache what you have already fetched rather than re-scraping it, and consider setting contactEmail for heavy or scheduled runs.

Support

Found a page that parses wrong, or a field you need that is missing? Open an issue on the Issues tab of this Actor. Include the run ID, the exact input you used, and the Liquipedia page URL — that is usually enough to reproduce and fix it quickly.