itch.io Game, Review, Creator and Jam Scraper
Pricing
from $1.00 / 1,000 results
itch.io Game, Review, Creator and Jam Scraper
Scrape itch.io games by genre, tag, platform, price band or keyword, plus creator catalogues and game jam results. Returns price and pay-what-you-want floor, rating, tags, platforms, files and the full review thread with creator replies. Incremental mode tracks changes.
Pricing
from $1.00 / 1,000 results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Pull structured records out of itch.io (itch.io), the indie game marketplace. Browse the site's own game index with its own filters, search by keyword, follow a creator's whole catalogue, or read a game jam and its ranked results. Every game comes back with its price and its pay-what-you-want floor, its rating and rating count, its tags, platforms, file list and the jam it was submitted to. Turn on the detail lookup and each game also brings its full review thread: every public comment, who wrote it, when, and whether the reply came from the game's own creator.
Why This Scraper
- The review thread, with creator replies. Other itch.io datasets stop at the star average. This one returns the individual comments, nested replies included, and flags every reply written by the game's own creator. That is the difference between "4.9 stars" and knowing what players actually said and how the studio answered.
- The pay-what-you-want floor, not just the sticker price. A huge share of the catalogue is "name your own price". Both numbers come back separately, read from the page's own payload rather than from button text, so a free game, a donation game and a $15.99 game are never confused.
- Five modes, one output contract. Browse, keyword search, creator, jam and pasted links all produce the same flat record shape, so a mixed pull needs no branching downstream.
- Jam results in full. A ranked jam returns every entry's overall rank, its number of ratings, its adjusted score, and its rank and score under each individual criterion the jam scored on.
- Creator profiles with public follower counts. A creator record carries their catalogue, their outbound links, and the follower, post and topic counters, read exactly rather than from the abbreviated text the page shows.
- Recurring monitoring built in. Incremental mode returns only what changed since the last run of the same search, and resume continues one interrupted pull without paying for rows you already have.
Data You Get
Sample shape, values are illustrative placeholders, not from a live listing.
| Field | Example |
|---|---|
recordType | "game" |
recordId | "game-00000001" |
gameId | 00000001 |
title | "Sample Game Title" |
url | "https://sample-studio.itch.io/sample-game" |
developerName | "Sample Studio" |
developerUrl | "https://sample-studio.itch.io" |
shortText | "A one line tagline for the game." |
coverImageUrl | "https://img.itch.zone/000000000/315x250/cover.png" |
genre | "Puzzle" |
tags | ["atmospheric", "pixel art", "singleplayer"] |
platforms | ["Windows", "macOS", "Linux"] |
priceUsd | 4.99 |
minimumPriceUsd | 0 |
pricingModel | "name-your-own-price" |
isOnSale | true |
salePercent | 40 |
rating | 4.6 |
ratingCount | 1234 |
status | "Released" |
publishedAt | "2026-01-01T00:00:00Z" |
updatedAt | "2026-01-01T00:00:00Z" |
madeWith | ["Godot"] |
languages | ["English"] |
inputs | ["Keyboard", "Mouse"] |
accessibility | ["Subtitles"] |
averageSession | "About an hour" |
files | [{"name": "sample-game-win.zip", "sizeText": "120 MB", "platforms": ["Windows"]}] |
isBrowserPlayable | false |
jamName | "Sample Game Jam 2026" |
jamUrl | "https://itch.io/jam/sample-game-jam" |
reviewCount | 210 |
reviewsReturned | 20 |
reviews | [{"authorName": "player-one", "body": "Loved the ending.", "isDeveloperReply": false}] |
followers | 12345 |
gameCount | 18 |
topEntries | [{"jamRank": 1, "jamScore": 4.689, "jamCriteria": [{"criterion": "Style", "rank": 2}]}] |
changeType | "NEW" |
scrapedAt | "2026-01-01T00:00:00Z" |
How to Use
Browse the index, no extra requests per game:
{"mode": "browse","genres": ["Puzzle"],"sortBy": "top-rated","maxItems": 100}
Browse with the full detail lookup and the review thread:
{"mode": "browse","tags": ["horror"],"price": "free","fetchDetails": true,"maxReviewsPerGame": 50,"maxItems": 25}
A creator's whole catalogue plus their follower count:
{"mode": "developer","creators": ["sample-studio", "another-studio"],"fetchDetails": true}
A ranked jam with its full result table:
{"mode": "jam","jams": ["sample-game-jam-2026"],"fetchDetails": true,"maxJamEntries": 100}
Paste links of any kind:
{"mode": "url","urls": ["https://sample-studio.itch.io/sample-game","https://itch.io/games/top-rated/genre-puzzle","https://itch.io/jam/sample-game-jam"],"fetchDetails": true}
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | select | browse | browse, search, developer, jam or url. |
queries | array | ["horror"] | Search mode keywords. One page of results per keyword. |
creators | array | ["gbpatch"] | Creator mode: handles, creator page links, or a link to one of their games. |
jams | array | ["gmtk-2024"] | Jam mode: jam handles or jam links. Leave empty to read a whole listing. |
jamScope | select | in-progress | Which jam listing to read when no jams are named. |
urls | array | see above | URL mode: game, creator, jam, browse or search links, mixed freely. |
genres | array | (none) | Browse mode only. Genres written the way the site writes them. One filter slot each. |
tags | array | (none) | Browse mode only. Tags written the way they appear under a game. One filter slot each. |
jamEntries | select | any | Browse mode only. Only jam entries, or only games outside a jam. One slot. |
sortBy | select | popular | Browse mode only. The site's own orderings. Every value except the default uses one slot. |
platform | select | any | Browse, search and url. Windows, macOS, Linux, Android, iOS, or playable in the browser. One browse slot. |
price | select | any | Free is browse and search. Currently discounted, $5 or less and $15 or less are browse mode only. One browse slot. |
hasDemo | boolean | false | Browse, search and url. Only games that publish a playable demo. One browse slot. |
minRating | integer | 0 | Browse, search and url. Minimum rating, 0 to 5. Needs fetchDetails. |
minRatingCount | integer | 0 | Browse, search and url. Minimum number of ratings. Needs fetchDetails. |
fetchDetails | boolean | false | Read each record's own page. Adds one request per record and one Detail enrichment event. |
maxReviewsPerGame | integer | 20 | Cap on comments returned per game. 0 returns the game without its thread. |
includeJamEntries | boolean | true | Also return each jam's ranked entry table. |
maxJamEntries | integer | 20 | Cap on ranked entries per jam. 0 for every entry published. |
maxItems | integer | 20 | The run's cap. 0 for unlimited. |
maxPages | integer | 0 | Result pages per scope. 0 means no limit. |
resumeFromRunId | string | (none) | Continue one interrupted run from its run or dataset id. |
incrementalMode | boolean | false | Return only what changed since the last run of the same search. |
stateKey | string | (none) | Name a monitoring campaign, or deliberately share state. |
emitUnchanged | boolean | false | Also return unchanged rows. These are billed. |
emitExpired | boolean | false | Also return rows that disappeared. These are billed. |
proxy | object | Apify Proxy | Connection configuration. |
mcpConnectors | array | (none) | Optional MCP connectors to pipe results into. |
notionParentPageUrl | string | (none) | Notion parent page id, for the Notion connector. |
maxNotifyListings | integer | 50 | Cap on items written to each connector. |
Three things the site itself limits
- At most two filter slots per browse address. Genres, tags, platform, price, jam entries and demo each use one slot, and any ordering other than the site default uses one as well. Asking for a third stops the run immediately with a message naming what to drop, rather than spending requests on an address the site will not serve.
- Keyword search is one page, and it is a smaller filter surface. The site serves a single page of results per keyword and publishes no second page. Use browse mode when you need a large set. Search also publishes a much shorter filter vocabulary than the browse index: a platform option, a free or paid split and a demo flag, and nothing else. There is no genre, tag, jam-entry or ordering option, and no discount or price band. A filter the chosen mode cannot apply stops the run with a message naming it, so a run never comes back looking filtered when it is not.
- A creator page and a jam page are single documents. They publish no filter surface at all, so the listing filters are not available in creator or jam mode.
Which filter works where:
| browse | search | url | creator | jam | |
|---|---|---|---|---|---|
genres, tags, jamEntries, sortBy | yes | no | no | no | no |
platform, hasDemo, price: free | yes | yes | yes | no | no |
price: on-sale / under-5 / under-15 | yes | no | no | no | no |
minRating, minRatingCount | yes | yes | yes | no | no |
In url mode the filters above apply to a pasted search address. A pasted browse address is walked with the filter segments already in it, and the run says so by name when both are set at once.
A browse scope also stops at the site's own depth limit of 200 pages, which is 7,200 games. When that happens the run says so and, in incremental mode, will not mark anything expired from a scan it knows was incomplete.
Output Example
Sample shape, values are illustrative placeholders, not from a live listing.
{"recordType": "game","recordId": "game-00000001","gameId": 1,"title": "Sample Game Title","url": "https://sample-studio.itch.io/sample-game","slug": "sample-game","developerName": "Sample Studio","developerUrl": "https://sample-studio.itch.io","developerSlug": "sample-studio","shortText": "A one line tagline for the game.","coverImageUrl": "https://img.itch.zone/000000000/315x250/cover.png","description": "The full page description appears here when fetchDetails is on.","genre": "Puzzle","tags": ["atmospheric", "pixel art"],"platforms": ["Windows", "macOS"],"madeWith": ["Godot"],"languages": ["English"],"inputs": ["Keyboard", "Mouse"],"accessibility": ["Subtitles"],"averageSession": "About an hour","status": "Released","publishedAt": "2026-01-01T00:00:00Z","updatedAt": "2026-01-01T00:00:00Z","priceUsd": 4.99,"minimumPriceUsd": 0,"pricingModel": "name-your-own-price","isOnSale": false,"salePercent": null,"rating": 4.6,"ratingCount": 1234,"isBrowserPlayable": false,"hasDevlog": true,"files": [{ "name": "sample-game-win.zip", "sizeText": "120 MB", "platforms": ["Windows"] }],"jamName": "Sample Game Jam 2026","jamSlug": "sample-game-jam","jamUrl": "https://itch.io/jam/sample-game-jam","jamEntryId": 1,"reviewCount": 210,"reviewsReturned": 2,"reviews": [{"reviewId": 1,"url": "https://itch.io/post/1","authorName": "player-one","authorUrl": "https://itch.io/profile/player-one","authorSlug": "player-one","authorId": 1,"postedAt": "2026-01-01T00:00:00Z","postedAgo": "3 days ago","body": "Loved the ending.","isReply": false,"replyDepth": 0,"parentReviewId": null,"isDeveloperReply": false},{"reviewId": 2,"url": "https://itch.io/post/2","authorName": "Sample Studio","authorUrl": "https://itch.io/profile/sample-studio","authorSlug": "sample-studio","authorId": 2,"postedAt": "2026-01-01T00:00:00Z","postedAgo": "3 days ago","body": "Thank you, a sequel is in the works.","isReply": true,"replyDepth": 1,"parentReviewId": 1,"isDeveloperReply": true}],"scrapedAt": "2026-01-01T00:00:00Z","sourceUrl": "https://itch.io/games/genre-puzzle"}
Reviews, and what is not in them
A review row is exactly what the public comment thread shows to any visitor: the commenter's display name, their public handle, their profile address, their numeric user id, the exact time, the body text, where the comment sits in the reply tree, and whether the person answering is the game's own creator. The commenter's avatar image is deliberately not returned.
reviewCount is the total the page itself declares, which is usually far larger than reviewsReturned. Raise maxReviewsPerGame to walk further down the thread.
Incremental mode, and what counts as a change
In incremental mode each record carries changeType, changedFields, firstSeenAt and lastSeenAt. Two kinds of field are deliberately left out of the comparison, because including them would mark every record changed on every run:
- The review thread itself. A busy thread is entirely new rows within hours. Real movement is still detected, because
reviewCount,ratingandratingCountare all compared, so a game whose thread grew is still reported as UPDATED and still names those fields inchangedFields.reviewswill never appear there. - A jam entry's rank and score, which move with whichever ordering the run happened to read.
EXPIRED rows are only produced once a run has fully scanned the tracked search, so never after a capped run, a resumed run, or a scope that hit the site's 200-page depth limit.
Send results into your apps (MCP connectors)
Results can optionally be piped into the apps you already use, through Model Context Protocol connectors, without changing the dataset at all.
- Authorize a connector under Apify, Settings, API & Integrations.
- Select it in the Export to your apps (MCP connectors, optional) section of the input (
mcpConnectors). - For Notion, set
notionParentPageUrlto the page under which item pages should be created. maxNotifyListingscaps how many items are written to each connector per run.
Supported out of the box: Notion, Linear, Airtable and Apify. What gets written is a condensed, human readable summary per item, a title plus the key fields flattened to plain text, not the full JSON: nested objects collapse to their main value and arrays trim to a few names. The complete record always stays in the Apify dataset. If a connector fails, the run still succeeds and the dataset is unaffected.
Plan Requirement
Runs on any Apify account. Enable Apify Proxy in the Connection section for the most reliable results.