# Agoda Reviews Scraper (`reviewly/agoda-reviews-scraper`) Actor

Extract hundreds of reviews per hotel in minutes. including the ones Agoda's own page never shows you. Paste a hotel URL and get clean, structured review data: ratings, guest text in both the original language and yours, traveller types, stay dates, room types, photos and owner replies.

- **URL**: https://apify.com/reviewly/agoda-reviews-scraper.md
- **Developed by:** [Reviewly](https://apify.com/reviewly) (community)
- **Categories:** Travel, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 80.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 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.
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

## Agoda Reviews Scraper — Export Hotel Guest Reviews to JSON, CSV or Excel

**Extract hundreds of reviews per hotel in minutes — including the ones Agoda's own page never shows you.** Paste a hotel URL and get clean, structured review data: ratings, guest text in both the original language and yours, traveller types, stay dates, room types, photos and owner replies.

- 📈 **5–6× more reviews** than the hotel page displays — 669 to 763 across test runs, against 121 without the sweep
- 🌍 **Four review sources in one dataset** — Agoda, Booking.com, Priceline and partner sites, merged and de-duplicated
- 🗣️ **Original + translated text** on every review, so nothing is lost in translation
- ⚡ **No browser, no CAPTCHA solving** — a lightweight HTTP scraper, so runs are fast and cheap
- ✅ **Honest coverage reporting** — every record tells you how many reviews it collected and flags partial runs

***

### 📌 What This Actor Does

This **Apify Actor** turns any Agoda hotel page into a structured dataset of guest reviews. You give it one or more Agoda hotel URLs; it returns one record per hotel containing the property's rating summary and every review it could reach, ready to download as **JSON, CSV, Excel or XML**, or pull straight from the Apify API.

Agoda's website only ever shows a slice of a property's reviews, and it hides them behind pagination, language filters and traveller-type filters. This Actor works through those filters systematically and merges the results, so you get a far more complete picture than manual browsing or a naive scraper produces.

#### Who it's for

- **Hotel and hospitality teams** monitoring guest sentiment and comparing against competitors
- **Revenue and reputation managers** tracking how scores move over time
- **Market researchers and analysts** studying travel demand, guest expectations and regional differences
- **Data scientists and AI teams** building training sets or running sentiment and topic analysis
- **Agencies and consultants** producing reputation audits and competitive benchmarking reports for hotel clients
- **Developers** who need Agoda review data through a clean API instead of maintaining a scraper

#### Real-world uses

- Pull every reachable review for your hotel and your five closest competitors, then compare per-aspect scores
- Feed review text into an LLM to summarise recurring complaints about breakfast, noise or cleanliness
- Track a property's rating trend month over month by re-running on a schedule
- Build a multilingual review corpus using the untranslated `originalComment` field
- Identify which traveller segments rate a property worst and why

***

### ✨ Key Features

- **Deep review extraction.** Sweeps Agoda's per-language filter (34 languages on the test property) and its six traveller-type filters, de-duplicating as it goes.
- **Multi-source data.** Agoda merges reviews from Booking.com, Priceline and partner sites. Each review is labelled with its `providerName` so you always know the source.
- **Both languages, always.** `reviewComments` gives you the translation in your chosen language; `originalComment` and `originalLanguage` preserve what the guest actually wrote.
- **Rich property summary.** Every record includes the aggregate score, per-aspect grades (location, cleanliness, service, room comfort, value, facilities, food), rating distribution, per-traveller-type scores and topic sentiment tags.
- **40 fields per review** — rating, title, positives, negatives, merged text, reviewer name and country, traveller type, room type, length of stay, check-in/out dates, helpful votes, photo URLs and the hotel's own reply.
- **Photo URLs included**, fully qualified and ready to download.
- **Transparent coverage.** `reviewsCollected`, `reviewsAvailable` and a `partial` flag on every record, so you never mistake a throttled run for a complete one.
- **Choose your language.** 15 output languages, from English and Spanish to Japanese, Korean, Thai and Vietnamese.
- **Fast mode** for a cheap sample (~121 reviews in a single request) when you don't need everything.
- **Incremental saving.** Each hotel is written to the dataset the moment it finishes, so an interrupted run keeps what it already collected.

***

### 🧠 Why This Actor Is Different

**It doesn't stop where Agoda's page stops.** A straightforward scraper paginates the review list and hits Agoda's ceiling at around 121 reviews per property — no matter how many pages it requests or how it sorts. This Actor uses Agoda's own language and traveller-type filters as a lever. Measured, on hotel 49487:

| Approach | Reviews returned |
|---|---|
| One plain API request (`fastMode`) | 121 |
| Re-sorting the list, all four sort orders | 121 — no gain |
| Language sweep | 611 |
| **Language + traveller-type sweep (default)** | **669 – 763** |

The range is real: Agoda intermittently answers a request with an empty list, so no two runs return exactly the same total. The Actor retries through that, and tells you via `partial` when it couldn't.

**It keeps the original text.** Most tools give you Agoda's machine translation and throw away what the guest actually typed. That is the difference between usable multilingual analysis and a lossy English-only corpus.

**It's honest about what it got.** Agoda signals rate limiting with an HTTP 200 and an empty review list — indistinguishable from "you've reached the end" unless you look closely. This Actor detects that difference, retries, and marks the record `partial: true` if anything was still missed. Silent truncation reported as success is the most common failure mode in review scrapers, and it's the one that quietly corrupts your analysis.

**It's cheap to run.** No headless browser, no CAPTCHA solver — just HTTP requests. That means lower compute usage and faster runs than browser-based alternatives.

**It's structured for analysis.** One record per hotel with reviews nested inside, so hotel-level and review-level data never get tangled or duplicated across thousands of rows.

***

### ⚙️ Input Configuration

#### Minimal example

```json
{
  "startUrls": [
    { "url": "https://www.agoda.com/ibis-budapest-city/hotel/budapest-hu.html" }
  ]
}
```

#### Full example

```json
{
  "startUrls": [
    { "url": "https://www.agoda.com/ibis-budapest-city/hotel/budapest-hu.html" },
    { "url": "https://www.agoda.com/park-hyatt-tokyo/hotel/tokyo-jp.html" }
  ],
  "maxReviews": 500,
  "fastMode": false,
  "language": "en-us",
  "includeDemographicSweep": true,
  "requestDelayMs": 500,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

#### Field reference

| Field | Type | Default | What it does |
|---|---|---|---|
| `startUrls` | array | **required** | Agoda hotel URLs. The `/reviews/` version of a URL works too. |
| `maxReviews` | integer | `0` | Stop after this many reviews per hotel. `0` means collect everything reachable. |
| `fastMode` | boolean | `false` | One request per hotel instead of a full sweep. ~121 reviews rather than ~763. |
| `language` | string | `en-us` | Language Agoda translates reviews into. The original text is kept regardless. |
| `includeDemographicSweep` | boolean | `true` | Adds six traveller-type passes. Worth ~150 extra reviews; ignored in fast mode. |
| `requestDelayMs` | integer | `500` | Pause between requests. Raise it if you see throttling. |
| `proxyConfiguration` | object | Residential | Proxy settings. See Advanced Tips. |

**Supported `language` values:** `en-us`, `de-de`, `fr-fr`, `es-es`, `it-it`, `pt-pt`, `nl-nl`, `ru-ru`, `ja-jp`, `ko-kr`, `zh-cn`, `zh-tw`, `th-th`, `id-id`, `vi-vn`.

#### Tips for best results

- **Keep the residential proxy on**, especially for multiple hotels or scheduled runs — Agoda rate-limits per IP and a full sweep is 85–115 requests per hotel.
- **Use `fastMode` to test.** Validate your URLs and output shape cheaply before committing to a full run.
- **Set `maxReviews` if you only need a sample.** It stops the sweep early and cuts your run time proportionally.
- **Add hotels in batches, not hundreds at a time.** Each property takes several minutes for a complete sweep.
- **Copy URLs straight from your browser.** Any Agoda hotel page URL works; extra query parameters are harmless.

***

### 📤 Output Format

You get **one dataset record per hotel**. Property data sits at the top level; reviews are nested in a `reviews` array.

```jsonc
{
  "hotelId": 49487,
  "hotelName": "Ibis Budapest City",
  "url": "https://www.agoda.com/ibis-budapest-city/hotel/budapest-hu.html",
  "reviewsPageUrl": "https://www.agoda.com/ibis-budapest-city/reviews/budapest-hu.html",

  "score": 8.6,
  "scoreScale": 10,
  "scoreText": "Excellent",
  "reviewCount": 2022,
  "reviewCommentsCount": 2158,

  "gradesPerAspect": {
    "location": 9,
    "staffPerformance": 8.8,
    "cleanliness": 8.7,
    "roomComfort": 8.6,
    "valueForMoney": 8.5,
    "facilities": 8.2,
    "foodDining": 7.1
  },

  "providers": [
    { "providerId": 332,  "name": "Agoda",               "reviewCount": 167,  "textReviewCount": 70 },
    { "providerId": 3038, "name": "Booking.com",         "reviewCount": 1719, "textReviewCount": 769 },
    { "providerId": -999, "name": "Additional providers","reviewCount": 136,  "textReviewCount": 3 }
  ],

  "ratingDistribution": [
    { "bucket": "exceptional",       "name": "9+ Exceptional",       "count": 259 },
    { "bucket": "excellent",         "name": "8-9 Excellent",        "count": 197 },
    { "bucket": "very_good",         "name": "7-8 Very Good",        "count": 217 },
    { "bucket": "good",              "name": "6-7 Good",             "count": 87 },
    { "bucket": "below_expectation", "name": "<6 Below Expectation", "count": 79 }
  ],

  "travelerTypes": [
    { "id": 2, "name": "Couples",        "score": 8.7, "count": 641 },
    { "id": 3, "name": "Solo travelers", "score": 8.7, "count": 309 }
  ],

  "reviewTags": [
    { "tagName": "Location", "mentioned": 8, "positivePercentage": 100, "negativePercentage": 0 }
  ],

  "reviewsAvailable": 842,
  "reviewsCollected": 763,
  "partial": false,

  "reviews": [
    {
      "hotelId": 49487,
      "hotelName": "Ibis Budapest City",
      "hotelUrl": "https://www.agoda.com/ibis-budapest-city/hotel/budapest-hu.html",

      "hotelReviewId": 1057164279,
      "providerId": 332,
      "providerName": "Agoda",

      "rating": 9.6,
      "ratingText": "Exceptional",

      "reviewTitle": "I am satisfied with the Ibis Budapest City Hotel.",
      "reviewComments": "The cleaning was quick and the staff were friendly…",
      "reviewPositives": null,
      "reviewNegatives": null,
      "text": "The cleaning was quick and the staff were friendly…",

      "originalTitle": "이비스 부다페스트 시티 호텔 만족합니다.",
      "originalComment": "청소도 빠르고 직원들도 친절했어요…",
      "originalLanguage": "ko",
      "translatedTo": "en",

      "reviewDate": "2026-07-28T00:00:00+07:00",
      "checkInDate": "2026-07-20T00:00:00",
      "checkOutDate": "2026-07-26T00:00:00",
      "stayMonth": "July 2026",

      "reviewerName": "cho",
      "reviewerCountry": "South Korea",
      "reviewerCountryCode": "KR",
      "travelerType": "Solo traveler",
      "roomType": "Room with 1 double bed",
      "lengthOfStay": 6,

      "helpfulVotes": 0,
      "unhelpfulVotes": 0,
      "photos": ["https://pix6.agoda.net/generic/…jpeg"],

      "responderName": "Ibis Budapest City",
      "responseText": "Thank you for your wonderful review…",
      "responseDate": "2026-07-29T00:00:00"
    }
  ]
}
```

#### Property fields

| Field | Description |
|---|---|
| `hotelId`, `hotelName`, `url` | Agoda's numeric id, the property name, and the URL you supplied |
| `reviewsPageUrl` | Direct link to the property's review page on Agoda |
| `score`, `scoreScale`, `scoreText` | Aggregate rating (e.g. 8.6 out of 10, "Excellent") |
| `reviewCount` | Every rating Agoda counts, including score-only ratings with no text |
| `reviewCommentsCount` | A second count Agoda reports alongside `reviewCount`; passed through as-is |
| `gradesPerAspect` | Sub-scores: location, cleanliness, service, room comfort, value, facilities, food |
| `providers[]` | Each review source with its total and its text-review count |
| `ratingDistribution[]` | How many reviews fall in each rating band |
| `travelerTypes[]` | Score and review count per travel party, count-weighted across sources |
| `reviewTags[]` | Topics guests mention, with positive/negative sentiment percentages |
| `reviewsAvailable` | Agoda's estimate of reviews with text — see the FAQ, it's an estimate |
| `reviewsCollected` | How many this run actually retrieved |
| `partial` | `true` if rate limiting cut the sweep short — treat the record as incomplete |

#### Review fields

| Field | Description |
|---|---|
| `hotelReviewId` | Unique review id — use it to de-duplicate across runs |
| `providerId`, `providerName` | Which site the review came from |
| `rating`, `ratingText` | Score out of 10 and its label |
| `reviewTitle`, `reviewComments` | Title and body, translated into your chosen language |
| `reviewPositives`, `reviewNegatives` | Liked/disliked halves, where the source splits them |
| **`text`** | **The field to read.** Merges whichever fields the source filled in |
| `originalTitle`, `originalComment`, `originalLanguage` | What the guest actually wrote, untranslated |
| `reviewDate`, `checkInDate`, `checkOutDate`, `stayMonth` | When the review was posted and when the stay happened |
| `reviewerName`, `reviewerCountry`, `reviewerCountryCode` | Who wrote it and where they're from |
| `travelerType`, `roomType`, `lengthOfStay` | Travel party, room booked, nights stayed |
| `helpfulVotes`, `unhelpfulVotes` | Community votes on the review |
| `photos[]` | Fully qualified guest photo URLs |
| `responseText`, `responderName`, `responseDate` | The property's public reply |

#### Why you should read `text`, not `reviewComments`

Different sources fill different fields. Agoda's own reviews put everything in `reviewComments`. Booking.com reviews split into `reviewPositives` and `reviewNegatives` and usually leave `reviewComments` empty — in one measured run, 607 of 680 reviews came from Booking.com. `text` merges whichever the source used, so it's populated on virtually every row. The individual fields stay available if you need them separately.

***

### ▶️ How to Use

1. **Open the Actor** in the Apify Console and click **Try for free**.
2. **Paste your hotel URLs** into the *Start URLs* field — one per line, straight from your browser.
3. **Leave the proxy on Residential.** It's pre-filled and strongly recommended.
4. *(Optional)* Tick **Fast mode** for a quick, cheap sample first.
5. Click **Start**. Watch the log — it reports each hotel as it finishes.
6. **Download your data** from the *Storage* tab as JSON, CSV, Excel or XML — or fetch it from the API.

#### Run it on a schedule

Use Apify **Schedules** to re-run weekly or monthly and track how a property's reviews change. De-duplicate on `hotelReviewId` to append only new reviews.

#### Call it from code

```bash
curl -X POST "https://api.apify.com/v2/acts/YOUR_USERNAME~agoda-reviews-scraper/runs?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "startUrls": [{ "url": "https://www.agoda.com/ibis-budapest-city/hotel/budapest-hu.html" }],
    "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
  }'
```

Official clients are available for **JavaScript** and **Python**, and every run's dataset is reachable over the Apify API.

***

### 📈 Use Cases

**1. Competitive reputation benchmarking**
Scrape your hotel plus your closest competitors and compare `gradesPerAspect` side by side. You'll see precisely where you lose — cleanliness, breakfast, noise — instead of guessing from a single overall score.

**2. Guest sentiment analysis with AI**
Feed the `text` field into an LLM or sentiment model to surface recurring complaints and praise at scale. `reviewTags` gives you Agoda's own topic breakdown as a cross-check.

**3. Reputation monitoring over time**
Schedule monthly runs and track `score`, `ratingDistribution` and review volume. Catch a downward trend while you can still act on it.

**4. Market and location research**
Compare guest satisfaction across neighbourhoods, cities or star ratings before an acquisition or a new development. `travelerTypes` shows which segments a market actually serves.

**5. Agency reporting and lead generation**
Reputation-management and hospitality-marketing agencies use review data to build audit reports that win clients — showing a prospect exactly what guests complain about is a far stronger pitch than a generic deck.

**6. Multilingual research datasets**
Use `originalComment` and `originalLanguage` to build genuine multilingual corpora for translation, NLP or academic work.

***

### 🛠️ Advanced Tips

#### Proxy: what it does and doesn't buy you

Agoda rate-limits per exit IP, and a full sweep is roughly 85–115 requests per hotel, so residential proxy is pre-filled and is the right default — especially for multi-hotel runs, repeated runs, or anything on a schedule, where a single IP would accumulate limits.

Be aware of what it doesn't fix, though. Agoda's throttling is largely **random per request** rather than a durable per-IP ban: the same filter can return reviews on one attempt and an empty list seconds later on the same IP. What recovers those reviews is the Actor's retry ladder, not a new IP. In our tests a residential run returned 669 reviews and unproxied runs returned 680 and 763 — well within run-to-run variance, with no clear advantage either way on a single property. So use the proxy for the reasons above, but don't expect it to raise your review count on one hotel.

#### Tune your run for cost or completeness

| Goal | Settings |
|---|---|
| Cheapest sample | `fastMode: true` |
| Balanced | `maxReviews: 300`, `includeDemographicSweep: false` |
| Maximum coverage | Defaults, residential proxy, `requestDelayMs: 800` |

#### Scaling to many hotels

- Split large lists across several runs rather than one very long one — easier to monitor and retry.
- Raise `requestDelayMs` to 800–1500 when running many hotels, to trip the rate limiter less often.
- Check `partial` on each record and re-run just those hotels rather than the whole batch.
- Failed URLs are written to the `FAILED_TARGETS` record in the key-value store with the reason.

#### Building an incremental pipeline

`hotelReviewId` is stable across runs. Store the ids you've already seen and insert only new ones — that turns a weekly run into a cheap append rather than a full re-import.

***

### ❓ FAQ & Troubleshooting

**Why did I get fewer reviews than the number Agoda advertises?**
Agoda's headline count includes score-only ratings — guests who left a star rating but wrote nothing. Those are never served to anyone who isn't logged in, so no scraper can retrieve them. On our test property, 2,022 advertised ratings corresponded to several hundred reviews with actual text. `reviewsCollected` tells you what you got.

**What does `partial: true` mean?**
Rate limiting or an internal safety cap cut that hotel's sweep short, so some reachable reviews are probably missing. Re-run that hotel with a residential proxy and a higher `requestDelayMs`. We flag this deliberately — reporting a truncated run as complete would quietly corrupt your analysis.

**Is `reviewsAvailable` an exact total?**
No, it's an estimate. Agoda calculates it per request, and the same property has reported different figures depending on how the request was paginated. Use it as a rough coverage check; use `partial` as the reliable completeness signal.

**Do I need a proxy?**
Keep it on — it's pre-configured, and it matters as soon as you scrape more than one hotel or run on a schedule, because Agoda rate-limits per IP. On a single property we did not measure a clear gain from it; see *Proxy* under Advanced Tips for the detail.

**The run failed with "Agoda refused every attempt."**
Your IP is rate-limited. Enable or widen the residential proxy configuration and retry. If it persists, raise `requestDelayMs`.

**Can I get reviews in my own language?**
Yes — set `language` to any of the 15 supported locales. Agoda translates the reviews, and `originalComment` still holds what the guest wrote.

**Some reviews have `text: null`. Is that a bug?**
No. A few reviews genuinely carry only a rating. Some sources send a placeholder sentence ("This guest did not leave comments about this hotel"); we strip that rather than store it as if a guest wrote it, keeping the rating and dates, which are real.

**Can I scrape by hotel ID instead of URL?**
No — URLs only. Copy them from your browser.

**Can I filter to only recent reviews?**
Not through input. Collect the reviews and filter on `reviewDate` afterwards.

**How long does one hotel take?**
A full sweep is a few minutes per property. `fastMode` is seconds. Multiply by your URL count.

**How do I get a CSV or Excel file?**
Open the run's **Storage** tab and pick your format, or append `?format=csv` to the dataset API URL.

**Is web scraping Agoda legal?**
This Actor collects only publicly visible review data — no logins, no personal accounts. You are responsible for how you use the data, including complying with the GDPR and applicable local law. If you plan to republish reviews or store personal data, take your own legal advice.

***

### 📞 Support

Questions, bug reports and feature requests are welcome.

- **Email:** <me@ahmedhrid.com>
- **Issues:** Open an issue on the Actor's page in the Apify Store

When reporting a problem, please include the **run ID** and the hotel URL that failed. If you can, re-run it with the environment variable `APIFY_LOG_LEVEL=DEBUG` set — that records every request, retry and proxy rotation, and makes most issues diagnosable straight away.

***

**Keywords:** Agoda scraper, Agoda reviews scraper, hotel reviews scraper, Agoda API, web scraping, Apify Actor, hotel review data extraction, guest review analysis, hospitality data, travel data scraping, review monitoring, reputation management, Booking.com reviews, hotel sentiment analysis.

# Actor input Schema

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

Agoda hotel URLs to scrape, e.g. https://www.agoda.com/ibis-budapest-city/hotel/budapest-hu.html. The /reviews/ variant of a hotel URL works too.

## `maxReviews` (type: `integer`):

Stop after this many reviews per hotel. 0 means collect everything reachable.

## `fastMode` (type: `boolean`):

Fetch only the single default page of reviews (about 120 per hotel, one API call) instead of sweeping every review language. Much faster and cheaper, but on the test property that is 121 reviews against 670-760 for a full sweep.

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

Language Agoda should translate the reviews into. The untranslated text is kept in originalTitle/originalComment regardless.

## `includeDemographicSweep` (type: `boolean`):

After the language sweep, sweep six traveller types (solo, couple, family, business, …). On the test hotel this added 70-150 reviews that no language filter surfaced. Ignored in fast mode.

## `requestDelayMs` (type: `integer`):

Pause between API calls. Agoda throttles per exit IP by returning empty review lists; the actor detects that, retries and rotates its proxy session, but a delay keeps it from happening in the first place. A full sweep is roughly 85 calls per hotel (34 review languages plus the traveller-type pass), so this setting has a real effect on run time.

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

Recommended, and important once you scrape more than one hotel or run on a schedule: Agoda rate-limits per exit IP and a full sweep is 85-115 calls per hotel. Note that Agoda's throttling is largely random per request rather than a lasting per-IP ban, so the retry ladder recovers most reviews and a proxy did not measurably raise the count on a single property. The actor rotates to a fresh session whenever it detects throttling.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.agoda.com/ibis-budapest-city/hotel/budapest-hu.html"
    }
  ],
  "maxReviews": 0,
  "fastMode": true,
  "language": "en-us",
  "includeDemographicSweep": false,
  "requestDelayMs": 500,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Each record is one hotel. Top level: hotelId, hotelName, url, reviewsPageUrl, score out of scoreScale plus scoreText, reviewCount and reviewCommentsCount as Agoda reports them, gradesPerAspect (location, cleanliness, staffPerformance, roomComfort, valueForMoney, facilities, foodDining), providers\[] with each source's name, reviewCount and textReviewCount, ratingDistribution\[] by bucket, travelerTypes\[] with score and count per travel party, reviewTags\[] with per-topic sentiment, recentScores\[] per provider, and the coverage pair reviewsAvailable / reviewsCollected plus a `partial` flag that is true when throttling or the page cap cut the sweep short. Nested `reviews[]`: hotelReviewId, providerId and providerName (Agoda / Booking.com / Priceline / …), rating out of 10 and its rating text, title and body, the separate liked/disliked halves where the source splits them, a merged `text`, the untranslated originalTitle/originalComment plus source language, reviewer name, country, review count and expert flag, travel-party type, room type, length of stay, review and check-in/check-out dates, helpful and unhelpful votes, photo URLs, and the property's response.

# 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.agoda.com/ibis-budapest-city/hotel/budapest-hu.html"
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("reviewly/agoda-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 = {
    "startUrls": [{ "url": "https://www.agoda.com/ibis-budapest-city/hotel/budapest-hu.html" }],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("reviewly/agoda-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 '{
  "startUrls": [
    {
      "url": "https://www.agoda.com/ibis-budapest-city/hotel/budapest-hu.html"
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call reviewly/agoda-reviews-scraper --silent --output-dataset

```

## MCP server setup

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