# Hostelworld Scraper \[$1.40/1K💰] | Listings + Reviews (`ahmed_jasarevic/hostelworld-scraper`) Actor

Scrape Hostelworld by city, country, URL or property page. Get nightly prices, dorm vs private tiers, ratings, amenities, policies, photos and coordinates — plus full review text with traveller nationality in a second dataset. No browser needed.

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

## Pricing

from $1.40 / 1,000 listings

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

## Hostelworld Scraper — Hostel Listings, Nightly Prices and Full Review Text

Extract **Hostelworld hostel data** by city, country, URL or property page — nightly prices from, dorm vs private tiers, guest ratings, amenities, policies, photos, geo-coordinates and full **review text with traveller nationality**.

Two datasets: one row per property, one row per review. Built for **hostel price comparison**, hostel market research, review sentiment analysis and travel-content datasets.

***

### Two datasets, one run

**Listings** (default dataset) — one row per property, ~45 fields: name, price-from, dorm and private minimums, rating, review count, city-centre distance, amenities, policies, photos, coordinates.

**Reviews** (named `reviews` dataset) — one row per review with **the review text itself**, the date, the score, the breakdown by category, and **the reviewer's nationality and nickname**.

The review dataset is what most *combined* scrapers split out. Dedicated review-only Actors exist — but they return reviews **without** the property records, so you pay twice, make two calls and join the results yourself. Here both datasets come from one run, already keyed.

***

### What makes this different from other Hostelworld scrapers

Hostelworld's own **mobile app API** is what most scrapers hit, and it is protected by JA3 TLS fingerprinting — it rejects most datacenter requests outright. This Actor instead uses Hostelworld's **first-party web APIs**: the Apigee-backed `api.hostelworld.net` endpoints that power the website itself, plus the static-pages API for the long-form content (descriptions, policies, amenities, "things to note").

Because it calls the same endpoints the website calls, you get the **full property record** — not just the card fields — and you do not need browser fingerprint spoofing or a paid proxy to do it.

***

### Main use cases

- **Hostel price comparison** — nightly price-from across every property in a city, dorm vs private, in any currency
- **Hostel market research** — capacity, rating distribution and review volume per property
- **Review sentiment and language analysis** — full review text with traveller nationality
- **Hostel directory or travel content datasets** — amenities, photos, policies and descriptions for thousands of properties
- **Location and catchment analysis** — coordinates plus `cityCentreDistanceKm` for map and walkability work
- **Price and availability tracking** — re-run the same city on a schedule and diff `priceFrom`
- **City hostel inventory planning** — scrape a whole country and get every active city's hostels
- **Competitive hostel benchmarking** — ratings, review counts and badges side by side

***

### Input

| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
| `startUrls` | array | no | London city page | Hostelworld city pages (`/hostels/europe/england/london/`) or property pages (`/hostels/p/502/slug`). The URL type is **auto-detected**. |
| `cities` | array | no | `[]` | Cities to scrape, as `"City"` or `"City, Country"`. **Use `"City, Country"`** — a bare city name is resolved by probing the largest hostel countries, which costs extra requests. |
| `countries` | array | no | `[]` | Whole countries to crawl. Every active city is enumerated, then its hostels are listed. |
| `propertyType` | string | no | `hostel` | `hostel` or `hotel`. **Note:** Hostelworld's listing API currently returns the same city inventory for both, so this does not filter results — it is kept for URL/API path compatibility. |
| `currency` | string | no | `GBP` | ISO code for all price fields: `GBP`, `EUR`, `USD`, `AUD`, `CAD`, `THB`, `MXN`, `BRL`, `ZAR`. |
| `language` | string | no | `en` | `Accept-Language` sent to the API (`en`, `de`, `es`, `fr`, ...). |
| `maxListings` | integer | no | `200` | Hard cap on properties written to the dataset (1–5000). Free-tier users are capped at 10. |
| `maxCitiesPerCountry` | integer | no | `25` | When crawling a whole country, how many of its cities to enumerate (1–500). |
| `maxReviewsPerProperty` | integer | no | `10` | Newest reviews to fetch per property, 10 per API page (0–200). `0` skips reviews entirely. |
| `includeDetails` | boolean | no | `true` | Fetch the full property record — amenities, photos, policies, price stats, badges, "things to note". Turn off for fast listing-only runs. |
| `includeReviews` | boolean | no | `true` | Fetch review text, date and nationality into the `reviews` dataset. |
| `concurrency` | integer | no | `8` | Parallel API requests (1–50). 8–10 is safe. |
| `maxExpansionCountries` | integer | no | `10` | Auto-expansion only: how many of the largest hostel countries to draw extra cities from when no country is given. |
| `maxCountryProbes` | integer | no | `20` | When a city is given without a country, how many countries to probe before giving up (1–60). |
| `maxRequestsPerCrawl` | integer | no | `0` | Safety cap per crawl round. **`0` = unlimited (recommended)** — a non-zero value can cut a large run short. |
| `proxy` | object | no | `useApifyProxy: false` | Standard Apify proxy picker. Not needed — the first-party API does not block. |

#### Examples

**City price sweep, no reviews — the cheap hostel-comparison run:**

```json
{
  "cities": ["Barcelona, Spain", "Lisbon, Portugal"],
  "maxListings": 500,
  "includeDetails": false,
  "includeReviews": false,
  "currency": "EUR"
}
```

**Full property records for one city, in euros:**

```json
{
  "cities": ["Berlin, Germany"],
  "maxListings": 300,
  "includeDetails": true,
  "includeReviews": false,
  "currency": "EUR",
  "language": "en"
}
```

**Review dataset for sentiment analysis:**

```json
{
  "cities": ["Bangkok, Thailand"],
  "maxListings": 200,
  "includeDetails": false,
  "includeReviews": true,
  "maxReviewsPerProperty": 50,
  "currency": "THB"
}
```

**Whole-country inventory:**

```json
{
  "countries": ["Portugal"],
  "maxCitiesPerCountry": 40,
  "maxListings": 1500,
  "currency": "EUR"
}
```

**Straight from URLs you already have:**

```json
{
  "startUrls": [
    "https://www.hostelworld.com/hostels/europe/england/london/",
    "https://www.hostelworld.com/hostels/p/502/the-london-hostel"
  ],
  "currency": "GBP"
}
```

***

### Output

#### Listings dataset

| Field | Description |
|---|---|
| `id` / `slug` / `name` / `url` | Hostelworld property ID, slug, name and canonical URL |
| `propertyType` | `hostel`, `hotel` or `bed-and-breakfast` |
| `address` / `city` / `cityId` / `country` / `region` / `continent` | Full location |
| `geo` | `{ latitude, longitude }` |
| `cityCentreDistanceKm` | Distance from the city centre — the walkability signal |
| `currency` | ISO code of every price field in the row |
| `priceFrom` | Lowest nightly price per person |
| `priceFromDorm` / `priceFromPrivate` | Dorm and private room minimums |
| `priceStats` | Hostelworld's own price statistics |
| `roomTiers[]` | Structured tiers: `type` (`dorm/shared`, `private`), `from`, `currency` |
| `rating` | Average guest rating (0–10 scale normalised) |
| `ratingOverallPct` | Overall score as published (percentage scale) |
| `numberOfReviews` | Total review count on the property |
| `ratingBreakdown` | Per-category rating breakdown |
| `reviewCountFetched` | **How many reviews this run actually retrieved** — compare against `numberOfReviews` to see coverage |
| `checkInFrom` / `checkOutUntil` / `freeCancellation` | Booking policy fields |
| `cancellationPolicy` / `policies[]` / `thingsToNote[]` | House rules and guest-facing notes |
| `photo` / `photoCount` / `photos[]` | Hero image, photo count and up to 20 full-size photo URLs |
| `description` / `shortDescription` / `hostelworldSays` | Long, short and Hostelworld's own editorial description |
| `badges[]` / `bestFor[]` | Featured badges and "best for" tags |
| `paymentMethods[]` | Accepted payment methods |
| `reviewsDataset` | Name of the reviews dataset, or `null` when reviews were off |
| `source` | `city:<name>` or `country:<name>` — where this row was seeded from |
| `scrapedAt` | ISO timestamp |

#### Reviews dataset

| Field | Description |
|---|---|
| `id` | Review ID |
| `propertyId` / `propertyName` / `propertySlug` / `propertyUrl` | **Join key** back to the listing row |
| `city` / `country` | Denormalized, so the review dataset stands alone |
| `date` | Review date |
| `text` | Full review text |
| `rating` / `ratingBreakdown` | Overall score and per-category breakdown |
| `nationality` / `nationalityCode` | **Reviewer's nationality** |
| `travellerNickname` / `travellerReviews` | Reviewer identity and how many reviews they have written |
| `groupType` / `ageRange` / `tripTypes` | Solo / group, age band, leisure vs business |
| `language` | Language the review was written in |
| `scrapedAt` | ISO timestamp |

#### `reviewCountFetched` is the coverage flag

`numberOfReviews` is what the property has; `reviewCountFetched` is what this run retrieved. A property with `numberOfReviews: 412` and `reviewCountFetched: 10` has 2% coverage — fine for a quick read, not fine for sentiment analysis. Raise `maxReviewsPerProperty` (up to 200) when the review corpus is the point of the run.

#### Example output

Listings row:

```json
{
  "id": 502,
  "slug": "the-london-hostel",
  "name": "The London Hostel",
  "url": "https://www.hostelworld.com/hostels/p/502/the-london-hostel-europe-england-london/",
  "propertyType": "hostel",
  "address": "256-262 Kingsland Road, London, E2 8AA",
  "city": "London",
  "cityId": 2796,
  "country": "United Kingdom",
  "region": null,
  "continent": "Europe",
  "geo": { "latitude": 51.5289, "longitude": -0.0762 },
  "cityCentreDistanceKm": 2.4,
  "currency": "GBP",
  "priceFrom": 21.5,
  "priceFromDorm": 21.5,
  "priceFromPrivate": 44.0,
  "priceStats": { "minPrice": 21.5, "maxPrice": 89.0 },
  "roomTiers": [
    { "type": "dorm/shared", "from": 21.5, "currency": "GBP" },
    { "type": "private", "from": 44.0, "currency": "GBP" }
  ],
  "rating": 8.9,
  "ratingOverallPct": 89,
  "numberOfReviews": 1284,
  "ratingBreakdown": { "staff": 9.3, "cleanliness": 8.8, "location": 8.4, "value": 8.7 },
  "checkInFrom": "14:00",
  "checkOutUntil": "10:00",
  "freeCancellation": true,
  "cancellationPolicy": "Free cancellation up to 1 day before arrival",
  "photo": "https://images.hostelworld.com/hostels/p/502/the-london-hostel.jpg",
  "photoCount": 24,
  "photos": ["https://images.hostelworld.com/hostels/p/502/1.jpg"],
  "description": "A large independent hostel in the heart of East London, minutes from Shoreditch...",
  "shortDescription": "Large independent hostel in East London",
  "badges": ["Best Location"],
  "bestFor": ["Solo travellers", "Groups"],
  "paymentMethods": ["Visa", "Mastercard", "Cash"],
  "policies": ["No smoking", "Curfew 23:00-07:00"],
  "thingsToNote": ["Bring a photo ID", "Lockers available"],
  "reviewCountFetched": 10,
  "reviewsDataset": "reviews",
  "source": "city:london",
  "scrapedAt": "2026-09-30T10:02:41.000Z"
}
```

Reviews row:

```json
{
  "id": 8871234,
  "propertyId": 502,
  "propertyName": "The London Hostel",
  "propertySlug": "the-london-hostel",
  "propertyUrl": "https://www.hostelworld.com/hostels/p/502/the-london-hostel-europe-england-london/",
  "city": "London",
  "country": "United Kingdom",
  "date": "2026-08-14",
  "text": "Great location for East London and the staff were genuinely helpful. Dorms are basic but spotless, and the bike storage was a bonus.",
  "rating": 8.8,
  "ratingBreakdown": { "staff": 9.5, "cleanliness": 9.0, "location": 9.2, "value": 8.5 },
  "nationality": "Australia",
  "nationalityCode": "AU",
  "travellerNickname": "Traveller_4821",
  "travellerReviews": 14,
  "groupType": "solo",
  "ageRange": "25-34",
  "tripTypes": ["leisure"],
  "language": "en",
  "scrapedAt": "2026-09-30T10:02:43.000Z"
}
```

***

### Track hostel prices and reviews on a schedule

Hostel pricing moves with season, events and demand. Recurring runs turn the dataset into a live price and reputation feed:

- **Weekly** — same cities; diff `priceFrom` and `priceFromDorm` for high-frequency cities
- **Monthly** — diff `rating` and `reviewCountFetched` to track reputation movement over time
- **Peak-season baseline** — run once a month across a whole country in `EUR` for market sizing
- **New-opening detection** — keep only rows with an `id` not seen in the previous run
- **Wire into your stack** — Apify webhooks, Zapier, Make, Google Sheets and 100+ integrations fire on run completion; both datasets export as JSON, CSV, Excel, XML, HTML or RSS

Split your schedules by cost: `includeReviews: false` on the weekly price run, `includeReviews: true` with a higher `maxReviewsPerProperty` on the monthly reputation run. Reviews are billed per row, listings are billed per property.

***

### Related Actors

- [Booking.com Review Scraper](https://apify.com/ahmed_jasarevic/booking-com-hotel-review-scraper) (`ahmed_jasarevic/booking-com-hotel-review-scraper`) — hotel-scale review text and sentiment data at much larger volume
- [Booking.com Scraper](https://apify.com/ahmed_jasarevic/fast-booking-scraper) (`ahmed_jasarevic/fast-booking-scraper`) — wider property coverage for cross-platform price comparison
- [Airbnb Scraper](https://apify.com/ahmed_jasarevic/airbnb-scraper-listings-prices-hosts) (`ahmed_jasarevic/airbnb-scraper-listings-prices-hosts`) — peer-to-peer accommodation for a different segment of the same trip
- [Hostelworld Listings Scraper by easyapi](https://apify.com/easyapi/hostelworld-listings-scraper) (`easyapi/hostelworld-listings-scraper`) — listing fields only; pairs with their separate reviews Actor
- [Hostelworld Reviews Scraper by easyapi](https://apify.com/easyapi/hostelworld-reviews-scraper) (`easyapi/hostelworld-reviews-scraper`) — the most-used dedicated review Actor; reviews only, no property records

***

### FAQ

#### Why not use the official Hostelworld Partner API?

Because you need to be an approved **affiliate partner** first — it is not an open developer API. If you run a booking engine or a monetised travel site, apply for affiliate access and use the official Partner API; it is the correct route for that use case. For **research, comparison, dataset building and analysis**, there is no self-serve access, which is what this Actor covers.

#### Why do other Hostelworld scrapers return less?

Because most of them hit Hostelworld's **mobile app API**, which is protected by JA3 TLS fingerprinting — it rejects requests that do not come from the real app. This Actor calls the **first-party web APIs** that power the website instead, which is why it returns amenities, policies, badges, "things to note", the full description and the review text without browser fingerprint spoofing or a paid proxy.

#### Does `propertyType: "hotel"` give me hotels?

**No — and this is a real limitation, stated plainly.** Hostelworld's listing API currently returns the same city inventory for both `hostel` and `hotel`, so the field changes the API path but does not filter results. Treat `propertyType` as a path selector, not a filter. If you need true hotel-only inventory, use a different source.

#### How do I avoid wasted requests on ambiguous city names?

Always write `"City, Country"` in `cities`. A bare city name forces the Actor to probe the largest hostel countries until it finds a match, up to `maxCountryProbes` — real wasted calls on a big run. If a city genuinely appears in several countries, that probe is what you want, but be aware of it in the log.

#### Why is `rating` not the same scale as `ratingOverallPct`?

`rating` is the normalised average on Hostelworld's 0–10 scale; `ratingOverallPct` is the raw overall score as published on a percentage scale. They track each other but are not interchangeable — use `rating` for aggregation and `ratingOverallPct` if you need to reproduce what a reader sees on the page.

#### How complete is the review dataset?

`reviewCountFetched` tells you exactly. Hostelworld returns reviews 10 per API page, so `maxReviewsPerProperty: 10` is one page. Raise it up to 200 for deeper corpora, and compare `reviewCountFetched` against `numberOfReviews` to know your coverage before running analysis on it.

#### Does it need a browser or a proxy?

No. It is API-only — no JavaScript rendering, no headless browser, no CAPTCHA solving. The default run uses no proxy at 256 MB and 8 parallel requests, which is comfortably within what the API accepts.

#### Can I crawl a whole country?

Yes — put the country in `countries`. The Actor enumerates every active city in that country, then lists each city's hostels. `maxCitiesPerCountry` (default 25) caps how many cities are taken, and the log tells you how many were skipped, so nothing disappears silently.

***

### For AI Agents & LLM Apps

Callable via the Apify MCP server and the Apify API. Returns **two** named datasets: `dataset` (default) with one row per property, and `reviews` with one row per review.

**Minimal valid input** — one city, listing data only, cheapest:

```json
{ "cities": ["Barcelona, Spain"], "includeDetails": false, "includeReviews": false, "currency": "EUR" }
```

**Full run with review text:**

```json
{
  "cities": ["Berlin, Germany"],
  "maxListings": 300,
  "includeDetails": true,
  "includeReviews": true,
  "maxReviewsPerProperty": 50,
  "currency": "EUR"
}
```

**Whole-country inventory:**

```json
{ "countries": ["Portugal"], "maxCitiesPerCountry": 40, "maxListings": 1500, "currency": "EUR" }
```

**Output field list** — listings: `id`, `slug`, `name`, `url`, `propertyType`, `address`, `city`, `cityId`, `country`, `region`, `continent`, `geo`, `cityCentreDistanceKm`, `currency`, `priceFrom`, `priceFromDorm`, `priceFromPrivate`, `priceStats`, `roomTiers`, `rating`, `ratingOverallPct`, `numberOfReviews`, `ratingBreakdown`, `reviewCountFetched`, `checkInFrom`, `checkOutUntil`, `freeCancellation`, `cancellationPolicy`, `policies`, `thingsToNote`, `photo`, `photoCount`, `photos`, `description`, `shortDescription`, `hostelworldSays`, `badges`, `bestFor`, `paymentMethods`, `reviewsDataset`, `source`, `scrapedAt`. Reviews: `id`, `propertyId`, `propertyName`, `propertySlug`, `propertyUrl`, `city`, `country`, `date`, `text`, `rating`, `ratingBreakdown`, `nationality`, `nationalityCode`, `travellerNickname`, `travellerReviews`, `groupType`, `ageRange`, `tripTypes`, `language`, `scrapedAt`.

**Behaviors an agent should know**

- **Two separately billed events.** `includeReviews: false` bills only the `listing` event; the `reviews` dataset is skipped entirely and `reviewsDataset` comes back `null` on every row.
- **Reviews are billed per review row, not per property.** `maxReviewsPerProperty: 50` adds up to 50 review charges per property on top of the listing charge. If the review corpus is not the point of the run, set it to `0`.
- **`propertyType` does not filter.** `hotel` returns the same inventory as `hostel`. Do not promise the caller hotels.
- **Always pass `"City, Country"`.** A bare city name triggers country probing and wastes requests; `maxCountryProbes` caps the waste at 20 lookups by default.
- **`maxRequestsPerCrawl` defaults to `0`, meaning unlimited** — a non-zero value can cut a large run short. Leave it at `0` unless you have a specific reason.
- **`propertyType` is kept only for URL/API-path compatibility**, so a start URL like `/hotels/.../london/` is parsed correctly even though the results are not hotel-filtered.
- **Join key is `id` ↔ `propertyId`.** Use it to attach reviews to listings.
- **`reviewCountFetched` vs `numberOfReviews`** is your coverage check — never run sentiment analysis without comparing them.
- **Two dataset schemas, both with an `overview` view** — select the `reviews` storage to read review rows.
- **`currency` applies to every price field in the row.** `priceFrom`, `priceFromDorm`, `priceFromPrivate`, `priceStats` and each `roomTiers[].from` are all in `row.currency`.

**Billing model** — pay per event: `listing` ($0.0014–$0.0015 per property row) and `review` ($0.00075–$0.0008 per review row), plus a per-run Actor Start event scaled by memory. Free-plan users are capped at 10 properties.

***

### Legal & Compliance Disclaimer

This Actor is an independent third-party tool. It is not affiliated with, endorsed by, sponsored by, or connected with Hostel Group / Hostelworld.

It reads **only publicly available data** — the JSON endpoints that power Hostelworld's own public website, plus publicly visible property pages. It does not log in, does not create an account, does not use an affiliate or partner token, does not solve CAPTCHAs, does not use proxies by default, and does not bypass the official Partner API agreement.

Output includes **guest review content** — free-text review bodies, reviewer nicknames, reviewer nationalities, age bands and group types. This is **personal data** about identifiable individuals under GDPR and UK GDPR. You are responsible for your own lawful basis for processing it, for honouring deletion requests, and for keeping retention periods short. Do not use review text or reviewer profiles to build marketing lists, and do not re-publish review text without the appropriate permission.

Commercial or high-volume extraction may fall under Hostelworld's terms of use, and monetised use of their content normally requires affiliate or partner agreement — review their terms before large-scale collection or redistribution. Review text and property descriptions remain the property of their authors and Hostelworld.

This Actor is a data-collection tool; it does not provide legal advice and makes no claim that any particular use is permitted.

***

### SEO Keywords

hostelworld scraper, hostel data, hostel price comparison, hostel listings api, hostel reviews dataset, hostel api alternative, review text scraping, traveller nationality data, hostel city inventory, hostel market research, hostel sentiment analysis, budget travel data, hostel prices by city, hostelworld api scraper, dorm bed prices, hostel amenities data, travel dataset, hostel database, hostel scraping tool, hostel review analysis, backpacking data, hostelworld alternative, travel content dataset

# Actor input Schema

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

Optional. Hostelworld city pages (e.g. https://www.hostelworld.com/hostels/europe/england/london/) or property pages (e.g. https://www.hostelworld.com/hostels/p/502/slug). The URL type is auto-detected.

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

Cities to scrape, as "City" or "City, Country" (recommended). Example: \["Barcelona, Spain", "Berlin, Germany", "Lisbon"].

## `countries` (type: `array`):

Whole countries to crawl. Every active city in the country is enumerated, then its hostels are listed. Example: \["Portugal", "Thailand"].

## `propertyType` (type: `string`):

Kept for URL/API path compatibility. Note: Hostelworld's listing API currently returns the same city inventory for both values, so this does not filter results.

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

ISO currency code used for all price fields (GBP, EUR, USD, ...).

## `language` (type: `string`):

Accept-Language sent to the Hostelworld API (en, de, es, fr, ...).

## `maxListings` (type: `integer`):

Hard cap on how many properties are scraped and pushed to the dataset. Free users are additionally capped at 10.

## `maxCitiesPerCountry` (type: `integer`):

When scraping a whole country, how many of its cities to enumerate.

## `maxReviewsPerProperty` (type: `integer`):

How many of the newest reviews to fetch per property (10 per API page). Reviews are written to a separate "reviews" dataset, one row per review. Set 0 to skip reviews.

## `includeDetails` (type: `boolean`):

Fetch the full property record (amenities, photos, policies, price stats). Turn off for a fast listing-only run.

## `includeReviews` (type: `boolean`):

Fetch review text/date/nationality for each property into the separate "reviews" dataset.

## `concurrency` (type: `integer`):

How many API requests run in parallel. 8-10 is safe; raise only if the API throttles without errors.

## `maxExpansionCountries` (type: `integer`):

Used only for auto-expansion when no country is given in the input: how many of the countries with the most properties to draw the extra cities from.

## `maxCountryProbes` (type: `integer`):

When a city is given without a country, the actor probes the largest hostel countries until it finds a match. This caps how many it tries.

## `maxRequestsPerCrawl` (type: `integer`):

Safety cap on requests, applied per crawl round. 0 = unlimited (recommended — otherwise a large run can be cut short).

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

Select proxies to be used by your crawler.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.hostelworld.com/hostels/europe/england/london/"
    }
  ],
  "cities": [],
  "countries": [],
  "propertyType": "hostel",
  "currency": "GBP",
  "language": "en",
  "maxListings": 200,
  "maxCitiesPerCountry": 25,
  "maxReviewsPerProperty": 10,
  "includeDetails": true,
  "includeReviews": true,
  "concurrency": 8,
  "maxExpansionCountries": 10,
  "maxCountryProbes": 20,
  "maxRequestsPerCrawl": 0,
  "proxy": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `listings` (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 = {
    "startUrls": [
        {
            "url": "https://www.hostelworld.com/hostels/europe/england/london/"
        }
    ],
    "propertyType": "hostel",
    "currency": "GBP",
    "language": "en",
    "maxListings": 200,
    "maxCitiesPerCountry": 25,
    "maxReviewsPerProperty": 10,
    "includeDetails": true,
    "includeReviews": true,
    "concurrency": 8,
    "maxExpansionCountries": 10,
    "maxCountryProbes": 20,
    "maxRequestsPerCrawl": 0,
    "proxy": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed_jasarevic/hostelworld-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 = {
    "startUrls": [{ "url": "https://www.hostelworld.com/hostels/europe/england/london/" }],
    "propertyType": "hostel",
    "currency": "GBP",
    "language": "en",
    "maxListings": 200,
    "maxCitiesPerCountry": 25,
    "maxReviewsPerProperty": 10,
    "includeDetails": True,
    "includeReviews": True,
    "concurrency": 8,
    "maxExpansionCountries": 10,
    "maxCountryProbes": 20,
    "maxRequestsPerCrawl": 0,
    "proxy": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("ahmed_jasarevic/hostelworld-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 '{
  "startUrls": [
    {
      "url": "https://www.hostelworld.com/hostels/europe/england/london/"
    }
  ],
  "propertyType": "hostel",
  "currency": "GBP",
  "language": "en",
  "maxListings": 200,
  "maxCitiesPerCountry": 25,
  "maxReviewsPerProperty": 10,
  "includeDetails": true,
  "includeReviews": true,
  "concurrency": 8,
  "maxExpansionCountries": 10,
  "maxCountryProbes": 20,
  "maxRequestsPerCrawl": 0,
  "proxy": {
    "useApifyProxy": false
  }
}' |
apify call ahmed_jasarevic/hostelworld-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ahmed_jasarevic/hostelworld-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/RBAcw5ZzLOsUb5Tj7/builds/rU2J5O6XUcVNnBy0c/openapi.json
