# Wego Scraper - MENA Hotel Deals, Rates & Reviews (`abotapi/wego-com-scraper`) Actor

Scrape Wego hotels by city or search URL. Get rates, providers, booking links, coordinates, scores, images and property details. Optionally fetch guest review text, ratings, dates and public author details.

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

## Pricing

from $1.50 / 1,000 hotel 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

## Wego Hotel Scraper

Find Wego hotel rates by city and stay dates, or paste hotel search links. Each dataset row contains a hotel, its cheapest available rate for that stay, and links to the hotel and booking offer. Optional profile and guest review fields add more detail when you need them.

### Why This Scraper?

- **Three ways in.** Search by city and stay dates, or paste a Wego search, city, hotel or hotel id link.
- **Rates you can compare.** Quoted amounts, taxes, providers, room types and cancellation terms on every row.
- **Location and reputation.** Star class, coordinates, review scores and the image URLs available with each result.
- **Optional hotel profiles.** Contact details, amenities, policies and property information with `fetchDetails`, which is on by default.
- **Optional guest reviews.** Review text, ratings, dates and public author details with `fetchReviews`.
- **Built for schedules.** Track changes across runs with Incremental mode, pick which fields count as a change with `ignoreFieldsForChanges`, or resume an interrupted run without repeating earlier rows.

### Use Cases

- **Travel deal sites and content teams:** pull the cheapest currently quoted rate for popular MENA cities to publish rate roundups and deal alerts.
- **Rate shoppers and revenue managers:** watch a specific hotel's quoted rate across a stay window with Incremental mode, and get notified only when the price actually moves.
- **OTAs and metasearch aggregators:** mirror Wego's own provider, room type and cancellation terms for a city into your own comparison tool or dataset.
- **Corporate and group travel planners:** shortlist hotels by star class, price band and free cancellation, then add contact details, amenities and policies with `fetchDetails`.
- **Market researchers:** build a dataset of prices, star classes and review scores across MENA cities for hospitality market analysis.
- **Review and reputation tools:** collect guest review text, ratings and public author details per hotel with `fetchReviews`.

### Data You Get

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

| Field | Example |
|---|---|
| `hotelId` | `000001` |
| `name` | `Sample City Hotel` |
| `url` | Wego hotel page link |
| `star` | `4` |
| `cityName` | `Dubai` |
| `latitude` | `25.0000` |
| `longitude` | `55.0000` |
| `imageUrl` | Primary hotel image URL |
| `imageUrls` | Every image URL available with the result |
| `imagesCount` | `50`, the reported image count, which may exceed available URLs |
| `reviewScore` | `85` out of 100 |
| `reviewCount` | `100` |
| `reviewBreakdown` | Scores and counts by guest group |
| `priceAmount` | `180` in the quoted currency |
| `priceCurrency` | `USD` |
| `totalAmountUsd` | `180` |
| `taxAmountUsd` | `20` |
| `providerCode` | `example-provider` |
| `roomType` | `Standard room` |
| `freeCancellation` | `true` |
| `address` | Available with `fetchDetails` |
| `amenities` | Available with `fetchDetails` |
| `reviews` | Guest reviews when `fetchReviews` is on |
| `reviewsFetched` | Number of guest reviews returned for this hotel |

Extra fields on each row include `providerHotelId`, `roomIds`, `usualPrice`, `similarHotelIds`, `nameI18n`, `hotelSocialProof`, `rateSocialProof` and the full `aiReviews` summaries.

The Console dataset has five views: Results, Rate details, Hotel profile, Guest reviews and Changes (incremental). A run summary is stored under the `OUTPUT` key.

### How to Use

#### Search a city

**Search a city:**

```json
{
  "mode": "search",
  "locations": ["Dubai"],
  "checkIn": "2026-10-01",
  "checkOut": "2026-10-03",
  "maxItems": 20
}
```

#### Compare several cities with filters

**Compare several cities with filters:**

```json
{
  "mode": "search",
  "locations": ["Dubai", "Doha"],
  "checkIn": "2026-10-01",
  "checkOut": "2026-10-03",
  "starRatings": ["4", "5"],
  "maxPriceUsd": 300,
  "maxItems": 30
}
```

#### Fetch hotel profiles and guest reviews

**Fetch hotel profiles and guest reviews:**

```json
{
  "mode": "search",
  "locations": ["Dubai"],
  "checkIn": "2026-10-01",
  "checkOut": "2026-10-03",
  "fetchDetails": true,
  "fetchReviews": true,
  "maxReviewsPerHotel": 20,
  "maxItems": 5
}
```

#### Use hotel search links

**Use hotel search links:**

```json
{
  "mode": "url",
  "urls": ["https://www.wego.com/en/hotels/searches/dxb/2026-12-01/2026-12-03?guests=2"],
  "maxItems": 20
}
```

| Link shape | Example | Scope |
|---|---|---|
| Search page | `https://www.wego.com/en/hotels/searches/dxb/2026-12-01/2026-12-03?guests=2` | That city, those dates and guests. Past dates move to the next upcoming week with a log warning. A trailing hotel id keeps only that hotel. |
| City page | `https://www.wego.com/hotels/united-arab-emirates/dubai` | That city, default stay window. |
| Hotel page | `https://www.wego.com/hotels/united-arab-emirates/dubai/le-meridien-mina-seyahi-beach-resort-waterpark-690184` | That hotel only, default stay window. |
| Hotel id link | `https://www.wego.com/en/hotels/770060` | That hotel only, default stay window. |

A URL-mode run with `urls` left untouched scrapes one example per shape (city page, hotel page, hotel id link). The old default was a single Dubai search link with fixed past dates; the default now carries no dates, so it no longer returns an empty result. Sort and order query parameters in a pasted link are not applied; use the sort input. Other Wego domains and language prefixes are accepted. A link that cannot be read is skipped with a log warning. Results and prices depend on availability for the selected stay. `imageUrls` contains URLs supplied with the result; `imagesCount` is a separate reported count.

Each hotel is tracked by its own id within a run, not by the stay dates or guest count in the link that found it. If you paste two search links for the same city with different dates or guest counts, the second link's row for a hotel the first link already found in that run is dropped as a duplicate, even though its rate is for a different stay. For example, one link for Dubai in October and a second link for Dubai in November in the same run will only return the October rate for any hotel both links find. Run separate actor runs when you need rates for the same city across more than one stay window.

#### Run it from your code

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/wego-com-scraper").call(run_input={
    "mode": "search",
    "locations": ["Dubai"],
    "checkIn": "2026-10-01",
    "checkOut": "2026-10-03"
})
for hotel in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(hotel["name"], hotel["priceAmount"], hotel["priceCurrency"])
```

JavaScript:

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/wego-com-scraper').call({
  mode: 'search',
  locations: ['Dubai'],
  checkIn: '2026-10-01',
  checkOut: '2026-10-03'
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

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

### Input Parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `search` | Search by city or use `url` for hotel search links. |
| `locations` | array | `Dubai` | City names in search mode. |
| `checkIn` | string | about a week from today | Stay start in search mode. |
| `checkOut` | string | two nights after check-in | Stay end in search mode. |
| `rooms` | integer | `1` | Rooms in search mode. |
| `adults` | integer | `2` | Adults in search mode. |
| `currency` | string | `USD` | Currency for quoted rates. |
| `urls` | array | three example links | Wego hotels links in URL mode: search, city, hotel or hotel id. |
| `starRatings` | array | none | Keep selected star classes. |
| `minPriceUsd` | integer | none | Minimum quoted price in USD. |
| `maxPriceUsd` | integer | none | Maximum quoted price in USD. |
| `freeCancellationOnly` | boolean | `false` | Keep offers with free cancellation. |
| `sortBy` | string | `popularity` | Order returned hotels. |
| `fetchDetails` | boolean | `true` | Add the hotel profile. One enrichment event per committed profile. |
| `fetchReviews` | boolean | `false` | Add guest review records. |
| `maxReviewsPerHotel` | integer | `20` | Review cap per hotel; `0` skips review reads. |
| `maxItems` | integer | `20` | Maximum hotel rows; `0` means unlimited. |
| `maxPages` | integer | `0` | Maximum feed polls per city; `0` means no user-set poll limit; a hard cap of 30 polls per city always applies. |
| `resumeFromRunId` | string | none | Continue from an earlier run or dataset. |
| `incrementalMode` | boolean | `false` | Return changes for a recurring search. |
| `stateKey` | string | none | Optional name for the recurring search state. |
| `emitUnchanged` | boolean | `false` | Also return unchanged hotels. |
| `emitExpired` | boolean | `false` | Also return hotels absent after a complete scan. |
| `ignoreFieldsForChanges` | array | `[]` | Field names (or dotted nested paths such as `images.url`) that never make a row UPDATED and never appear in `changedFields`. Fields stay in the output. Incremental mode only. |
| `changeScope` | string | `all` | `priceAndStock` compares only the rate fields (price, tax, currency, free cancellation, rooms left). |
| `compactUpdates` | boolean | `false` | UPDATED and EXPIRED rows come back short (ids, current price, old and new values in `priceChanges`); they carry no profile or review fields, so they add no detail-enrichment and no review units. Each row holds one cheapest rate, so `variantChanges` is always empty. |
| `expireAfterMissedScans` | integer | `1` | With `emitExpired`, mark EXPIRED only after this many consecutive complete scans missed the hotel. EXPIRED means the hotel left the results, not necessarily that it is unavailable. |
| `mcpConnectors` | array | empty | Optional connector IDs for an export. |
| `notionParentPageUrl` | string | none | Parent page for a Notion export. |
| `maxNotifyListings` | integer | `50` | Maximum rows sent through connectors. |
| `proxy` | object | Apify default | Connection configuration. |

The hotel record is charged once per dataset row. A successful profile read adds one Hotel detail enrichment event. When guest reviews are enabled, each started block of 10 fetched reviews adds one more enrichment event on a hotel row that is returned: 1-10 reviews add one event, 11-20 add two. Empty or failed review reads and unchanged rows suppressed by incremental mode add no review event.

For recurring monitoring, keep the same city, stay dates and filters. The first incremental run returns NEW hotels; later runs return changes. `emitUnchanged` and `emitExpired` can add billed rows. Resume continues a specific previous run and skips rows it already collected.

Each run applies `maxItems` in the site's own display order for that stay window before sorting hotels into NEW, UPDATED, UNCHANGED or EXPIRED. On a city with more hotels than its share of `maxItems`, a hotel ranked below that cutoff is not scanned at all that run, so a genuine change on that specific hotel is not detected until it rises within the cutoff on a later run. Raise `maxItems` (or set it to `0`) for a scope you monitor with incremental mode, especially a large city, so every tracked hotel is scanned each run.

With `emitExpired` on, every city or link in one input shares a single EXPIRED check. If a later run cannot look up one of those cities or links (the lookup is refused or finds no match that time) while the others scan completely, the hotels tracked for that city are marked EXPIRED even though they were not checked. For example, a Dubai and Doha watch whose Doha lookup fails once reports every tracked Doha hotel as EXPIRED. When you rely on EXPIRED rows, schedule one city or search link per task: a single-city run whose lookup fails skips EXPIRED detection instead.

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

Optionally select authorized connectors with `mcpConnectors`. Set `notionParentPageUrl` for Notion and use `maxNotifyListings` to cap exported rows. The complete records remain in the dataset.

### Output Example

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

```json
{
  "recordId": "000001",
  "hotelId": 1,
  "rowType": "hotel",
  "name": "Sample City Hotel",
  "url": "https://www.wego.com/en/hotels/searches/dxb/2026-10-01/2026-10-03/1",
  "star": 4,
  "cityCode": "DXB",
  "cityName": "Dubai",
  "latitude": 25.0,
  "longitude": 55.0,
  "imageUrl": "https://zen.wego.com/hotelz/000/00000000/0000000000.jpeg",
  "imageUrls": ["https://zen.wego.com/hotelz/000/00000000/0000000000.jpeg"],
  "imagesCount": 10,
  "reviewScore": 85,
  "reviewCount": 100,
  "priceAmount": 180,
  "priceCurrency": "USD",
  "priceUsd": 180,
  "providerCode": "example-provider",
  "roomType": "Standard room",
  "freeCancellation": true,
  "address": "Sample street, Dubai",
  "amenities": ["Wi-Fi", "Parking"],
  "reviewsFetched": 1,
  "reviews": [{"reviewId": "review-0001", "rating": 8, "comments": [{"type": "pros", "comment": "Comfortable room"}], "postedAt": "2026-01-01", "authorName": "Guest Name"}],
  "changeType": "NEW",
  "changedFields": [],
  "firstSeenAt": "2026-01-01T00:00:00Z",
  "lastSeenAt": "2026-01-01T00:00:00Z"
}
```

The sample shows optional profile and guest review fields together. Search-only runs omit profile fields, and reviews are included only when enabled.

### Plan Requirement

An Apify account is needed to run the actor. The default Apify proxy connection is enough: the data routes were probed on the standard shared pool and no residential proxy is required. If you paste your own proxy configuration it is always used.

If the connection is refused for your account, the run logs one of these messages and does not return an empty dataset as if nothing matched:

- "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required."
- "No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested Wego pages."
- "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search."

When the default connection is unavailable but a backup connection serves the pages, the log notes "Served over the backup connection (the default connection was unavailable)." and the run continues.

Choose review and detail options based on the data you need; the input shows the charges associated with each option.

### FAQ

#### How much does it cost?

You pay for the Actor start event, one Hotel record event per dataset row, and one Hotel detail enrichment event for a successful profile read or a started block of 10 committed guest reviews. Compact update rows add no detail enrichment events. The **Pricing** tab shows the current rates. Use **Max items** to cap the cost of any run.

#### Is it legal to scrape Wego?

This actor collects only publicly available hotel search data. You are responsible for how you use it: follow Wego's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Hotel rates and availability change constantly and are not guaranteed once collected.

#### Can I get only new or changed hotel rates on a schedule?

Yes. Schedule the actor from the **Schedules** tab and turn on **Incremental mode**. Later runs of the same city, stay dates and filters then return only NEW, UPDATED and REAPPEARED hotels, and unchanged ones are not billed unless **Emit unchanged** is on.

#### What is the difference between Resume and Incremental mode?

Resume continues one specific interrupted run: paste its run or dataset ID and this run skips every record that run already collected. Incremental mode is for running the same search again and again (for example daily) and returning only what changed since the last run. Once a scope already has saved incremental state, adding Resume on top is refused; use Resume alone to finish an interrupted run, then let incremental mode continue from its own saved state next time.

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

If every request to the source was refused, the run stops with a clear message so "no hotels for this search" is never confused with "nothing could be read". Run it again in a few minutes, or change the Proxy configuration. If some cities or URLs served while others were refused, the run succeeds and the run log names each refused city or URL; when nothing was returned at all, the status message also names the refused count.

#### Can I paste multiple search links for the same city with different dates?

You can, but each hotel is tracked by its own id for the run, not by the dates or guest count in the link that found it. If two pasted links cover the same city with different stay dates or guest counts, the second link's row for a hotel the first link already found in that run is dropped as a duplicate, even though its rate is for a different stay. Run separate actor runs when you need rates for the same city across more than one stay window.

#### Why didn't Incremental mode report a change I know happened?

Each run applies **Max items** in the site's own display order before classifying hotels, so on a city or search larger than its share of Max items, a hotel ranked below that cutoff is not scanned that run at all. A genuine price or detail change on that specific hotel is only detected once it rises within the cutoff on a later run. Raise Max items, or set it to `0`, for any scope you monitor with Incremental mode.

#### Why were all hotels in one city marked EXPIRED at once?

With **Emit expired** on, all cities or links in one input share one EXPIRED check. If a run could not look up one of them (a refused or empty lookup) while the others scanned completely, that city's tracked hotels are reported as EXPIRED even though they were not checked. Schedule one city or search link per task when you rely on EXPIRED rows; a single-city run whose lookup fails skips EXPIRED detection instead.

#### 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 hotel rows into Notion, Linear or Airtable.

### 🔗 Want more travel data?

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

<table>
<tr><td>🏨 <a href="https://apify.com/abotapi/trip-com-scraper"><b>Trip.com Hotels, Rooms &amp; Reviews Scraper</b></a><br>Pull structured hotel listings from trip.com with prices, room types, amenities...</td><td>🏨 <a href="https://apify.com/abotapi/booking-com-scraper"><b>Booking.com Scraper</b></a><br>Scrape booking.com hotels, apartments, villas and hostels. Search any destination with...</td></tr>
<tr><td>🏨 <a href="https://apify.com/abotapi/expedia-universal-scraper"><b>Expedia Hotels Scraper</b></a><br>Scrape Expedia.com hotel listings and reviews for any destination. Extract prices...</td><td>🏨 <a href="https://apify.com/abotapi/rakuten-travel-scraper"><b>Rakuten Travel Scraper</b></a><br>Scrape Rakuten Travel, Japan's largest domestic hotel-booking site, by prefecture...</td></tr>
<tr><td>🏨 <a href="https://apify.com/abotapi/yanolja-com-scraper"><b>Yanolja Scraper</b></a><br>Scrape Yanolja (NOL), Korea's largest accommodations marketplace, by region or URL. Every...</td><td>🏨 <a href="https://apify.com/abotapi/klook-activities-scraper"><b>Klook Scraper</b></a><br>Scrape Klook activities, tours, attractions and travel experiences from search pages or...</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/wego-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' runs the site's own hotel metasearch for the cities and stay window you set. 'url' processes the Wego hotels search URLs you paste: each URL's own path decides the city and dates, so the search-mode fields below do not apply there.

## `locations` (type: `array`):

One or more city names, for example 'Dubai', 'Makkah', 'Cairo', 'Doha', 'Abu Dhabi'. Each name is matched against the site's own place search; a name with no match is skipped with a warning, never invented. Search mode only: in URL mode the pasted URL decides its own scope.

## `checkIn` (type: `string`):

Stay window start, YYYY-MM-DD. Defaults to about a week from today when left empty. Search mode only.

## `checkOut` (type: `string`):

Stay window end, YYYY-MM-DD. Must be after the check-in date; defaults to two nights after check-in when left empty. Search mode only.

## `rooms` (type: `integer`):

Number of rooms to price, 1 to 4. Rates are quoted per room for the whole stay. Search mode only.

## `adults` (type: `integer`):

Adult guests per room, 1 to 8. Search mode only.

## `currency` (type: `string`):

Currency the rates are quoted in. The USD-converted price is always included on every row, so currency only changes the display values. Search mode only.

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

Paste Wego hotels links: a search page like https://www.wego.com/en/hotels/searches/dxb/2026-12-01/2026-12-03?guests=2 (a search page with past dates is moved to the next upcoming week, with a warning), a city page, a hotel page, or a bare hotel id link. City and hotel links use the default stay window. Sort and order query parameters in a pasted link are not applied; use the sort input. Multi-URL supported; each is walked independently.

## `starRatings` (type: `array`):

Keep only hotels of these star classes. Empty means every class. Applied to the rows this run reads. Applies in BOTH modes.

## `minPriceUsd` (type: `integer`):

Only keep rows whose rate is at least this many US dollars for the whole stay. Applied to the rows this run reads. Applies in BOTH modes.

## `maxPriceUsd` (type: `integer`):

Only keep rows whose rate is at most this many US dollars for the whole stay. Applied to the rows this run reads. Applies in BOTH modes.

## `freeCancellationOnly` (type: `boolean`):

Keep only rows whose quoted rate carries a free-cancellation window in the source's own terms. Applied to the rows this run reads. Applies in BOTH modes.

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

Arranges the rows this run collected, after they are read. 'As the site streamed them' keeps the source's own display order for your stay window. This is a local tidy up of one run's output, not a catalogue-wide ordering. Applies in BOTH modes.

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

Read each hotel's own profile for the complete record: address, phone, email, website, description, named amenities, check-in and check-out times, room and floor counts, payment options and review highlights. The feed row already carries name, star class, coordinates, review score, cheapest rate, provider, room type, board basis and free-cancellation terms. Turning this on adds the Hotel detail enrichment charge per record actually enriched this run.

## `fetchReviews` (type: `boolean`):

Optionally read the latest guest reviews for each hotel. Off by default. The existing Hotel detail enrichment event adds one unit per started block of 10 reviews returned on a committed hotel row. Works with Fetch hotel details on or off; no review charge for zero reviews, failed reads or suppressed incremental rows.

## `maxReviewsPerHotel` (type: `integer`):

Maximum guest reviews to collect for each hotel when Fetch guest reviews is on. Reviews are read 10 at a time; 1-10 reviews add one enrichment unit, 11-20 add two, and so on. Set 0 to skip review reads.

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

The single cap on this run: stop after collecting this many records across all cities and URLs. Set 0 for unlimited.

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

Safety bound on how many times to re-poll the streaming results feed per city while it fills in. Leave empty (0) to use the built-in ceiling: a hard cap of 30 polls per city always applies, so the run stops when the feed reports it is done, at Max items, or after 30 polls, whichever comes first.

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

Leave the default. Every read route on this source answers plain JSON to the standard shared pool, so the cheapest connection already works.

## `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 scope, for example a city rate watch. The first run returns everything matching as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED records. What is compared: every output field of the hotel, including the cheapest rate (price, tax, currency, free cancellation, rooms left), so a rate move IS reported as UPDATED. What is excluded: the booking deep link and the scrape timestamp (they change on every run), plus any field you list in Ignore fields when detecting changes. 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 scopes 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 scope: not when Max items capped it, not when Resume was used, and not when the run was refused. This returns, and bills, extra synthetic rows, so leave it off unless you need expiry tracking.

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

All fields (default) compares the whole hotel record. Price and availability only compares just the rate fields (price, tax, currency, free cancellation, rooms left), so descriptions, photos and review counts never create an UPDATED row. Changing the scope changes the automatic state key unless you set State key.

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

Off by default. Turn on to return UPDATED and EXPIRED rows as short rows: ids, current price, priceChanges with old and new values, and per-rate changes. NEW rows stay complete. Compact rows carry no reviews, so they add no review charge.

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

With Emit expired on, a hotel is marked EXPIRED only after it was missing from this many consecutive complete scans. Default 1 expires at once. EXPIRED means the hotel dropped out of the results, which can be a listing change or a real removal; use the price and availability fields to judge availability.

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

Field names that never make a row UPDATED and never appear in changedFields (the fields stay in the output). Use a top-level name such as reviewCount, or a dotted path such as images.url to ignore one key inside every element of a nested list. Applies to incremental mode only.

## `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 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",
  "locations": [
    "Dubai"
  ],
  "rooms": 1,
  "adults": 2,
  "currency": "USD",
  "urls": [
    "https://www.wego.com/hotels/united-arab-emirates/dubai",
    "https://www.wego.com/hotels/united-arab-emirates/dubai/le-meridien-mina-seyahi-beach-resort-waterpark-690184",
    "https://www.wego.com/en/hotels/770060",
    "https://www.wego.com/en/hotels/searches/dxb/2026-11-20/2026-11-22?guests=2",
    "https://www.wego.com/en/hotels/searches/dubai/2026-11-20/2026-11-22?guests=2",
    "https://www.wego.com/ar/hotels/searches/dxb/2026-11-20/2026-11-22?guests=2",
    "https://www.wego.com/en/hotels/searches/dxb/2026-11-20/2026-11-22/690184?guests=2"
  ],
  "freeCancellationOnly": false,
  "sortBy": "popularity",
  "fetchDetails": true,
  "fetchReviews": false,
  "maxReviewsPerHotel": 20,
  "maxItems": 20,
  "maxPages": 0,
  "proxy": {
    "useApifyProxy": true
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "changeScope": "all",
  "compactUpdates": false,
  "expireAfterMissedScans": 1,
  "ignoreFieldsForChanges": [],
  "maxNotifyListings": 50
}
```

# Actor output Schema

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

No description

## `rate-details` (type: `string`):

No description

## `profile` (type: `string`):

No description

## `reviews` (type: `string`):

No description

## `changes` (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",
    "locations": [
        "Dubai"
    ],
    "rooms": 1,
    "adults": 2,
    "currency": "USD",
    "urls": [
        "https://www.wego.com/hotels/united-arab-emirates/dubai",
        "https://www.wego.com/hotels/united-arab-emirates/dubai/le-meridien-mina-seyahi-beach-resort-waterpark-690184",
        "https://www.wego.com/en/hotels/770060",
        "https://www.wego.com/en/hotels/searches/dxb/2026-11-20/2026-11-22?guests=2",
        "https://www.wego.com/en/hotels/searches/dubai/2026-11-20/2026-11-22?guests=2",
        "https://www.wego.com/ar/hotels/searches/dxb/2026-11-20/2026-11-22?guests=2",
        "https://www.wego.com/en/hotels/searches/dxb/2026-11-20/2026-11-22/690184?guests=2"
    ],
    "freeCancellationOnly": false,
    "sortBy": "popularity",
    "fetchDetails": true,
    "fetchReviews": false,
    "maxReviewsPerHotel": 20,
    "maxItems": 20,
    "proxy": {
        "useApifyProxy": true
    },
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "compactUpdates": false,
    "ignoreFieldsForChanges": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/wego-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",
    "locations": ["Dubai"],
    "rooms": 1,
    "adults": 2,
    "currency": "USD",
    "urls": [
        "https://www.wego.com/hotels/united-arab-emirates/dubai",
        "https://www.wego.com/hotels/united-arab-emirates/dubai/le-meridien-mina-seyahi-beach-resort-waterpark-690184",
        "https://www.wego.com/en/hotels/770060",
        "https://www.wego.com/en/hotels/searches/dxb/2026-11-20/2026-11-22?guests=2",
        "https://www.wego.com/en/hotels/searches/dubai/2026-11-20/2026-11-22?guests=2",
        "https://www.wego.com/ar/hotels/searches/dxb/2026-11-20/2026-11-22?guests=2",
        "https://www.wego.com/en/hotels/searches/dxb/2026-11-20/2026-11-22/690184?guests=2",
    ],
    "freeCancellationOnly": False,
    "sortBy": "popularity",
    "fetchDetails": True,
    "fetchReviews": False,
    "maxReviewsPerHotel": 20,
    "maxItems": 20,
    "proxy": { "useApifyProxy": True },
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "compactUpdates": False,
    "ignoreFieldsForChanges": [],
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/wego-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",
  "locations": [
    "Dubai"
  ],
  "rooms": 1,
  "adults": 2,
  "currency": "USD",
  "urls": [
    "https://www.wego.com/hotels/united-arab-emirates/dubai",
    "https://www.wego.com/hotels/united-arab-emirates/dubai/le-meridien-mina-seyahi-beach-resort-waterpark-690184",
    "https://www.wego.com/en/hotels/770060",
    "https://www.wego.com/en/hotels/searches/dxb/2026-11-20/2026-11-22?guests=2",
    "https://www.wego.com/en/hotels/searches/dubai/2026-11-20/2026-11-22?guests=2",
    "https://www.wego.com/ar/hotels/searches/dxb/2026-11-20/2026-11-22?guests=2",
    "https://www.wego.com/en/hotels/searches/dxb/2026-11-20/2026-11-22/690184?guests=2"
  ],
  "freeCancellationOnly": false,
  "sortBy": "popularity",
  "fetchDetails": true,
  "fetchReviews": false,
  "maxReviewsPerHotel": 20,
  "maxItems": 20,
  "proxy": {
    "useApifyProxy": true
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "compactUpdates": false,
  "ignoreFieldsForChanges": []
}' |
apify call abotapi/wego-com-scraper --silent --output-dataset

```

## MCP server setup

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