Untappd Beer, Brewery and Check-in Scraper avatar

Untappd Beer, Brewery and Check-in Scraper

Pricing

from $1.00 / 1,000 results

Go to Apify Store
Untappd Beer, Brewery and Check-in Scraper

Untappd Beer, Brewery and Check-in Scraper

Scrape Untappd beers, breweries, venues and check-ins by keyword, brewery, Top Rated chart or pasted link. Returns rating, rating count, style, ABV, IBU, brewery, check-in counters and recent check-ins with comments. Incremental mode tracks changes.

Pricing

from $1.00 / 1,000 results

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

0

Bookmarked

6

Total users

3

Monthly active users

2 days ago

Last modified

Categories

Share

Untappd Scraper: Beers, Breweries, Venues and Check-ins

Untappd Scraper turns Untappd into structured beer, brewery, venue and check-in data. Search the site's own beer, brewery or venue index by keyword and filters, pull one or more breweries together with their complete beer list, read the site's own Top Rated chart by style and country, or paste beer, brewery, venue, search and chart links. Beer records carry typed ids, style, ABV, IBU, rating, rating count and popularity at no extra cost (Top Rated chart rows are lighter, without popularity, styleId, breweryId or brewery coordinates); brewery and venue records carry their own location and identity fields instead. One opt-in per-record lookup adds the prose description, the exact check-in counters and the recent check-in feed: who drank it, their rating, comment, serving style, venue and badges. Export the dataset to JSON, CSV or Excel, or read it straight into your app through the API.

Why This Scraper?

  • Four ways to find data. Search by keyword and filters, look up named breweries with their full beer list, read the site's own Top Rated chart, or paste links. No need to build addresses by hand.
  • Complete brewery beer lists. A brewery's beer list is walked past the site's own per-query result ceiling by splitting the beer id range, so the whole list is reachable however large it is, not just the first page a logged-out visitor sees.
  • Filters applied at the source. Beer style, minimum rating, minimum rating count, ABV band, still-in-production and exclude-homebrew are all applied by the site's own index, so the result count is narrowed before download, not after.
  • Venues as first-class records. Bars, taprooms and bottle shops come back with address, categories, verification and activity, alongside beers and breweries.
  • Typed fields, not raw strings. Numbers come back as numbers (abv: 5.4, rating: 3.5, totalCheckins: 1590000), with the site's own abbreviated text ("1.59M+") kept alongside rather than in place of the parsed value.
  • An opt-in detail lookup. Switch on one toggle to add the prose description, the exact all-time, unique-drinker and last-four-weeks check-in counters, and the recent check-in feed, billed only for the records that actually receive the extra page request. If detail pages keep failing, the actor logs a warning and stops fetching them for the rest of the run; the remaining records come back with index fields only and are not charged for enrichment.
  • Built for recurring monitoring. Incremental mode classifies every record as new, updated, unchanged, reappeared or expired against the previous run, and a genuinely blocked run fails loudly instead of returning an empty dataset.

Use Cases

  • Beer catalog and inventory apps: pull a brewery's complete beer list with style, ABV, IBU and rating to power a shop, taproom or cellar-tracking catalog.
  • Craft beer research and trend analysis: read the Top Rated chart by style and country to compare how styles and regions rank against each other.
  • Venue discovery tools: find taprooms, bars and bottle shops with address, categories and activity for a local guide or map.
  • Review and reputation monitoring: watch a beer's or brewery's rating, rating count and recent check-in comments as they move over time.
  • Portfolio and competitor tracking: schedule incremental runs against a list of breweries or styles to catch new releases and rating changes as they happen.

Data You Get

Sample shape: values are illustrative placeholders, not from a live record.

FieldExample
entityType"beer" (also "brewery", "venue")
recordId"beer-100000", a stable cross-run key
beerId100000
name"Example Wheat Ale"
url"https://untappd.com/b/example-brewing-example-wheat-ale/100000"
style / styleId"Wheat Beer - Witbier / Blanche" / 47
abv / ibu5.4 / 9
rating / ratingCount3.5 / 625469
popularity1590000
inProduction / isHomebrewtrue / false
labelImagebeer label image URL
breweryId / breweryName200000 / "Example Brewing Company"
breweryUrlbrewery page URL
breweryLatitude / breweryLongitude39.7392 / -104.9903
descriptionprose description (needs Fetch details and check-ins)
totalCheckins / totalCheckinsText1590000 / "1.59M+" (needs Fetch details and check-ins)
uniqueUsers709417 (needs Fetch details and check-ins)
monthlyCheckins3487 (needs Fetch details and check-ins)
checkinsReturned1 (needs Fetch details and check-ins)
checkinsthe recent check-in feed (needs Fetch details and check-ins)
chartRankrank on the Top Rated chart, null outside it
changeType"NEW", "UPDATED", "UNCHANGED", "REAPPEARED" or "EXPIRED" (incremental mode only)

Brewery records replace the beer fields above with breweryType, country, city, state, address, beerCount, outOfBusiness, latitude and longitude, and add website, instagramUrl, twitterUrl, facebookUrl, parentCompany, isOfficial and the brewery's own rating and ratingCount when Fetch details is on. Venue records carry address, city, state, country, categories, isVerified, isClosed, servesBeer, servesFood, servesWine, servesSpirits, popularity and popularityLast30Days. Each entry in checkins carries its own checkinId, checkinUrl, userName, userSlug, userProfileUrl, rating, comment, servingStyle, venueName, venueUrl, purchasedFrom, badges, toastCount, commentCount, photoUrl and createdAt. Incremental mode adds changedFields, firstSeenAt and lastSeenAt alongside changeType. A beer or venue link pasted in url mode returns the exact same index-derived fields as a search result for that entity, never a narrower record.

How to Use

  1. Pick a mode: search (keyword and filters), brewery (named breweries plus their beer list), topRated (the site's own chart by style and/or country), or url (paste links).
  2. Fill in the fields for that mode, and set the filters you want: style, minimum rating, minimum rating count, ABV band, production status.
  3. Switch on Fetch details and check-ins if you want the description, the exact check-in counters and the recent check-in feed, and set Max results and Max result pages to control run size and cost.
  4. Click Start, then download the dataset as JSON, CSV or Excel, or read it through the API.

URL mode link shapes. The Console example list shows every shape below. The shipped default list keeps one link per distinct target (nine: a beer, a brewery by address, a brewery by id, a venue, four Top Rated charts and a search); the beer id only, share query, photos page, beer list and name slug variants resolve to a target already in the default list, so an untouched url-mode run does not scrape them separately. Replace them with your own links. A venue link the site's search index does not list is read from the venue's own page instead. Any other address, and any venue link that returns no venue, is skipped with a warning naming it.

Link shapeExample
Beer pagehttps://untappd.com/b/blue-moon-brewing-company-belgian-white/3839
Beer id onlyhttps://untappd.com/beer/3839
Beer page with share queryhttps://untappd.com/b/blue-moon-brewing-company-belgian-white/3839?ref=share
Beer photos pagehttps://untappd.com/b/blue-moon-brewing-company-belgian-white/3839/photos
Brewery addresshttps://untappd.com/DogfishBeer
Brewery beer listhttps://untappd.com/DogfishBeer/beer
Brewery by idhttps://untappd.com/brewery/1
Brewery with name slughttps://untappd.com/w/dogfish-head-craft-brewery/1
Venuehttps://untappd.com/v/bowditch-field/932830
Top Rated, globalhttps://untappd.com/beer/top_rated
Top Rated by stylehttps://untappd.com/beer/top_rated?type=belgian-quad
Top Rated by countryhttps://untappd.com/beer/top_rated?country=belgium
Top Rated by style and countryhttps://untappd.com/beer/top_rated?type=belgian-quad&country=belgium
Search page (beer, brewery or venue)https://untappd.com/search?q=hazy+ipa&type=beer

Search beers by keyword, narrowed by rating count:

{
"mode": "search",
"entityType": "beer",
"queries": ["hazy ipa"],
"minRatingCount": 500,
"maxItems": 50
}

A brewery with its complete beer list:

{
"mode": "brewery",
"breweries": ["Dogfish Head Craft Brewery"],
"includeBreweryBeers": true,
"maxItems": 0
}

The Top Rated chart for one style and country:

{
"mode": "topRated",
"styles": ["Belgian Quadrupel"],
"country": "Belgium"
}

Paste links (beer, venue, brewery, search or chart):

{
"mode": "url",
"urls": [
"https://untappd.com/b/blue-moon-brewing-company-belgian-white/3839",
"https://untappd.com/beer/top_rated?type=belgian-quad"
]
}

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/untappd-scraper").call(run_input={"mode": "search", "queries": ["hazy ipa"], "maxItems": 50})
for beer in client.dataset(run["defaultDatasetId"]).iterate_items():
print(beer["name"], beer["rating"], beer["breweryName"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/untappd-scraper').call({ mode: 'search', queries: ['hazy ipa'], maxItems: 50 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

Max results, max pages and the site's own ceiling

One keyword search returns at most 1,000 results, which is the site's own per-query ceiling, not a cap this actor adds; the run logs a warning naming it and suggests narrowing with a style, a minimum rating count or an ABV band. A filter-only beer search (no keyword) and a brewery's beer list are not subject to that ceiling: the actor walks those by splitting the beer id range, so the whole set is reachable however large it is. A filter-only venue or brewery search has no such split and still stops at 1,000. Max result pages caps how many pages are read per scope; leave it at 0 to stop only at Max results, the end of the results, or the site's own ceiling.

Resume and recurring updates

  • resumeFromRunId continues ONE interrupted run. Paste its run or dataset id and records already collected there are neither returned nor billed again.

  • incrementalMode is for a schedule over the same search. The first run returns everything as NEW. Later runs return only NEW, UPDATED and REAPPEARED by default; turn on emitUnchanged or emitExpired to also return (and bill) unchanged or expired rows. A record can only be classified REAPPEARED if it was tombstoned EXPIRED by an earlier run, and a record can only be tombstoned EXPIRED when that earlier run had emitExpired on AND had proved a complete, uncapped, non-resumed scan of the tracked search; a capped run, a resumed run, a run that collected nothing, or a keyword scope that hit the site's own 1,000-result ceiling all skip expiry detection instead of tombstoning records they simply did not reach. stateKey names or shares the stored state, so two different searches never mix state with each other.

    What is compared. The beer, brewery and venue data fields (name, rating, ratingCount, abv, style, status, location and similar) decide UPDATED and appear in changedFields. These fields stay in the output but never appear in changedFields and never make a record UPDATED, because they move on every scrape: scrapedAt, scrapedTimestamp, beerName, imageUrl, sourceUrl, chartRank, checkins (including each check-in's toastCount, commentCount and createdAt), checkinsReturned, popularity, totalCheckins, totalCheckinsText, monthlyCheckins, monthlyCheckinsText, uniqueUsers and uniqueUsersText. Numbers compare the same whether stored as 5.0 or 5. Add your own exclusions with Ignore fields when detecting changes (incremental mode only) (ignoreFieldsForChanges): field names, or a dotted path such as checkins.rating. Changing the ignore list never produces a one-time wave of UPDATED rows, because unchanged is decided by re-comparing the saved snapshot with the current ignore list.

Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.

What gets written to the connector: a condensed, human-readable summary of each record, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.

  1. Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
  3. For Notion, also set notionParentPageUrl to the page where items should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

Input Parameters

ParameterTypeDefaultDescription
modestringsearchsearch, brewery, topRated, or url.
entityTypestringbeerSearch mode only: beer, brewery, or venue.
queriesarrayno default (prefill: ["hazy ipa"])Search mode keywords. Leave empty to browse by the filters alone.
breweriesarrayno default (prefill: ["Dogfish Head Craft Brewery"])Brewery mode: names, numeric ids, vanity addresses, or full brewery links.
includeBreweryBeersbooleantrueAlso return the named brewery's complete beer list.
urlsarraynine distinct example links (a beer, a brewery by address, a brewery by id, a venue, four Top Rated charts and a search)Url mode: beer, brewery, venue, search or chart links, or a bare numeric beer id.
stylesarrayno default (empty)Keep only these beer styles, checked against the site's own published list.
countrystringno default (empty)Country filter, checked against the site's own published list.
minRatinginteger0Minimum rating on the site's 0 to 5 scale.
minRatingCountinteger0Minimum number of ratings.
minAbvinteger0Minimum ABV percentage.
maxAbvintegerno default (empty, no maximum)Maximum ABV percentage.
inProductionOnlybooleanfalseKeep only beers still in production.
excludeHomebrewbooleanfalseDrop beers entered as homebrew.
minCheckinsinteger0Minimum total check-ins. Requires fetchDetails; setting it without that toggle fails the run immediately, before any request is made.
sortBystringpopularitypopularity, popularity_recent, name_asc, name_desc, brewery_name, abv_desc, or abv_asc.
fetchDetailsbooleanfalseRead each record's own page: description, exact check-in counters and the recent check-in feed. Billed as one Detail enrichment event per record returned.
maxCheckinsPerEntityinteger20Cap on individual check-ins returned per record. 0 means the maximum of 100, not zero check-ins; leaving it blank uses the default of 20; use 1 for the smallest non-empty feed. The site's page shows about 20 recent check-ins to a logged-out visitor and its Show More button needs a login, so more than about 20 are not available.
maxItemsinteger20Stop after this many records. 0 for unlimited.
maxPagesinteger0Max result pages read per scope. 0 for no limit.
resumeFromRunIdstringno default (empty)Continue one interrupted run from its run or dataset id.
incrementalModebooleanfalseReturn only new and changed records on repeated runs.
stateKeystringno default (empty)Name or share an incremental-mode state.
emitUnchangedbooleanfalseAlso return (and bill) unchanged records.
emitExpiredbooleanfalseAlso return (and bill) expired records, only after a complete scan.
ignoreFieldsForChangesarrayno default (empty)Field names (or dotted paths) left out of change detection in incremental mode. They stay in the output.
proxyobject{"useApifyProxy": true}Connection settings.
mcpConnectorsarrayno default (empty)Optional: send a summary of each record to apps you authorized under Integrations.
notionParentPageUrlstringno default (empty)Notion connector only: page under which records are created.
maxNotifyListingsinteger50Cap on items written to each connector per run.

Output Example

Sample shape: values are illustrative placeholders, not from a live record.

{
"entityType": "beer",
"recordId": "beer-100000",
"beerId": 100000,
"name": "Example Wheat Ale",
"url": "https://untappd.com/b/example-brewing-example-wheat-ale/100000",
"style": "Wheat Beer - Witbier / Blanche",
"styleId": 47,
"abv": 5.4,
"ibu": 9,
"rating": 3.5,
"ratingPrecise": 3.49888,
"ratingCount": 625469,
"popularity": 1590000,
"inProduction": true,
"isHomebrew": false,
"hasCommunityAward": false,
"labelImage": "https://assets.untappd.com/site/beer_logos/beer-100000_sm.jpeg",
"breweryId": 200000,
"breweryName": "Example Brewing Company",
"breweryUrl": "https://untappd.com/w/example-brewing-company/200000",
"breweryLatitude": 39.7392,
"breweryLongitude": -104.9903,
"description": "An unfiltered wheat ale spiced with coriander and orange peel.",
"totalCheckins": 1590000,
"totalCheckinsText": "1.59M+",
"uniqueUsers": 709417,
"monthlyCheckins": 3487,
"checkinsReturned": 1,
"checkins": [
{
"checkinId": 100000001,
"checkinUrl": "https://untappd.com/user/example_user/checkin/100000001",
"userName": "Example User",
"userSlug": "example_user",
"userProfileUrl": "https://untappd.com/user/example_user",
"rating": 4,
"comment": "Great with an orange slice.",
"servingStyle": "Draft",
"venueName": "Example Taproom",
"venueUrl": "https://untappd.com/v/example-taproom/000000",
"purchasedFrom": "Example Taproom",
"badges": ["Earned the Example badge!"],
"toastCount": 2,
"commentCount": 0,
"photoUrl": null,
"createdAt": "Fri, 28 Aug 2026 03:23:16 +0000",
"checkinText": "Example comment",
"checkinDate": "Fri, 28 Aug 2026 03:23:16 +0000",
"checkinPhotoUrl": null
}
],
"chartRank": null,
"sourceUrl": null,
"scrapedAt": "2026-08-28T12:00:00Z",
"scrapedTimestamp": "2026-08-28T12:00:00Z"
}

Output tabs and run summary

The dataset has these tabs: Overview (all records), Detail enrichment (page fields added by Fetch details), Check-ins (one row per check-in, from the checkins list of each record, needs Fetch details), Changes (incremental mode rows), Breweries and Venues. Check-ins are not separate dataset items, so they add no extra result charge. After each run a summary is saved under the OUTPUT key of the key-value store (records by type and change type, enriched count, rejected requests).

Field aliases and what is not offered

Each check-in also carries checkinText, checkinDate and checkinPhotoUrl (same values as comment, createdAt and photoUrl). Beer records also carry beerName (= name) and imageUrl (= labelImage), and every record carries scrapedTimestamp (= scrapedAt), so exports built for other Untappd datasets keep working. Row-level errors are reported in the run status message rather than as a per-row error field.

A bare beer id (for example 3839) is accepted in Site links (urls) in URL mode, and free-text searches go in queries. The "friends" and "you" check-in filters are not offered: they show only a logged-in account's own feed and this scraper never signs in.

Fields deliberately dropped from check-in rows: user avatar images and the per-link referral token, because neither carries data about the beer.

Plan Requirement

The default connection setting works on a plan that includes Apify proxy access: the standard proxy pool is enough, and the residential group is never selected for you. The site challenges plain clients but serves real pages to the browser-grade connection this actor uses, and an individual connection that is refused is replaced with a fresh one automatically.

Apify free plans do not include proxy access. On such a plan the run continues on a backup connection and logs: "The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable." When results come from it, the status reads "Served over the backup connection (the default connection was unavailable)." If no page can be read the run fails with one of three messages instead of returning an empty dataset: "The proxy connection was refused for this account ... a paid plan is required" (no proxy access), "No results: residential proxies are unavailable on this run ... and the backup connection could not load the requested Untappd pages" (residential selected but unavailable), or "Could not load any results page (the requests failed) ... This is a connection problem, not an empty search" (the site could not be reached). If you enter your own proxy URLs, check that their credentials are valid.

FAQ

How much does it cost?

You pay per record returned (the Result event), a small Actor start charge of one event per GB of run memory (the default memory is 4 GB, so four start events per run), plus one Detail enrichment event for each returned record that received its own page request when Fetch details and check-ins is switched on. In incremental mode, a record whose page was read to check for changes but that turned out unchanged and suppressed is neither returned nor charged the enrichment event. The Pricing tab shows the current rates. Use Max results to cap the cost of any run.

This actor collects only publicly available beer, brewery, venue and check-in data that a logged-out visitor can see. You are responsible for how you use it: follow Untappd's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Ratings, styles and check-in counts are generally facts, but check-in comments, photos and usernames are user-generated content and may carry their own rights.

Can I get only new or changed records on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new, updated and reappeared records by default, and unchanged ones are not billed unless you turn on Emit unchanged.

Why does a brewery's beer list return a different count than the brewery's own headline figure?

The returned list is the site's own search index for that brewery id, which can carry variants, collaborations and retired brews the brewery's own summary figure counts differently. Both numbers are reported exactly as the site gives them; neither is corrected into the other.

Why did my run fail instead of returning an empty dataset?

If every request is refused after retries, the run stops with a clear error naming it, so a real block is never confused with "no results found". A search that reads fine but genuinely matches nothing still succeeds, with an empty dataset and a status message saying so.

Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.

🔗 Want more wine and drinks data?

Pair this actor with these related scrapers from the same team:

🍷 Dan Murphy’s Scraper
Scrape Dan Murphy’s products by category, keyword, or specials. Extract 45+ fields...
🍷 Vivino Wine Scraper
From $1.2/1K. Scrape Vivino.com for wine ratings, prices, taste profiles, food pairings...
🍷 Wine-Searcher Scraper
Look up wines on wine-searcher.com by name, URL, or LWIN code. Returns 30+ fields...
🥦 ResQ Club Scraper
Scrape ResQ Club surplus food offers in Finland, Sweden and Estonia: name, price, current...
🥦 Instacart Scraper
Scrape Instacart grocery catalogs with per-store prices. Run keywords across several...
🥦 FoodHero Scraper
Scrape FoodHero surplus grocery deals across Canada by area, store or offer ID. Extract...

👉 Browse all abotapi scrapers

💬 Support

  • 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
  • 🛠️ Need another site, extra fields or a private build? Email contact@abotapi.com.
  • ⭐ Enjoying it? A quick review on the actor page helps other users find it.