# HolidayCheck.de Scraper — Hotel Reviews & Ratings (`studio-amba/holidaycheck-de-scraper`) Actor

Scrape hotel reviews from holidaycheck.de: reviewer rating, review text, recommendation, travel type, and hotel aggregate rating. Bright Data Web Unlocker bypasses Akamai. No login required.

- **URL**: https://apify.com/studio-amba/holidaycheck-de-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 result scrapeds

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

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

## How to integrate an Actor?

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

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

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

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

# README

## HolidayCheck.de Scraper — Hotel Reviews & Ratings (No Login)

Scrape hotel reviews from holidaycheck.de, Germany's largest hotel review and travel booking platform — reviewer text, rating, recommendation, traveler type, and the hotel's aggregate rating.

### What is HolidayCheck?

HolidayCheck is the German-speaking market's dominant hotel review site — over 13 million hotel reviews, used the way Anglophone travelers use TripAdvisor. Hotels, tour operators, and OTAs across DACH treat a HolidayCheck score as a real signal, and travelers routinely check it before booking through TUI, Check24, or directly.

- **Reputation monitoring** — Track what German travelers actually say about your hotel or resort, review by review
- **Competitive benchmarking** — Compare your property's rating and recommendation rate against nearby hotels in the same destination
- **Market research** — Analyze sentiment, common complaints, and traveler-type patterns (families vs. couples vs. friends) across a destination
- **Content and BI pipelines** — Feed structured German-language review text into sentiment analysis or LLM summarization

### What data does HolidayCheck Scraper extract?

- Review title and full text (German)
- HolidayCheck's per-review quality score (0-1 internal scale) and whether the reviewer would recommend the hotel
- Traveler type (family, couple, friends, ...), travel date, and review submission date
- Reviewer's first name, age group, and how many reviews they've written
- The hotel's aggregate rating (HolidayCheck's public 1-6 scale) and official star category
- Destination and country context

### How to scrape HolidayCheck data

| Field | Type | Description |
|-------|------|-------------|
| `searchQuery` | String (optional) | A German destination name (e.g. `"Mallorca"`, `"Gardasee"`, `"Hurghada"`) or a direct HolidayCheck hotel review URL. Defaults to `"Mallorca"`. |
| `maxResults` | Integer | Maximum reviews to return (default: 50) |
| `brightDataApiKey` | String (secret) | Bright Data Web Unlocker API key — required, see below |
| `proxyConfiguration` | Object | Not used by this actor — kept for input-schema compatibility |

**A Bright Data Web Unlocker API key is required.** holidaycheck.de runs Akamai Bot Manager: plain requests (no proxy) get a hard HTTP 400 from Akamai on every real page, and a real headless browser on the same IP gets Akamai's block interstitial — verified directly during the build of this actor. Bright Data's Web Unlocker (Germany exit) returns the real page. Get a key at [brightdata.com](https://brightdata.com).

**How destination matching works:** HolidayCheck has no public free-text search API (checked the site's search-widget JS bundle and a handful of guessed REST paths — nothing usable). `searchQuery` is matched against a curated directory of ~27 known-good destinations harvested from the site's own navigation, covering major German cities plus popular holiday regions (Mallorca, Gardasee, Toskana, Sizilien, Türkische Riviera/Ägäis, Hurghada/Safaga, Zanzibar, and more). An unmatched query falls back to Mallorca. You can also pass a direct hotel review URL (`https://www.holidaycheck.de/hr/bewertungen-{slug}/{id}`) to scrape one specific hotel instead of a whole destination — this bypasses matching entirely and works for any hotel on the site.

**How it works internally:** for a destination query, the actor fetches that destination's hotel-listing hub page, collects the hotel review-page links on it (up to 12 hotels), then paginates each hotel's review page (`?p=1`, `?p=2`, ...) until it has enough reviews or that hotel runs out. Review data isn't in a clean JSON API — it's embedded in the page's server-rendered React hydration state, which the actor parses with a small custom extractor (not full JSON, since the blob contains `undefined`/`new Date(...)` literals that aren't valid JSON).

### Output

Each result is one review:

| Field | Type | Example |
|-------|------|---------|
| `reviewId` | String | `"3715a17e-adbb-499a-a4d2-e7e2d77f32ac"` |
| `entityName` | String | `"allsun Hotel Eden Playa"` |
| `entityId` | String | `"af34b64c-bdf3-310a-8dcb-e376de5b4cdd"` |
| `entityUrl` | String | Hotel review page URL |
| `url` | String | Exact paginated page URL this review came from |
| `reviewTitle` | String | `"Eine top gepflegte traumhafte Hotelanlage"` |
| `reviewText` | String | Full review body (German) |
| `ratingScore` | Number | `1` (0-1 internal HolidayCheck score, not the public star display) |
| `entityRating` | Number | `5.45` (hotel's aggregate rating, 1-6 scale) |
| `entityRatingScale` | String | `"1-6"` |
| `entityStars` | Integer | `4` |
| `recommendation` | Boolean | `true` |
| `reviewerName` | String | `"Christa"` |
| `reviewerAgeGroup` | String | `"FROM_61_TO_65"` |
| `reviewerReviewCount` | Integer | `13` |
| `travelDate` | String | `"2026-05-01T00:00:00.000Z"` |
| `entryDate` | String | `"2026-05-14T21:02:33.000Z"` |
| `traveledWith` | String | `"COUPLE"` |
| `destination` | String | `"Mallorca"` |
| `country` | String | `"Spanien"` |
| `language` | String | `"de"` |
| `scrapedAt` | String | ISO 8601 timestamp |

### Example output

```json
{
    "reviewId": "3715a17e-adbb-499a-a4d2-e7e2d77f32ac",
    "entityName": "allsun Hotel Eden Playa",
    "entityId": "af34b64c-bdf3-310a-8dcb-e376de5b4cdd",
    "entityUrl": "https://www.holidaycheck.de/hr/bewertungen-allsun-hotel-eden-playa/af34b64c-bdf3-310a-8dcb-e376de5b4cdd",
    "url": "https://www.holidaycheck.de/hr/bewertungen-allsun-hotel-eden-playa/af34b64c-bdf3-310a-8dcb-e376de5b4cdd",
    "scrapedAt": "2026-08-02T14:21:31.841Z",
    "reviewTitle": "Eine top gepflegte traumhafte Hotelanlage",
    "reviewText": "Wir haben diese traumhafte Hotelanlage im letzten Jahr bei einem Spaziergang entdeckt! Wir durften kurz reinschauen und waren fasziniert.",
    "ratingScore": 1,
    "entityRating": 5.454017803284389,
    "entityRatingScale": "1-6",
    "entityStars": 4,
    "recommendation": true,
    "reviewerName": "Christa",
    "reviewerAgeGroup": "FROM_61_TO_65",
    "reviewerReviewCount": 13,
    "travelDate": "2026-05-01T00:00:00.000Z",
    "entryDate": "2026-05-14T21:02:33.000Z",
    "traveledWith": "COUPLE",
    "destination": "Mallorca",
    "country": "Spanien",
    "language": "de"
}
```

### Cost estimate

Priced per result on Apify's Pay-Per-Event model (see the actor's pricing tab for current numbers). A 50-review run (the default) is a handful of Bright Data requests — one per destination hub page plus one per review page fetched (~10 reviews each) — so cost per run stays low even though every fetch goes through Bright Data's Web Unlocker.

### Limitations

- `searchQuery` matches against a curated destination directory (~27 entries), not a live site search — see "How destination matching works" above. Pass a direct hotel review URL for any hotel not covered by a destination match.
- `ratingScore` is HolidayCheck's internal 0-1 quality/sentiment score per review, not identical to the public star rating shown on the site (that's a separate weighted aggregate HolidayCheck computes across many contribution categories, not exposed as a single per-review number in the page data).
- Review text and metadata are scraped from the public website and may change if HolidayCheck updates its page structure.
- Respect HolidayCheck's terms of service and use responsibly.

### Frequently asked questions

**Do I need my own Bright Data account?**
Yes. HolidayCheck blocks plain requests with Akamai Bot Manager, so a Bright Data Web Unlocker API key is required to run this actor.

**Can I scrape a specific hotel instead of a whole destination?**
Yes — pass the hotel's HolidayCheck review URL (e.g. `https://www.holidaycheck.de/hr/bewertungen-du-lac-et-du-parc-grand-resort/b977c6db-9977-3a0f-b0de-a77a0588cec0`) as `searchQuery`.

**Why don't all reviews for a destination get scraped?**
The actor caps discovery at 12 hotels per destination and 15 pages per hotel as a safety limit against runaway runs. Increase `maxResults` and re-run, or target a specific hotel URL directly, to go deeper on one property.

**What does `entityRating` mean?**
HolidayCheck's public hotel score, on a 1-6 scale (higher is better) — the same number shown site-wide next to the hotel name.

### Related scrapers

- [TUI Scraper](https://apify.com/studio-amba/tui-scraper) — Package holiday listings.
- [GetYourGuide Scraper](https://apify.com/studio-amba/getyourguide-scraper) — Tours and activities.
- [Checkatrade Scraper](https://apify.com/studio-amba/checkatrade-scraper) — UK service-provider reviews (different vertical, same Bright Data pattern).

### Disclaimer

This actor collects only publicly available review data from holidaycheck.de for legitimate use such as reputation monitoring and market research. Respect HolidayCheck's terms of service and applicable data-protection law when using the output.

### Need this data on a schedule, or a custom version?

We run this scraper as a managed service for businesses: scheduled runs, deduplication, delta detection, and delivery to your inbox, Google Sheets, or API — maintenance included. We can also build a custom version with your exact fields and filters, or combine multiple sources into one feed.

See [studioamba.dev/services](https://studioamba.dev/services/) or email <hello@studioamba.dev> for a free data sample. We maintain 300+ European web scrapers and answer within one business day.

# Actor input Schema

## `searchQuery` (type: `string`):

A German destination name (e.g. 'Mallorca', 'Gardasee', 'Hurghada') to scrape reviews for hotels there, or a direct holidaycheck.de hotel review URL (e.g. 'https://www.holidaycheck.de/hr/bewertungen-{slug}/{id}') to scrape that one hotel only. Destination matching uses a curated directory, not live site search — see the actor README for the covered list. Defaults to Mallorca.

## `maxResults` (type: `integer`):

Maximum number of reviews to return. The actor walks hotels on the destination hub page and paginates each hotel's reviews (~10 per page) until this many reviews are collected.

## `brightDataApiKey` (type: `string`):

Your Bright Data API key for the Web Unlocker zone. Required to bypass holidaycheck.de's Akamai Bot Manager challenge. Get one at https://brightdata.com. Can also be supplied via the BRIGHT\_DATA\_API\_KEY environment variable.

## `proxyConfiguration` (type: `object`):

Not used — this actor routes all traffic through Bright Data Web Unlocker (DE), not Apify proxies. Kept for input-schema compatibility.

## Actor input object example

```json
{
  "searchQuery": "Mallorca",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "DE"
  }
}
```

# 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 = {
    "searchQuery": "Mallorca",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "DE"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/holidaycheck-de-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 = {
    "searchQuery": "Mallorca",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "DE",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/holidaycheck-de-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "searchQuery": "Mallorca",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "DE"
  }
}' |
apify call studio-amba/holidaycheck-de-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=studio-amba/holidaycheck-de-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/c4A1F1BpbMHAN9T3n/builds/7Ny9OieNsggFdyBAg/openapi.json
