# Fever Scraper - Events, Prices, Venues & Dates (`abotapi/fever-com-scraper`) Actor

Scrape Fever events by city, category, keyword or URL. Extract from-prices, venues, dates and ratings, with optional enrichment for event descriptions, venue addresses and available sessions.

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

## Pricing

from $1.50 / 1,000 event records

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Fever Scraper: Events, Experiences and Prices by City

Fever Scraper turns feverup.com into a clean events data feed. Browse a city's whole catalogue of immersive experiences, pop-ups, concerts and local events by name, category or keyword, or paste Fever links straight in. Every row carries the event identity, the from-price in its own currency, the venue, the date range and the rating pair from the listing itself. The description, venue address with coordinates, categories, session dates and ticket availability are one toggle away, then export to JSON, CSV or Excel, or pull results straight into your app through the API.

### Why This Scraper?

- **Two ways to find events.** Browse city catalogues by name with an optional category and keyword, or paste any Fever event, city or category link and let the URL decide the scope.
- **No page-by-page crawl to get stuck on.** A city catalogue page renders its whole feed in one request. A category page can serve only its first window behind the site's Load more control; when that happens the run reports "Partial results" instead of silently under-counting.
- **Identity, price and rating on every row.** The event title, from-price with its own currency, venue, date range and rating pair come straight from the listing, with no toggle required.
- **Event-page depth on demand.** Switch on the description, venue address with coordinates, categories, session dates and ticket availability, and the extra fee applies only to the records you actually enrich.
- **Built for schedules.** Incremental mode returns only new and changed events on repeat runs, and a fully refused run fails loudly instead of quietly returning an empty dataset.
- **Keyword and price filters the site itself lacks.** Both are applied to what this run actually reads, checked against each event's own currency.
- **Wide city coverage.** Dozens of cities across several languages, from New York and London to Madrid, Paris, Milan and Sao Paulo.

### Use Cases

- **Local event guides and newsletters:** pull a city's candlelight, music, exhibition or food events with prices and dates for a weekly roundup.
- **Price and availability monitoring:** schedule incremental mode against one city or category to catch price drops, new sessions or events going on sale.
- **Travel and city-guide apps:** feed nearby experiences, venues and ratings into your own app or itinerary tool.
- **Competitive and market research:** track which immersive experiences and pop-ups are launching across cities and how they are priced.
- **Ticketing aggregators:** build a cross-city catalogue of experiences with venue, price and session data for comparison.

### Data You Get

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

| Field | Example |
| --- | --- |
| `recordId` | `"9000001"` |
| `rowType` | `"event"` |
| `eventId` | `"9000001"` |
| `url` | `"https://feverup.com/m/9000001"` |
| `title` | `"Sample Concert Evening"` |
| `citySlug` | `"new-york"` |
| `locale` | `"en"` |
| `category` | `"candlelight"` |
| `priceFrom` | `25` |
| `priceText` | `"From 25.00 USD"` |
| `originalPrice` | `30` |
| `onSale` | `true` |
| `discountPercent` | `16.7` |
| `currency` | `"USD"` |
| `startDate` | `"2026-11-01T19:00:00-04:00"` |
| `endDate` | `"2026-11-30T21:00:00-04:00"` |
| `venueName` | `"Sample Hall"` |
| `rating` | `4.5` |
| `ratingCount` | `320` |
| `isNew` | `false` |
| `description` (Fetch event details) | `"A candlelit evening of chamber music for all ages."` |
| `venueAddress` (Fetch event details) | `"100 Sample Street, New York, 10001"` |
| `ticketsAvailable` (Fetch event details) | `true` |
| `reviews` (Fetch event details) | `[{"reviewer": "Sample G.", "rating": 5, "date": "2026-10-04T19:55:04+00:00", "text": "Great evening.", "helpfulVotes": 0}]` |
| `changeType` (incremental mode) | `"UPDATED"` |

Every row also carries `imageUrl`, `priceType` (`"from"` on a from-priced event), `sessionDate` (the specific date a session card matched, on category agenda pages), `latitude`/`longitude` and `categories` (event details toggle), `firstSessionDate`/`lastSessionDate` and `sessionsText` (event details toggle), `detailCarriedForward` (present and `true` only when a failed details read was repaired from a previous run's snapshot instead of left blank), `scrapedAt`, and, in incremental mode, `changedFields`, `firstSeenAt` and `lastSeenAt`.

### How to Use

1. Pick a **mode**: `search` (browse city catalogues) or `url` (paste Fever links).
2. In search mode, list one or more **cities**, and optionally a **category** and a keyword filter; in url mode, paste event, city or category links, each one deciding its own scope.
3. Optionally set the **price bounds** and switch on **Fetch event details** for the description, venue address, categories, session dates and ticket availability.
4. Set **Max items** to control run size and cost, then click **Start**.

**Browse a city:**

```json
{
  "mode": "search",
  "cities": ["new-york"],
  "maxItems": 20
}
```

**Narrow to a category and a price band:**

```json
{
  "mode": "search",
  "cities": ["new-york"],
  "category": "candlelight",
  "minPrice": 20,
  "maxPrice": 60,
  "maxItems": 20
}
```

**Browse a city with full event details:**

```json
{
  "mode": "search",
  "cities": ["london"],
  "fetchDetails": true,
  "maxItems": 10
}
```

**Paste Fever links (an event and a category):**

```json
{
  "mode": "url",
  "urls": [
    "https://feverup.com/m/653922",
    "https://feverup.com/en/new-york/candlelight"
  ],
  "maxItems": 10
}
```

Pasting a single event link returns its full detail fields (description, address, session dates) either way, since that page has to be read to identify the event; the details fee is only added when **Fetch event details** is switched on.

#### URL shapes (url mode)

| Shape | Example | Notes |
|---|---|---|
| City catalogue | `https://feverup.com/en/new-york` | Whole city catalogue. |
| City, www host | `https://www.feverup.com/en/london` | Same as the plain host. |
| City, other locale | `https://feverup.com/es/madrid` | Locales en, es, fr, it, pt, de. |
| Category | `https://feverup.com/en/new-york/candlelight` | Also `https://feverup.com/en/london/music-events`. |
| Category, trailing slash | `https://feverup.com/en/new-york/candlelight/` | Same scope. |
| Category with `?page=2` | `https://feverup.com/en/new-york/candlelight?page=2` | The site ignores the query, so this is the same scope and is never read as page 2. |
| Event | `https://feverup.com/m/653922` | Also with a tracking query such as `?utm_source=x`. |

Not supported, each logs a per-URL warning that names the reason and counts as an unresolved URL (never a silent zero): a locale-only page such as `https://feverup.com/en`, nested category paths such as `/en/new-york/candlelight/jazz`, and `/en/m/ID` (use `https://feverup.com/m/ID`).

**The default now scrapes one example per shape.** If you switch to url mode and leave the URLs field untouched, the actor reads the example URLs above (a few city and category pages and one event), up to your item limit, instead of nothing.

In search mode, `cities` and `category` accept plain names ("New York", "London", "Music Events") and Fever city codes (NYC, LON); Vienna and Washington DC resolve to Fever's own slugs `wien` and `washington`. A name that cannot be read fails the run with a clear message.

If you come from another Fever scraper, its input words work too: `city` (name, slug or code such as LON), `queryType` (`browse` is search mode, `event` reads one event) and `id` (a numeric event ID, same as pasting `https://feverup.com/m/ID`; when it is filled only that event is read and Mode and the sample URL list are ignored, unless `queryType` is `browse`). Its output names map onto ours: name is `title`, venue is `venueName`, price is `priceText`, numeric_price is `priceFrom`, cover_image is `imageUrl`, coordinates are `latitude` and `longitude`, start_time and end_time are `startDate` and `endDate`, city_code is `citySlug`, queryType is `rowType`. The site has no native sort or keyword parameter, so keyword and price filters apply to the rows the run reads.

#### Run it from your code

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/fever-com-scraper").call(run_input={"mode": "search", "cities": ["new-york"], "maxItems": 20})
for event in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(event["title"], event["priceFrom"], event["currency"])
```

JavaScript:

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/fever-com-scraper').call({ mode: 'search', cities: ['new-york'], maxItems: 20 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

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

#### Resume and recurring updates

- **Resume** (`resumeFromRunId`) continues one interrupted run: paste its run or dataset id and the actor skips every record id already collected there, so you don't pay twice. Every city page and every pasted URL is still read on each run (there is no page-by-page crawl to resume mid-page), so Resume saves the push and the charge for records already collected, not the read itself. A category page may still only reach its first window if the site's Load more control caps it, whether or not Resume is set.
- **Incremental mode** (`incrementalMode`) is for running the same search again and again, for example daily. Each record is classified `NEW`, `UPDATED` (with `changedFields`), `UNCHANGED` (suppressed and not billed unless `emitUnchanged` is on), `REAPPEARED` or `EXPIRED`. A record only turns `REAPPEARED` if it was previously marked absent, and that only ever happens after an earlier run had `emitExpired` on and completed a full, uncapped, non-resumed scan of every tracked city or category with none of its sources refused; `EXPIRED` follows that same rule and is never produced by default. A category page that only served a capped window of its catalogue (behind the site's Load more control) is never treated as a complete scan, so that run skips EXPIRED detection and says so in the log.
- Resume and Incremental mode do not mix on a state key that already has tracked records: the run stops with a message asking you to remove Resume or pick a different **State key**, so a resumed run never seeds a monitoring baseline from a partial dataset.
- `stateKey` names or shares the stored state. With incremental mode off, output is exactly as before.
- **What is compared:** every returned field (price from, original price, on-sale flag, discount, currency, dates, venue, description, categories, tickets available). Rating, rating count, image URL, scrape time and the carried-forward marker never decide UPDATED (they are still returned).
- **Ignore fields when detecting changes** (`ignoreFieldsForChanges`): list field names (or dotted paths such as `sessions.image`) that must never make a record UPDATED or appear in `changedFields`. Changing this list does not cause a one-time wave of UPDATED rows.
- **Change scope** (`changeScope`): `priceAndStock` makes only price, original price, on-sale flag, discount, currency and tickets available decide UPDATED. Default `all` is unchanged.
- **Compact UPDATED rows** (`compactUpdates`, off by default): UPDATED rows carry only the event id, URL, title, current price fields and `priceChanges` with old and new values. The event details charge is not applied to a compact row, since the details are not in it. NEW rows stay full.
- **Expire after N missed scans** (`expireAfterMissedScans`, default 1): with Emit expired, a record is marked EXPIRED only after that many consecutive complete scans miss it. EXPIRED means the event dropped out of the listing (sell-out, ended run or ranking change), not that it is proven unavailable.

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

Optionally pipe the scraped events 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 event, not the full JSON record. 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 event pages 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

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `mode` | string | `search` | `search` walks city catalogues, `url` processes the Fever URLs you paste. |
| `cities` | array | `["new-york"]` | City slugs to browse (search mode), for example `new-york`, `london`, `madrid`, `paris`, `milan`, `sao-paulo`. |
| `queryType` | string | (none) | Alternative mode word: `browse` is search mode, `event` reads one event (use with `id`). |
| `city` | string | (none) | One city by name, slug or code such as `LON`; when set it replaces `cities`, so only this city is scraped. |
| `id` | string | (none) | A numeric Fever event ID, same as pasting `https://feverup.com/m/ID`. When filled, only that event is read: Mode and the sample URL list are ignored (set `queryType` to `browse` to ignore it). |
| `locale` | string | `en` | Site language prefix for city pages: `en`, `es`, `fr`, `it`, `pt` or `de` (search mode). |
| `category` | string | (none) | Narrow every city walk to one category slug, for example `candlelight`, `music-events`, `exhibitions` or `food` (search mode). |
| `query` | string | (none) | Keep only rows whose title or categories contain this keyword (search mode). |
| `urls` | array | one example per supported shape (see the URL shapes table) | Fever event, city or category URLs to process (url mode). |
| `minPrice` | integer | (none) | Keep only events whose from-price is at least this amount, in the row's own currency. |
| `maxPrice` | integer | (none) | Keep only events whose from-price is at most this amount, in the row's own currency. |
| `maxReviewsPerEvent` | integer | `20` | With **Fetch event details** on, attaches up to this many of the newest guest reviews to each event (maximum 500, 0 turns them off). Reviews are included in the event details fee and add no separate charge; changes to the reviews list alone never mark a row UPDATED. |
| `fetchDetails` | boolean | `false` | Fetch each event's page for description, venue address with coordinates, categories, session dates and ticket availability. Charged once per record. |
| `maxItems` | integer | `20` | Stop after collecting this many records across all cities and URLs. `0` means unlimited. |
| `resumeFromRunId` | string | (none) | Continue one interrupted run: paste its run or dataset id to skip records already collected there. |
| `changeScope` | string | `all` | Incremental only: `priceAndStock` limits UPDATED to price and availability moves. |
| `compactUpdates` | boolean | `false` | Incremental only: slim UPDATED rows with `priceChanges`. |
| `expireAfterMissedScans` | integer | `1` | Incremental only: consecutive complete scans a record must miss before EXPIRED. |
| `ignoreFieldsForChanges` | array | empty | Incremental only: fields that never decide UPDATED. |
| `incrementalMode` | boolean | `false` | Turn on for recurring monitoring of the same search: later runs return only NEW, UPDATED and REAPPEARED records. |
| `stateKey` | string | (none) | Name this monitoring campaign, or deliberately share state across differently configured runs. |
| `emitUnchanged` | boolean | `false` | Also return (and bill) records that have not changed since the last run. |
| `emitExpired` | boolean | `false` | Also return (and bill) records that were tracked before but are no longer found, once a run has fully scanned the tracked search. |
| `mcpConnectors` | array | (none) | Optional: send a summary of each record to apps you authorized under Integrations. |
| `notionParentPageUrl` | string | (none) | Notion connector only: page under which event pages are created. |
| `maxNotifyListings` | integer | `50` | Cap on records written to each connector per run. Does not affect the dataset. |
| `proxy` | object | `{"useApifyProxy": true}` | Connection settings. Leave the default unless a run reports it could not read any results. |

### Output Example

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

```json
{
  "recordId": "9000001",
  "rowType": "event",
  "eventId": "9000001",
  "url": "https://feverup.com/m/9000001",
  "title": "Sample Concert Evening",
  "citySlug": "new-york",
  "locale": "en",
  "category": "candlelight",
  "priceFrom": 25,
  "priceText": "From 25.00 USD",
  "originalPrice": 30,
  "onSale": true,
  "discountPercent": 16.7,
  "currency": "USD",
  "priceType": "from",
  "startDate": "2026-11-01T19:00:00-04:00",
  "endDate": "2026-11-30T21:00:00-04:00",
  "venueName": "Sample Hall",
  "rating": 4.5,
  "ratingCount": 320,
  "isNew": false,
  "imageUrl": "https://feverup.com/images/sample-event.jpg",
  "description": "A candlelit evening of chamber music for all ages.",
  "venueAddress": "100 Sample Street, New York, 10001",
  "latitude": 40.0,
  "longitude": -74.0,
  "categories": ["Music", "Family"],
  "firstSessionDate": "2026-11-01T19:00:00-04:00",
  "lastSessionDate": "2026-11-30T20:30:00-04:00",
  "ticketsAvailable": true,
  "sessionsText": "Nov 1 - Nov 30",
  "scrapedAt": "2026-11-01T12:00:00Z",
  "changeType": "UPDATED",
  "changedFields": ["priceFrom", "originalPrice"],
  "firstSeenAt": "2026-10-01T12:00:00Z",
  "lastSeenAt": "2026-11-01T12:00:00Z"
}
```

### Plan Requirement

Datacenter connections are enough for Fever: no residential proxy is required, and the default Apify proxy setting works without any change. Fever pages were read successfully over datacenter connections without a block. If a connection is refused, the run retries on a backup connection and logs "Served over the backup connection (the default connection was unavailable)."

On an Apify free plan the proxy may be unavailable. The run then logs "The selected connection is unavailable to this run" and continues on a backup connection, where some pages may still be unavailable. If nothing at all could be read you get one of these failures: "The proxy connection was refused for this account, so no page could be read" (your plan does not include proxy access), "No results: residential proxies are unavailable on this run" (the backup connection also could not load the pages), or "Could not load any results page (the requests failed), so nothing was collected" (a connection problem, not an empty search; try again later). You can also supply your own proxy URLs under **Proxy configuration**.

### FAQ

#### How much does it cost?

You pay a one time actor start fee plus a fee per event record returned, and a separate event details fee (the `detail-enrichment` event, charged once per record at the end of the run) only for records returned with **Fetch event details** on and whose event page was successfully read. Guest reviews are part of that fee and add no further charge. The record fee is the `apify-default-dataset-item` event. The **Pricing** tab shows the current rates. Use **Max items** to cap the cost of any run.

#### Is it legal to scrape Fever?

This actor collects only publicly available event listing data. You are responsible for how you use it: follow feverup.com's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Event names, dates and prices are generally facts, but photos and descriptions may be subject to third-party rights.

#### Can I get only new or changed events 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, and unchanged ones are not billed unless you ask for them.

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

If the run collected zero records and any pasted URL could not be opened or read, the run fails with a clear connection message instead of returning a false "zero results", since a URL you explicitly asked for was never resolved. A run that collected zero records only because some city or category pages were refused, while others returned records or genuinely matched nothing, stays a success whose status message names what could not be read.

#### What happens to an event whose date has passed?

Fever itself stops listing an event on its city and category pages once it is no longer bookable. On a monitored search with **Incremental mode** and **Emit expired records** both on, the next run that completes a full, uncapped scan of the tracked scope marks that event `EXPIRED`. If it ever reappears on the site later, it comes back as `REAPPEARED`, never as a fresh `NEW` record.

#### 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.

### 🔗 More scrapers you might like

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

<table>
<tr><td>🧩 <a href="https://apify.com/abotapi/viagogo-events-scraper"><b>Viagogo Scraper</b></a><br>Scrape Viagogo events by artist, production, venue, city, category, or URL. Extract event...</td><td>⚽ <a href="https://apify.com/abotapi/eventim-de-event-scraper"><b>Eventim Scraper</b></a><br>Scrape CTS Eventim Germany and EU event catalogue: concerts, festivals, comedy, sports...</td></tr>
<tr><td>🧩 <a href="https://apify.com/abotapi/songkick-concert-calendar-scraper"><b>Songkick Scraper</b></a><br>Scrape Songkick concert and event calendars: upcoming and past dates, venues, cities...</td><td>🛒 <a href="https://apify.com/abotapi/seatgeek-events-scraper"><b>SeatGeek Scraper</b></a><br>Scrape SeatGeek events with ticket price ranges (lowest, highest, average, median)...</td></tr>
<tr><td>✈️ <a href="https://apify.com/abotapi/pollstar-concert-tour-scraper"><b>Pollstar Scraper</b></a><br>Scrape Pollstar upcoming concerts and tour dates: play date, venue with full address and...</td><td>🧩 <a href="https://apify.com/abotapi/ticketmaster-event-discovery"><b>Ticketmaster Scraper</b></a><br>Discover and scrape Ticketmaster events across the US, UK, Australia and Canada. Search...</td></tr>
</table>

👉 [Browse all abotapi scrapers](https://apify.com/abotapi)

### 💬 Support

- 🐞 **Found a bug or a missing field?** Open a ticket on the [Issues tab](https://apify.com/abotapi/fever-com-scraper/issues/open). 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.

# Actor input Schema

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

How to start the scrape. 'search' walks city catalogues. 'url' processes the Fever URLs you paste: an event URL is fetched as a single event, and a city or category URL is read like a search, its own city and category deciding the scope. The filters below apply to every walk in both modes; a pasted event URL is the one exception and returns that single event in full.

## `cities` (type: `array`):

City slugs to browse, for example 'new-york', 'london', 'madrid', 'paris', 'milan', 'sao-paulo'. Each city is scraped independently. Search mode only: in URL mode the scope is read out of each pasted URL instead. Defaults to New York when empty. Plain names ('New York', 'London') and Fever codes (NYC, LON) are accepted; an unreadable name fails the run loudly.

## `queryType` (type: `string`):

Alias for Mode using the vocabulary of other Fever scrapers: 'browse' means mode 'search', 'event' means reading the single event in 'Event ID'. Leave empty to use Mode.

## `city` (type: `string`):

Single city as a name, slug or Fever code (LON, NYC, PAR). In search mode it replaces the Cities list, so only this city is scraped.

## `locale` (type: `string`):

The site language prefix for city pages: en, es, fr, it, pt or de. Unknown values fall back to en. Search mode only: in URL mode the pasted URL carries its own language.

## `category` (type: `string`):

Narrow every city walk to one category slug, for example 'candlelight', 'music-events', 'exhibitions' or 'food'. Leave empty to browse the whole city catalogue. Search mode only: in URL mode a pasted category URL decides its own scope.

## `query` (type: `string`):

Only keep events whose title or categories contain this text, for example 'candlelight' or 'jazz'. The site has no keyword parameter, so it is applied to the rows this run reads. Search mode only: in URL mode the pasted URL decides its own scope.

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

Paste event URLs (https://feverup.com/m/653922), city URLs (https://feverup.com/en/new-york) or category URLs (https://feverup.com/en/london/candlelight). A pasted URL decides its own scope. The price bounds below narrow what the walks read; a pasted event URL is the exception and returns that single event in full. Trailing slashes, a www host, other locales (en, es, fr, it, pt, de) and tracking or ?page query strings are accepted (the query is ignored). Locale-only pages (/en), nested category paths and /en/m/ID are not supported and log a per-URL warning.

## `id` (type: `string`):

Numeric Fever event ID, for example 653922. Reads that single event in full, like pasting https://feverup.com/m/653922. When it is filled, only this event is read: the Mode and Fever URLs fields (including the sample URL list) are ignored. Set Query type to 'browse' to ignore the ID and browse by city instead.

## `minPrice` (type: `integer`):

Only keep events whose from-price is at least this amount, in the row's own currency. The site has no parameter for this, so it is applied to the rows this run reads. Applies to every walk in both modes; a pasted event URL is the exception and returns that single event in full.

## `maxPrice` (type: `integer`):

Only keep events whose from-price is at most this amount, in the row's own currency. The site has no parameter for this, so it is applied to the rows this run reads. Applies to every walk in both modes; a pasted event URL is the exception and returns that single event in full.

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

Fetch each event's page for the description, the venue address with coordinates, the categories, the session dates and the ticket availability. Slower, and charged once per record. Leave off for a fast crawl: identity, from-price, venue, dates and rating are included either way.

## `maxReviewsPerEvent` (type: `integer`):

With Fetch event details on, attach up to this many of the newest guest reviews (reviewer, rating, date, text, helpful votes) to each event, following the site's own pages. 0 turns reviews off. Capped at 500 per event. Reviews add no separate fee.

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

The single cap on this run: stop after collecting this many records across all cities and URLs. A listing page serves what the site renders in one read (city pages render the catalogue; category pages serve a capped window per grid with the rest behind the site's Load more control), so there is no page cap. Set 0 for unlimited.

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

Leave the default for the cheapest run. The site serves ordinary shared connections, so the default pool is enough. Change it only if a run reports that it could not read any results.

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

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

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

Turn this on for daily or weekly recurring monitoring of the same search, for example a price watch. The first run returns everything matching as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED records. COMPARED between runs: every returned field (price from, original price, on-sale flag, discount, currency, dates, venue, description, categories, tickets available and the rest). EXCLUDED because they drift without the event changing: rating, rating count, image URL, scrape time and the carried-forward marker; they are still returned. Price moves and new dates ARE reported as UPDATED: on an events catalogue they are the signal, not noise. To react only to price and availability, set Change scope to price and availability. Turn on Emit unchanged or Emit expired only when you also want those rows returned (and billed). State is kept separately per city, URL and filter 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 cities, URLs and filters, so two different searches never mix state.

## `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 specifically want a 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: not when Max items capped it, not when Resume was used, not when the run was refused, and not when a category page served a capped window of its catalogue (the run says Partial results instead). This returns, and bills, extra synthetic rows, so leave it off unless you need expiry tracking.

## `changeScope` (type: `string`):

All fields (default): any change in a returned field makes a record UPDATED. Price and availability: only price, original price, on-sale flag, discount, currency and tickets available decide UPDATED; description, venue, dates and artwork changes never create a billable row. Rows are still returned in full.

## `compactUpdates` (type: `boolean`):

Off by default. When on, UPDATED rows carry only the event id, URL, title, current price fields and a priceChanges object with old and new values. The event-page details fee is not charged for a compact row because the fields it covers are not in the row. NEW rows stay full.

## `expireAfterMissedScans` (type: `integer`):

Used only with Emit expired. A record is marked EXPIRED only after it is missing from this many CONSECUTIVE complete scans (default 1). EXPIRED means the event dropped out of the listing, which can be a sell-out, an ended run or a ranking change; it is not proof the event is unavailable.

## `ignoreFieldsForChanges` (type: `array`):

Field names that never decide UPDATED and never appear in changedFields, for example description or venueName. They are still returned in the row. Rating, rating count and image URL are always ignored. Dotted paths like sessions.image drop that key inside every element of a list.

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

Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API and Integrations, then select it here. Notion gets a page per record; other connectors get a best-effort write or digest. Each connector receives a condensed summary per record, not the full record; the complete record always stays in the dataset. Leave empty to skip; this 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 record pages are created. Required to enable the Notion export; ignored by other connectors.

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

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

## Actor input object example

```json
{
  "mode": "search",
  "cities": [
    "new-york"
  ],
  "locale": "en",
  "urls": [
    "https://feverup.com/en/new-york",
    "https://www.feverup.com/en/london",
    "https://feverup.com/es/madrid",
    "https://feverup.com/en/new-york/candlelight",
    "https://feverup.com/en/london/music-events",
    "https://feverup.com/m/653922"
  ],
  "fetchDetails": false,
  "maxReviewsPerEvent": 20,
  "maxItems": 20,
  "proxy": {
    "useApifyProxy": true
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "changeScope": "all",
  "compactUpdates": false,
  "expireAfterMissedScans": 1,
  "maxNotifyListings": 50
}
```

# Actor output Schema

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

No description

## `detail` (type: `string`):

No description

## `changes` (type: `string`):

No description

## `reviews` (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",
    "cities": [
        "new-york"
    ],
    "locale": "en",
    "urls": [
        "https://feverup.com/en/new-york",
        "https://www.feverup.com/en/london",
        "https://feverup.com/es/madrid",
        "https://feverup.com/en/new-york/candlelight",
        "https://feverup.com/en/london/music-events",
        "https://feverup.com/m/653922"
    ],
    "fetchDetails": false,
    "maxReviewsPerEvent": 20,
    "maxItems": 20,
    "proxy": {
        "useApifyProxy": true
    },
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/fever-com-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",
    "cities": ["new-york"],
    "locale": "en",
    "urls": [
        "https://feverup.com/en/new-york",
        "https://www.feverup.com/en/london",
        "https://feverup.com/es/madrid",
        "https://feverup.com/en/new-york/candlelight",
        "https://feverup.com/en/london/music-events",
        "https://feverup.com/m/653922",
    ],
    "fetchDetails": False,
    "maxReviewsPerEvent": 20,
    "maxItems": 20,
    "proxy": { "useApifyProxy": True },
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/fever-com-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",
  "cities": [
    "new-york"
  ],
  "locale": "en",
  "urls": [
    "https://feverup.com/en/new-york",
    "https://www.feverup.com/en/london",
    "https://feverup.com/es/madrid",
    "https://feverup.com/en/new-york/candlelight",
    "https://feverup.com/en/london/music-events",
    "https://feverup.com/m/653922"
  ],
  "fetchDetails": false,
  "maxReviewsPerEvent": 20,
  "maxItems": 20,
  "proxy": {
    "useApifyProxy": true
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false
}' |
apify call abotapi/fever-com-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/fever-com-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/L3ZDfhCeVE4Yk5qt2/builds/55qGHfxpEFSwyW1s0/openapi.json
