# Skyscanner Hotel Reviews Scraper API $1/1k — Aggregated Reviews (`memo23/skyscanner-hotel-reviews-scraper`) Actor

Pull hotel reviews from Skyscanner, aggregated from partners such as Hotels.com, Expedia and Tripadvisor in one call. Full review text, rating, source, dates, images and hotel replies. Optional AI review insights answer any question about a hotel's reviews. $1/1k, JSON or CSV.

- **URL**: https://apify.com/memo23/skyscanner-hotel-reviews-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Travel
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 reviews

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## Skyscanner Hotel Reviews Scraper

Pull hotel reviews from Skyscanner, aggregated from partners such as Hotels.com, Expedia and Tripadvisor in a single API call.
Optional AI review insights answer any free-text question about a hotel's reviews. Pure HTTP, no anti-bot.

### Why Use This Scraper?

- ✅ Reviews from several booking partners in one call, each row tagged with its source
- ✅ Full review text, rating, guest type, dates, images, hotel replies
- ✅ AI review insights — ask a question, get a hotelSays + travellersSay summary
- ✅ Sort by most recent, highest rating, lowest rating or recommended
- ✅ Paginate up to thousands of reviews per hotel
- ✅ Clean JSON or CSV output, one row per review

### Overview

The actor talks to Skyscanner's hotel-enrich mobile API — the same endpoint the Android app uses to render a hotel's review tab. Skyscanner aggregates reviews from partners such as Hotels.com, Expedia and Tripadvisor into one response, so you get cross-site coverage without scraping each site separately. Which partners appear depends on the hotel. You provide a Skyscanner hotel id (parsed from any Skyscanner hotel URL) and the actor paginates through reviews, returning one row per review with full text, rating, dates, guest type, images and hotel replies. An optional AI review-insight mode asks a free-text question about the hotel and returns a summarised answer grounded in the reviews.

### Supported Inputs

**Hotel ID mode** — pass `hotelIds` directly:

```
129259677   (Dorsett Shepherds Bush London)
213438010   (United Lodge Hotel)
```

**URL mode** — paste Skyscanner hotel URLs, the hotelId is parsed from the path:

```
https://www.skyscanner.com/hotels/united-kingdom/london-hotels/park-grand-heathrow/ht-130757982
https://www.skyscanner.net/hotels/.../ht-130757982?adults=2&checkin=2026-11-15&checkout=2026-11-18
```

**Required:** either `hotelIds` or `startUrls`.

### Use Cases

| Audience | Use |
|---|---|
| Hospitality analysts | Benchmark hotel sentiment across OTAs in one pull |
| Market researchers | Track review volume, rating distribution and tag trends per hotel |
| AI / LLM builders | Feed the review-insight endpoint into a hotel Q\&A feature |
| Reputation managers | Monitor new reviews across booking sites from one source |
| Travel content teams | Pull real guest quotes and AI summaries for destination pages |

### How It Works

1. **Resolve hotel ids** — from `hotelIds` input or parsed from start URLs.
2. **Fetch reviews** — POST to `v1/hotel/reviews` on hotel-enrich with the hotel id, locale, offset, limit and sort.
3. **Paginate** — repeat with increasing offset until `maxReviewsPerHotel` is reached or reviews run out.
4. **Emit rows** — one row per review with full text, rating, dates, guest type, images, replies, and the partner it came from (`partnerId`, `partnerName`).
5. **Optional AI insight** — POST to `v1/review-insight` with a question, get a hotelSays + travellersSay summary plus top reviews.

![How it works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-skyscanner-hotel-reviews.png)

### Input Configuration

| Field | Type | Default | Description |
|---|---|---|---|
| `startUrls` | array | — | Skyscanner hotel URLs; hotelId is parsed from the URL. |
| `hotelIds` | array | — | Skyscanner hotel ids (numeric). Required when no startUrls. |
| `maxReviewsPerHotel` | integer | 50 | Max reviews to fetch per hotel. |
| `maxItems` | integer | 10 | Max number of hotels to process. |
| `sortBy` | enum | SORT_TYPE_MOST_RECENT | SORT_TYPE_MOST_RECENT, SORT_TYPE_RATING_DESC, SORT_TYPE_RATING_ASC, SORT_TYPE_RECOMMENDED. The first three are also applied by the actor (Skyscanner sorts some hotels only in batches); for a hotel with up to 200 reviews it fetches them all, so the top rows are exact. |
| `includeReviewInsight` | boolean | false | Ask an AI a question about each hotel's reviews. Add-on: $0.01 per hotel answered. |
| `reviewInsightQuestion` | string | "What do guests say about this hotel?" | Question for the review-insight endpoint. |
| `locale` | string | en-GB | Language reviews are returned in (en-GB, de-DE, ja-JP…). Reviews in another language come back translated. |
| `market` | string | GB | Country Skyscanner answers from. GB is sent as UK internally. |
| `proxy` | object | Apify proxy | Proxy configuration. Paying users use our residential pool automatically. |

#### Example: recent reviews for one hotel

```json
{
    "hotelIds": ["130757982"],
    "maxReviewsPerHotel": 100,
    "sortBy": "SORT_TYPE_MOST_RECENT"
}
```

#### Example: top-rated reviews with AI insight

```json
{
    "startUrls": ["https://www.skyscanner.com/hotels/united-kingdom/london-hotels/park-grand-heathrow/ht-130757982"],
    "maxReviewsPerHotel": 50,
    "sortBy": "SORT_TYPE_RATING_DESC",
    "includeReviewInsight": true,
    "reviewInsightQuestion": "Is the breakfast good?"
}
```

### Output Overview

One row per review (`type: "review"`), with full text, rating, dates, guest type, images, replies and the partner it came from. When `includeReviewInsight` is on, each hotel also gets one `type: "review_insight"` row with the AI Q\&A summary.

### Output Samples

**Review row:**

```json
{
    "type": "review",
    "hotelId": "130757982",
    "reviewId": "a947fd75da7a7ff622433e7ed00a1331",
    "partnerId": "h_h1",
    "partnerName": "Hotels.com",
    "rating": 4,
    "content": "Thanks park grand heathrow",
    "locale": "en-GB",
    "guestType": "GUEST_TYPE_UNSPECIFIED",
    "translationType": "TRANSLATION_TYPE_TRANSLATED",
    "reviewDate": "2026-10-20",
    "checkinDate": "2026-10-09",
    "images": [],
    "replies": []
}
```

**Review insight row:**

```json
{
    "type": "review_insight",
    "hotelId": "130757982",
    "question": "Is the breakfast good?",
    "hotelSays": {
        "answer": "According to the information provided by the property, details about the quality or variety of breakfast are not specified..."
    },
    "travellersSay": {
        "answer": "According to guest reviews, breakfast is frequently described as decent with a good selection of hot and cold items, though many mention it is basic and repetitive..."
    },
    "topReviews": [
        { "reviewId": "...", "content": "...", "rating": 4 }
    ]
}
```

### Key Output Fields

**Review rows**
`hotelId`, `reviewId`, `partnerId`, `partnerName`, `rating`, `title`, `content`, `locale`, `guestType`, `translationType`, `reviewDate`, `checkinDate`, `country`, `images[]`, `replies[]`, `logo`

**Review insight rows**
`hotelId`, `question`, `hotelSays.answer`, `travellersSay.answer`, `topReviews[]`

### FAQ

**Where do I find a hotelId?** Open any Skyscanner hotel URL — the number after `ht-` in the path (`/ht-130757982`) is the hotelId. You can also pass the full URL via `startUrls` and the actor parses it for you.

**Which sites are the reviews aggregated from?** Whichever partners Skyscanner has reviews from for that hotel, most often Hotels.com, Expedia and Tripadvisor. Every review row names its source in `partnerId` and `partnerName`.

**What's the difference between this and the hotels scraper?** The hotels scraper (`memo23/skyscanner-hotels-scraper`) returns search results with prices and ratings. This actor returns the actual review text. Use the hotels scraper to find hotel ids, then feed them here.

**Is the AI review insight always included?** No. It's a premium toggle (`includeReviewInsight`). When on, the actor asks one question per hotel and returns a summary grounded in that hotel's reviews. The answer is in English, whatever `locale` is set to; the reviews themselves follow `locale`.

**Are the reviews translated?** Skyscanner returns translated reviews by default. The `translationType` field on each row tells you whether the review was translated or is in its original locale.

### Support

- Issues: [Apify Console Issues tab](https://console.apify.com/actors/memo23%2Fskyscanner-hotel-reviews-scraper)
- Email: support@memo23.dev

### Additional Services

Need a custom review aggregation pipeline, a specific filter (guest type, locale, tags), or a batch of hotels? We build tailored integrations on top of this actor. Reach out via the Issues tab or email.

### Explore More Scrapers

- [Skyscanner Hotels Scraper](https://apify.com/memo23/skyscanner-hotels-scraper) — search, prices and content
- [Skyscanner Flight Scraper](https://apify.com/memo23/skyscanner-scraper) — itineraries, fares, multi-city

### 🤖 For AI Agents & LLM Apps

This actor is callable via the Apify MCP server. Quick reference:

**Purpose:** Pull hotel reviews aggregated from partners such as Hotels.com, Expedia and Tripadvisor in one call. Optional AI review-insight Q\&A.

**Minimal input (tested):**

```json
{
    "hotelIds": ["130757982"],
    "maxReviewsPerHotel": 50,
    "sortBy": "SORT_TYPE_MOST_RECENT"
}
```

**Output row types:** `review` (one per review: `hotelId`, `reviewId`, `partnerId`, `partnerName`, `rating`, `content`, `reviewDate`, `checkinDate`, `guestType`, `translationType`, `images`, `replies`), `review_insight` (AI Q\&A when `includeReviewInsight` is on).

**Billing:** Pay-per-event. $0.001 per review row ($1 per 1,000), $0.001 per hotel looked up, $0.01 per AI insight (plus $0.001 for its row), and $0.007 per GB of memory at run start. A hotel with no reviews is not sent for an insight and is not charged for one. Free-tier runs are capped.

**Agent notes:** `hotelIds` is required (or a Skyscanner hotel URL in `startUrls` — the `ht-<id>` segment is the hotelId). With `includeReviewInsight` on, the dataset holds two row types; filter on the `type` field. For AI insight, set `includeReviewInsight: true` and a `reviewInsightQuestion`.

### ⚠️ Disclaimer

This scraper is not affiliated with, endorsed by, or sponsored by Skyscanner Limited. "Skyscanner" is a trademark of Skyscanner Limited. This tool accesses publicly available data via Skyscanner's mobile API for research and analysis purposes only. Users are responsible for complying with Skyscanner's Terms of Service and all applicable laws, including GDPR and CCPA. The actor does not bypass authentication, paywalls, or access controls. For any concerns about data usage, contact the operator via the Issues tab.

### SEO Keywords

skyscanner hotel reviews scraper, skyscanner hotel reviews api, aggregated hotel reviews api, booking hotel reviews, trip.com hotel reviews, expedia hotel reviews, tripadvisor hotel reviews, hotel review aggregation, hotel sentiment api, hotel review text, hotel review insight, ai hotel review summary, hotel review q\&a, hotel guest reviews api, hotel rating api, hotel review data feed, cross-ota hotel reviews, hotel reputation api, hotel review scraper, skyscanner mobile api reviews

# Actor input Schema

## `startUrls` (type: `array`):

Skyscanner hotel page URLs, the kind ending in …/ht-129259677. The hotel id is read from the ht- part.

## `hotelIds` (type: `array`):

Skyscanner hotel ids (numeric), for example 129259677. The hotels scraper returns them in its hotelId field. Not needed when startUrls has a hotel URL.

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

Maximum reviews to fetch per hotel. Reviews are fetched 50 at a time until this is reached.

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

Maximum number of hotels to process.

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

Sort order for reviews. Most recent and the rating sorts are also applied by the actor, so rows come back in that order: Skyscanner sorts some hotels only in batches.

## `includeReviewInsight` (type: `boolean`):

Ask an AI a question about each hotel's reviews and get a hotelSays + travellersSay summary. The answer comes back in English whatever the language setting. Add-on: $0.01 per hotel answered (a hotel with no reviews is skipped and not charged).

## `reviewInsightQuestion` (type: `string`):

The question asked about each hotel's reviews, for example "Is the breakfast good?" or "Is it quiet at night?". Used only when the AI review insight is on.

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

Language reviews are returned in. Reviews written in another language come back translated, and translationType says which. Pick one or type another locale code.

## `market` (type: `string`):

Country Skyscanner answers from. Pick one or type another country code.

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

Proxy configuration (non-paying users). Paying users use our residential pool automatically.

## Actor input object example

```json
{
  "hotelIds": [
    "129259677"
  ],
  "maxReviewsPerHotel": 20,
  "maxItems": 10,
  "sortBy": "SORT_TYPE_MOST_RECENT",
  "includeReviewInsight": false,
  "reviewInsightQuestion": "What do guests say about this hotel?",
  "locale": "en-GB",
  "market": "GB",
  "proxy": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Rows told apart by `type`: `review` and `review_insight`.

# 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 = {
    "hotelIds": [
        "129259677"
    ],
    "maxReviewsPerHotel": 20,
    "proxy": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/skyscanner-hotel-reviews-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 = {
    "hotelIds": ["129259677"],
    "maxReviewsPerHotel": 20,
    "proxy": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/skyscanner-hotel-reviews-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 '{
  "hotelIds": [
    "129259677"
  ],
  "maxReviewsPerHotel": 20,
  "proxy": {
    "useApifyProxy": true
  }
}' |
apify call memo23/skyscanner-hotel-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,memo23/skyscanner-hotel-reviews-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/xDblzs1GtX2TMprus/builds/XwXXra2jEt03y0f08/openapi.json
