# Untappd Beer, Brewery and Check-in Scraper (`abotapi/untappd-scraper`) Actor

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.

- **URL**: https://apify.com/abotapi/untappd-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Categories:**
- **Stats:** 1 total users, 1 monthly users, 94.4% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Untappd Beer, Brewery and Check-in Scraper

Scrape **Untappd** (untappd.com): beers with their rating, rating count, style, ABV and IBU;
breweries with their type, location and complete beer list; venues; and the recent **check-in feed**
with each drinker's rating, comment, serving style, venue and badges.

Four modes, one flat record per beer, brewery or venue.

***

### Why this one

| | This actor | Typical Untappd scrapers on the Store |
|---|---|---|
| Results per keyword search | up to **1,000** | **5** (the logged-out wall on the site's own search page) |
| A brewery's beer list | **complete** (verified: 2,281 beers for one brewery) | first **25**, or brewery pages not supported at all |
| Top Rated chart | style **and** country, both from the site's own published lists | style only, or fixed chart |
| Venues (bars, taprooms, shops) | yes, as first class records | no |
| Filters applied at the source | style, minimum rating, minimum rating count, ABV band, still in production, exclude homebrew | none, or applied after download |
| Numbers | typed (`abv: 5.4`, `rating: 3.5`, `totalCheckins: 1590000`) | often raw strings (`"5.4%"`, `"1.3M+"`) |
| Recurring monitoring | incremental mode with NEW / UPDATED / REAPPEARED / EXPIRED | no |
| Resume an interrupted run | yes | no |

The 1,000 figure is the site's own per-query ceiling, not a cap this actor adds. A search with **no
keyword** (filters only) and a **brewery's beer list** are not subject to it: the actor walks those by
splitting the beer-id range, so the whole set is reachable however large it is.

***

### Modes

#### `search`

Search the site's own beer, brewery or venue index by keyword, narrowed by the filters below.

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

Leave `queries` empty and use the filters alone to browse, for example every Belgian Quadrupel with at
least 500 ratings:

```json
{
  "mode": "search",
  "queries": [],
  "styles": ["Belgian Quadrupel"],
  "minRatingCount": 500,
  "maxItems": 0
}
```

#### `brewery`

One row per brewery plus, by default, that brewery's **complete** beer list. Each entry is resolved
against the site itself, so a brewery name, a numeric id, a vanity address or a full link all work.

```json
{
  "mode": "brewery",
  "breweries": ["Dogfish Head Craft Brewery", "/dogfishbeer", "459"],
  "includeBreweryBeers": true,
  "maxItems": 0
}
```

#### `topRated`

The site's own Top Rated chart, for a style, a country, or both. Style and country names are checked
against the lists the site itself publishes; an unknown one is reported with close matches rather than
silently ignored.

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

#### `url`

Paste anything: beer pages, brewery pages, venue pages, search pages, chart pages, or a bare numeric
beer id. Pasted links are served first, so a brewery's large beer list can never fill `maxItems` and
drop the links you actually named.

```json
{
  "mode": "url",
  "urls": [
    "https://untappd.com/b/blue-moon-brewing-company-belgian-white/3839",
    "https://untappd.com/v/some-taproom/3793867",
    "https://untappd.com/beer/top_rated?type=belgian-quad&country=belgium"
  ]
}
```

***

### Check-ins and the detail toggle

Ids, name, brewery, style, ABV, IBU, rating, rating count, popularity, label images and location come
back on **every** record at no extra cost.

Switch on **Fetch details and check-ins** to add, per record and at one extra request each:

- the prose description,
- the exact **all-time**, **unique drinker** and **last four weeks** check-in counters,
- the recent **check-in feed**: who drank it, their rating, their comment, the serving style, the
  venue, where it was purchased, the badges they earned, any photo and when.

The site's own page carries about 20 recent check-ins for a logged-out visitor, so
`maxCheckinsPerEntity` above that returns what the page has. Set it to `0` to get the counters and the
description with no individual check-ins.

Only records that actually receive a page request are billed the **Detail enrichment** event.

***

### Output

One flat record per beer, brewery or venue. `entityType` says which, and `recordId` is a stable key
you can join on across runs.

Abridged example of a beer record (values below are illustrative):

```json
{
  "entityType": "beer",
  "recordId": "beer-000000",
  "beerId": 000000,
  "name": "Example Wheat Ale",
  "url": "https://untappd.com/b/example-brewing-example-wheat-ale/000000",
  "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-000000_sm.jpeg",
  "breweryId": 000000,
  "breweryName": "Example Brewing Company",
  "breweryUrl": "https://untappd.com/w/example-brewing-company/000000",
  "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": 2,
  "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"
    }
  ],
  "chartRank": null,
  "sourceUrl": null,
  "scrapedAt": "2026-08-28T12:00:00Z"
}
```

`beerCount` on a brewery row is the brewery's OWN headline figure as the site publishes it, and the
returned beer list can be longer than it: measured on one brewery, the site's headline says 1,434
while its search index carries 2,281 rows under the same brewery id (variants, collaborations and
retired brews). Both numbers are reported as the site gives them; neither is corrected into the other.

Brewery records add `breweryType`, `country`, `city`, `state`, `address`, `beerCount`,
`outOfBusiness`, `latitude`, `longitude`, and, with the detail toggle on, `website`, `instagramUrl`,
`twitterUrl`, `facebookUrl`, `parentCompany`, `isOfficial` and the brewery's own rating.

Venue records carry `address`, `city`, `state`, `country`, `categories`, `isVerified`, `isClosed`,
`servesBeer`, `servesFood`, `servesWine`, `servesSpirits`, `popularity` and
`popularityLast30Days`.

#### Two fields deliberately not returned

- **User avatar images.** Some of them are served by an avatar service whose address is a hash of the
  drinker's e-mail, so republishing that URL republishes a reversible e-mail hash. The public handle,
  display name and profile address are returned instead, which is what the check-in itself shows.
- **Third-party listing-directory links on a venue.** The venue's own `website` is returned; the two
  outbound directory links beside it are not beer data and one of them carries a referral token.

***

### Recurring monitoring and resume

Two separate features, both in the **Resume and recurring updates** section.

- **`resumeFromRunId`** continues ONE interrupted run. Paste the run or dataset id; records already
  collected there are neither returned nor billed again.
- **`incrementalMode`** is for a schedule. The first run returns everything as `NEW`; later runs return
  only `NEW`, `UPDATED` and `REAPPEARED` unless you also switch on `emitUnchanged` or `emitExpired`
  (both return, and bill, extra rows). Every row then carries `changeType`, `changedFields`,
  `firstSeenAt` and `lastSeenAt`.

State is keyed on the mode, targets and filters, so two different searches never share a baseline. Set
`stateKey` to name a campaign or to deliberately share one.

`EXPIRED` rows are only produced after a run that fully scanned the tracked search. A run capped by
`maxItems`, a resumed run, a run that collected nothing, and a keyword scope that hit the site's own
1,000-result ceiling all skip expiry detection rather than tombstoning records they simply did not
reach.

**Fields that never appear in `changedFields`,** because they move on every fetch and would rewrite
every row: `checkins`, `checkinsReturned`, `popularity`, `chartRank`, `scrapedAt`, `sourceUrl`, and the
abbreviated counter strings `totalCheckinsText`, `uniqueUsersText` and `monthlyCheckinsText`. Nothing is lost: `totalCheckins`, `uniqueUsers`, `monthlyCheckins`,
`rating`, `ratingPrecise` and `ratingCount` are all tracked, so real movement still classifies a record
`UPDATED` and still names those fields.

***

### Send results into your apps (MCP connectors)

Optionally pipe this run's records into Notion, Linear, Airtable or Apify through Model Context
Protocol (MCP) connectors. Authorize a connector once under Apify, Settings, API & Integrations, then
pick it in the connectors section of the input. Notion gets a rich page per record; the other
connectors get a best-effort write or digest. The export runs after the dataset is complete and never
changes what the dataset returns, so nothing is lost if you leave it off.

| Input | What it does |
|---|---|
| `mcpConnectors` | The connectors this run exports into (Notion, Linear, Airtable, Apify). Leave it empty and nothing is exported. |
| `notionParentPageUrl` | Notion connector only: the page under which one child page per record is created. Required to enable the Notion export, ignored by the other connectors. |
| `maxNotifyListings` | How many records are written to each connector in one run, default 50. Caps the export only, never the dataset. |

***

### Limits, honestly

- **One keyword search returns at most 1,000 results.** That is the site's own per-query ceiling. The
  run logs a warning naming it and suggests narrowing with a style, a minimum rating count or an ABV
  band. A **filter-only** search and a **brewery's beer list** are not affected.
- **The Top Rated chart is one fixed-length page per style and country.** The site publishes no page 2
  for it, so `maxPages` cannot extend it.
- **`country` does not narrow a beer search.** The site publishes a country on a brewery and on a
  venue, not on a beer. It is the site's own filter on the Top Rated chart, and a result-side filter on
  brewery and venue searches.
- **Check-ins are the public feed a logged-out visitor sees,** roughly the 20 most recent per page.
  This actor does not log in and returns nothing that requires an account.
- **A run that reads nothing fails.** If every request is refused, the run exits with an error naming
  it, never as a green run with an empty dataset.

***

### Connection

The site answers over the standard connection pool that every Apify plan includes, so that is the
default and the cheapest option. It does refuse individual exits from time to time; the actor rotates
to a new one and retries, with a hard cap of five attempts and a short timeout, then fails fast rather
than grinding. A residential pool is available if you want one, but this site does not need it, and it
is never selected for you.

### Local development

```bash
python3.12 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/python -m pytest tests -q
apify run --purge
```

# Actor input Schema

## `mode` (type: `string`):

Choose 'search' to search by keyword and filters, 'brewery' to pull named breweries and their beer lists, 'topRated' to read the site's own Top Rated chart, or 'url' to scrape pasted beer, brewery, venue, search and chart links.

## `entityType` (type: `string`):

Only used when mode = search. Beers return name, brewery, style, ABV, IBU, rating and rating count. Breweries return type, location, beer count and popularity. Venues return address, categories and activity. Ignored in the other three modes.

## `queries` (type: `array`):

Only used when mode = search, ignored in the other modes. One or more keywords, for example 'hazy ipa', 'westvleteren' or 'brewpub denver'. Leave empty to browse by the filters alone.

## `breweries` (type: `array`):

Only used when mode = brewery, ignored in the other modes. Brewery names, numeric ids, vanity addresses such as /dogfishbeer, or full brewery links.

## `includeBreweryBeers` (type: `boolean`):

Used in brewery mode and for a brewery link pasted in url mode. On by default: the brewery row is returned together with its COMPLETE beer list, each beer carrying its own style, ABV, IBU, rating and rating count. The site's own brewery page shows only the first 25 beers to a logged out visitor, so this is the only way to read the rest. Switch off to return the brewery row alone.

## `urls` (type: `array`):

Only used when mode = url, ignored in the other modes. Mix freely: beer pages such as /b/<slug>/<id>, brewery pages, venue pages such as /v/<slug>/<id>, search pages and /beer/top\_rated chart pages. A bare numeric beer id is also accepted.

## `styles` (type: `array`):

Optional. Keep only beers in these styles, written the way the site writes them, for example 'Belgian Quadrupel' or 'IPA - New England / Hazy'. Capitals, spaces and punctuation do not matter. Selecting several returns beers in any of them. Styles are checked against the site's OWN published style list every run; a style the site does not publish is reported with close matches, and if none of your styles exist the run stops rather than quietly returning unfiltered results.

## `country` (type: `string`):

Optional. Written the way the site writes it, for example 'Belgium' or 'United States'. On the Top Rated chart this is the site's own country filter. On a brewery or venue search it keeps only rows from that country. It has no effect on a beer search: the site publishes no country on a beer, only on its brewery. Checked against the site's own published country list; an unknown country stops the run with close matches.

## `minRating` (type: `integer`):

Optional. Keep only beers rated at or above this score on the site's own 0 to 5 scale. Applied by the site's index, so it narrows the result count at the source. Use 0 for no minimum.

## `minRatingCount` (type: `integer`):

Optional. Keep only beers that have been rated at least this many times, which is the usual way to filter out beers whose average is based on a handful of check-ins. Applied by the site's index. Use 0 for no minimum.

## `minAbv` (type: `integer`):

Optional. Keep only beers at or above this alcohol strength, as a percentage. Applied by the site's index. Use 0 for no minimum.

## `maxAbv` (type: `integer`):

Optional. Keep only beers at or below this alcohol strength, as a percentage. Applied by the site's index. Leave empty for no maximum.

## `inProductionOnly` (type: `boolean`):

Optional. Keep only beers the brewery still makes, dropping retired and one-off brews. Applied by the site's index.

## `excludeHomebrew` (type: `boolean`):

Optional. Drop beers entered as homebrew rather than as a commercial release. Applied by the site's index.

## `minCheckins` (type: `integer`):

Optional. Keep only records with at least this many all-time check-ins. That counter only exists on each beer, brewery or venue page, so this filter requires Fetch details and check-ins below and the run stops if it is set without it. Use 0 for no minimum.

## `sortBy` (type: `string`):

The order the site returns results in. Every value is one of the site's OWN orderings, applied at the source. Popularity is the site default and works for all three entity types. Beer name, brewery name and the two ABV orders apply to beers; recent popularity applies to venues. An ordering that does not exist for the entity you searched falls back to that entity's popularity order.

## `fetchDetails` (type: `boolean`):

Read each record's own page to add the prose description, the exact all-time, unique and monthly check-in counters, and the recent check-in feed: who drank it, their rating, their comment, the serving style, the venue, what badges they earned, any photo and when. One extra request per record, billed as one Detail enrichment event per record returned.

## `maxCheckinsPerEntity` (type: `integer`):

Cap on how many recent check-ins are returned per beer, brewery or venue. The description and the check-in counters are always complete regardless of this cap. Use 0 to return the counters and description but no individual check-ins. The site's own page carries about 20 recent check-ins for a logged out visitor, so values above that return what the page has.

## `maxItems` (type: `integer`):

Maximum number of records to return across the whole run. This is the run's cap. Use 0 for unlimited. Note the site's own limit underneath it: one KEYWORD search returns at most 1,000 results however high you set this. A search with no keyword, and a brewery's beer list, have no such limit, because the actor walks those by splitting the id range.

## `maxPages` (type: `integer`):

Maximum number of result pages read per scope. 0 means no limit, which is the default: the run then stops only at Max results, at the end of the results, or at the site's own ceiling.

## `resumeFromRunId` (type: `string`):

Paste a previous run ID or dataset ID to continue a large pull without returning or charging for records already collected there. Use this after an interrupted run. For recurring daily monitoring of the same search, use Incremental mode below instead.

## `incrementalMode` (type: `boolean`):

Turn this on for daily or recurring monitoring. The first run returns every matching record as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED records. Turn on Emit unchanged or Emit expired only when you also want those rows returned (and billed). State is kept separately for each search, filter and lookup setup; use State key to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above.

## `stateKey` (type: `string`):

Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently configured runs. Leave empty to let the actor derive a key automatically from the mode, targets and filters, so different searches never mix state with each other.

## `emitUnchanged` (type: `boolean`):

Off by default. Turn on to also return records that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have, so leave it off unless you want the full snapshot every run.

## `emitExpired` (type: `boolean`):

Off by default. Turn on to also return records that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search, so never when Max results capped it, when Resume was used, or when a keyword hit the site's own result ceiling. This returns, and bills, extra synthetic rows, so leave it off unless you need expiry tracking.

## `proxy` (type: `object`):

Apify Proxy is recommended. The standard pool is the default and is sufficient for this site.

## `mcpConnectors` (type: `array`):

Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a rich page-per-item export; other connectors get a best-effort write or digest. Leave empty to skip; never changes the dataset output. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL or id of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## Actor input object example

```json
{
  "mode": "search",
  "entityType": "beer",
  "queries": [
    "hazy ipa"
  ],
  "breweries": [
    "Dogfish Head Craft Brewery"
  ],
  "includeBreweryBeers": true,
  "urls": [
    "https://untappd.com/b/blue-moon-brewing-company-belgian-white/3839",
    "https://untappd.com/beer/top_rated?type=belgian-quad"
  ],
  "minRating": 0,
  "minRatingCount": 0,
  "minAbv": 0,
  "inProductionOnly": false,
  "excludeHomebrew": false,
  "minCheckins": 0,
  "sortBy": "popularity",
  "fetchDetails": false,
  "maxCheckinsPerEntity": 20,
  "maxItems": 20,
  "maxPages": 0,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "proxy": {
    "useApifyProxy": true
  },
  "maxNotifyListings": 50
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "search",
    "entityType": "beer",
    "queries": [
        "hazy ipa"
    ],
    "breweries": [
        "Dogfish Head Craft Brewery"
    ],
    "urls": [
        "https://untappd.com/b/blue-moon-brewing-company-belgian-white/3839",
        "https://untappd.com/beer/top_rated?type=belgian-quad"
    ],
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "proxy": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/untappd-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "search",
    "entityType": "beer",
    "queries": ["hazy ipa"],
    "breweries": ["Dogfish Head Craft Brewery"],
    "urls": [
        "https://untappd.com/b/blue-moon-brewing-company-belgian-white/3839",
        "https://untappd.com/beer/top_rated?type=belgian-quad",
    ],
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "proxy": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/untappd-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "search",
  "entityType": "beer",
  "queries": [
    "hazy ipa"
  ],
  "breweries": [
    "Dogfish Head Craft Brewery"
  ],
  "urls": [
    "https://untappd.com/b/blue-moon-brewing-company-belgian-white/3839",
    "https://untappd.com/beer/top_rated?type=belgian-quad"
  ],
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "proxy": {
    "useApifyProxy": true
  }
}' |
apify call abotapi/untappd-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/untappd-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/JttI8pRoJE61PXBUl/builds/0uvlhL7AfY2CdpEbQ/openapi.json
