# Agoda Scraper \[Only $1.5💰] | Hotel Prices | Reviews | Photos (`ahmed_jasarevic/agoda-scraper`) Actor

Scrape Agoda hotels for price monitoring and travel market research: nightly rates, star ratings, review scores, amenities, photos and geo-coordinates, for any city, date and currency.

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

## Pricing

from $0.80 / 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/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

## Agoda Scraper

Scrape Agoda hotel listings and guest reviews for hotel price monitoring, travel market research and building hotel databases: nightly rates, star ratings, review scores, amenities, photos, addresses and geo-coordinates, for any city, check-in date, stay length and currency.

This actor does not use a browser. It calls the same internal JSON surfaces the Agoda website itself calls, so a full city search returns in seconds and stays cheap to run.

### Main Use Cases

- Hotel price monitoring and nightly rate tracking across a market
- Travel market research and OTA competitor rate comparison
- Building structured hotel databases city by city, with geo-coordinates
- Guest review and sentiment analysis (ratings, positives, negatives, traveler type)
- Destination and accommodation supply research for travel products
- Affiliate and price-comparison content refreshed on a schedule

### How It Works

Agoda's website resolves a place name into a city ID, then runs a GraphQL search to return priced properties, then loads guest reviews from a separate endpoint. This actor drives those same three surfaces directly over plain HTTP, so there is no browser and no page rendering to slow the crawl down.

| Step | Method | Endpoint | Purpose |
| --- | --- | --- | --- |
| 1. Resolve destination | GET | `https://www.agoda.com/api/cronos/search/GetUnifiedSuggestResult/3/1/1/0/` | Turn a city or place name into an Agoda city ID. |
| 2. Search hotels | POST | `https://www.agoda.com/graphql/search` (operationName `citySearch`) | Return up to 45 priced properties per page, up to 3 pages per destination. |
| 3. Guest reviews | POST | `https://www.agoda.com/api/cronos/property/review/ReviewComments` | Paginate guest reviews for a property (up to 6 pages). |

Destinations, search pages and review requests all run concurrently, so a multi-city run finishes in a few seconds. Requests can be routed through the standard Apify proxy configuration.

### Extract Agoda Hotel Prices And Availability Without An Official API

Agoda publishes a Content API and a Search API, but both are partner-onboarding programs (you need an approved site ID and API key, and a partnership model such as Online Affiliate, Fulfill Assisted or Partner Fulfillment). There is no self-serve endpoint that returns search results and prices for a city. This actor reaches the same public data the website shows to a visitor, without a partner contract:

- Search by destination name (resolved to a city ID automatically) or by Agoda city ID.
- Price the result for a specific check-in and check-out date, occupancy (adults, children, rooms) and currency.
- Return star ratings, review scores and review counts alongside each rate.
- Page through results per destination (up to 3 pages, 45 properties per page, 135 per destination) and cap the whole run at 1,000 properties.

### Scrape Agoda Guest Reviews For Sentiment And Rating Analysis

When guest reviews are enabled, the actor fetches the review feed for each property and writes one row per review to a separate `reviews` dataset, joined to the Hotels dataset on `propertyId`. Each review carries the rating, title, comment text, positives, negatives, reviewer name and country, traveler type, room type, review date and helpful votes. This is the dataset to use for rating distribution, sentiment and complaint analysis.

### Input Parameters

| Field | Type | Required | Default | Notes |
| --- | --- | --- | --- | --- |
| `destinations` | array | No | `["Bangkok"]` | City or place names to search. Each is resolved to an Agoda city ID automatically. |
| `cityIds` | array | No | `[]` | Search these Agoda city IDs directly (for example 9395 = Bangkok, 15470 = Paris). Use when a destination name does not resolve correctly. |
| `checkIn` | string | No | about 30 days from today | Check-in date in YYYY-MM-DD format. |
| `checkOut` | string | No | one day after check-in | Check-out date in YYYY-MM-DD format. |
| `currency` | string | No | `USD` | ISO currency code for prices, for example USD, EUR or GBP. |
| `adults` | integer | No | `2` | Number of adults per room. |
| `children` | integer | No | `0` | Number of children. |
| `rooms` | integer | No | `1` | Number of rooms. |
| `maxResultsPerDestination` | integer | No | `45` | Maximum properties returned per destination (max 135). |
| `maxPropertiesPerRun` | integer | No | `1000` | Hard safety cap across all destinations (max 1000). |
| `destinationConcurrency` | integer | No | `6` | How many destinations are searched at the same time. |
| `pageConcurrency` | integer | No | `3` | How many search pages are fetched in parallel per destination (1 to 3). |
| `reviewConcurrency` | integer | No | `10` | Parallel review requests, used only when reviews are enabled. |
| `includeReviews` | boolean | No | `false` | Fetch guest reviews into a separate dataset and bill one REVIEW_FETCHED event per review. |
| `maxReviewsPerProperty` | integer | No | `10` | Maximum reviews per property (max 50), used only when reviews are enabled. |
| `proxy` | object | No | Apify Proxy off | Proxy configuration used for the requests. |

### Output Fields

#### Hotels dataset (default)

One item per Agoda property found by the search. Prices are specific to the `checkIn`/`checkOut` dates, occupancy and currency in the input.

- `propertyId`, `name`, `url`: Agoda property ID, name and property page URL.
- `starRating`, `reviewScore`, `reviewCount`: starred rating, Agoda review score (0 to 10) and review count.
- `propertyType`, `accommodationType`: property type and accommodation type ID.
- `address`, `latitude`, `longitude`, `distanceFromCityCenterMeters`: address object, geo-coordinates and distance from the city centre.
- `images`, `facilities`: photo URLs and facility list.
- `price`: price object for the requested dates, occupancy and currency.
- `destination`, `cityId`, `checkIn`, `checkOut`: the search context that produced the row.
- `scrapedAt`: ISO 8601 scrape timestamp.

Dataset views: `overview` and `cheapest`.

#### Reviews dataset (only when `includeReviews` is enabled)

One item per guest review, joined to Hotels on `propertyId`.

- `propertyId`, `propertyName`, `cityId`, `destination`: the property and search context.
- `checkIn`, `checkOut`: the search dates the review feed was read for.
- `reviewId`, `rating`, `title`, `comment`, `positives`, `negatives`: the review itself.
- `reviewerName`, `reviewerCountry`, `travelerType`, `roomType`: reviewer attributes.
- `reviewDate`, `checkInDate`, `helpfulVotes`: dates and helpful vote count.
- `scrapedAt`: ISO 8601 scrape timestamp.

Dataset view: `overview`.

### Example Input And Output

Example input:

```json
{
  "destinations": ["Bangkok", "Paris"],
  "checkIn": "2026-11-10",
  "checkOut": "2026-11-12",
  "currency": "USD",
  "adults": 2,
  "rooms": 1,
  "maxResultsPerDestination": 45,
  "includeReviews": true,
  "maxReviewsPerProperty": 10
}
```

Example Hotels row:

```json
{
  "propertyId": 1234567,
  "name": "Example Riverside Hotel Bangkok",
  "url": "https://www.agoda.com/example-riverside-hotel/hotel/bangkok-th.html",
  "starRating": 4,
  "reviewScore": 8.4,
  "reviewCount": 1523,
  "propertyType": "Hotel",
  "latitude": 13.7245,
  "longitude": 100.5142,
  "distanceFromCityCenterMeters": 1800,
  "price": { "currency": "USD", "perNight": 62.5, "total": 125 },
  "destination": "Bangkok",
  "cityId": 9395,
  "checkIn": "2026-11-10",
  "checkOut": "2026-11-12",
  "scrapedAt": "2026-10-13T09:00:00.000Z"
}
```

Example Reviews row:

```json
{
  "propertyId": 1234567,
  "propertyName": "Example Riverside Hotel Bangkok",
  "cityId": 9395,
  "destination": "Bangkok",
  "reviewId": 99887766,
  "rating": 9.2,
  "title": "Great location",
  "comment": "Clean room and friendly staff, close to the river.",
  "positives": "Location, staff",
  "negatives": "Breakfast could be better",
  "reviewerName": "Alex",
  "reviewerCountry": "United Kingdom",
  "travelerType": "Couple",
  "roomType": "Deluxe",
  "reviewDate": "2026-09-02",
  "helpfulVotes": 4,
  "scrapedAt": "2026-10-13T09:00:05.000Z"
}
```

### Integrations & Automation

Results are written to Apify datasets, so you can export them as JSON, CSV or Excel, read them through the Apify API, or push them onward with webhooks. Connect the actor to Zapier or Make to load rows into a spreadsheet, a database or a BI tool.

For price monitoring, schedule the actor daily or every few hours with the dates shifted forward, so each run tracks the same market over time. For slower market research, a weekly schedule is usually enough. Recurring runs also help the actor surface better in the Apify Store.

### Related Actors

- [knagymate/fast-agoda-scraper](https://apify.com/knagymate/fast-agoda-scraper)
- [bovi/agoda-scraper](https://apify.com/bovi/agoda-scraper)
- [knagymate/fast-agoda-reviews-scraper](https://apify.com/knagymate/fast-agoda-reviews-scraper)
- [datawebot/agoda-hotel-scraper](https://apify.com/datawebot/agoda-hotel-scraper)
- [corent1robert/booking-hotel-search](https://apify.com/corent1robert/booking-hotel-search)

### FAQ

#### Is there an official Agoda API?

There are two official Agoda APIs, the Content API and the Search API, but both are partner programs. Access requires onboarding, an approved site ID and API key, and a partnership model (Online Affiliate / MSE, Fulfill Assisted or Partner Fulfillment). There is no self-serve endpoint that returns city search results and prices, so teams that are not approved partners cannot use it for market research.

#### What are the alternatives to this actor for Agoda hotel data?

Alternatives include the official Agoda partner APIs (when you can get access), general travel data providers such as apibara-style auction and travel feeds, and other Apify Store actors that focus on Agoda reviews or Agoda hotel details. This actor is the option that returns both hotel rates and reviews from a single run, priced per item.

#### Can I monitor Agoda prices daily?

Yes. Schedule the actor with a check-in date a fixed number of days ahead and keep the same destinations, so each run records the same search over time. The `price` object uses the dates, occupancy and currency from the input, so keep those constant between runs for comparable tracking.

#### Does the actor work for any city and currency?

Yes, as long as Agoda lists the destination. You can pass a place name in `destinations` (resolved automatically) or an exact Agoda city ID in `cityIds`. Any ISO currency code is accepted in `currency`.

#### Does it return guest reviews as well?

Yes, when `includeReviews` is set to true. Reviews go into a separate `reviews` dataset, one row per review, joined to the Hotels dataset on `propertyId`. Each review fetch is billed as a REVIEW_FETCHED event.

#### Do I need a proxy?

No. Agoda responds to plain requests, so the actor works without a proxy. You can attach an Apify proxy in `proxy` if you want to spread the load or avoid rate limiting on very large runs.

### SEO Keywords

agoda scraper, agoda hotel scraper, scrape agoda hotels, agoda hotel prices, agoda reviews scraper, agoda api, agoda hotel dataset, hotel price monitoring, hotel rate tracking, travel market research, hotel database, agoda city id, hotel availability data, ota price comparison, hotel review sentiment analysis, bangkok hotel prices, paris hotel rates, dubai hotel data, hotel amenities data, hotel competitor analysis, agoda data extraction, travel data export, hotel ratings scraper, agoda without api

### For AI Agents & LLM Apps

Purpose: return Agoda hotel rows (with nightly prices, ratings and coordinates) and, optionally, guest review rows, for a set of destinations.

Minimal working input:

```json
{ "destinations": ["Bangkok"] }
```

Variant that reads reviews and uses exact city IDs:

```json
{ "cityIds": ["9395"], "includeReviews": true, "maxReviewsPerProperty": 10 }
```

Output fields: Hotels dataset: `propertyId`, `name`, `url`, `starRating`, `reviewScore`, `reviewCount`, `propertyType`, `accommodationType`, `address`, `latitude`, `longitude`, `distanceFromCityCenterMeters`, `images`, `facilities`, `price`, `destination`, `cityId`, `checkIn`, `checkOut`, `scrapedAt`. Reviews dataset: `propertyId`, `propertyName`, `cityId`, `destination`, `checkIn`, `checkOut`, `reviewId`, `rating`, `title`, `comment`, `positives`, `negatives`, `reviewerName`, `reviewerCountry`, `travelerType`, `roomType`, `reviewDate`, `checkInDate`, `helpfulVotes`, `scrapedAt`.

Behaviors an agent should know:

- `destinations` and `cityIds` are both honoured; a place name is resolved to a city ID automatically, while `cityIds` are used as given.
- `adults`, `children`, `rooms`, `currency`, `checkIn` and `checkOut` directly change the returned `price`. Keep them fixed across runs to compare like for like.
- `maxResultsPerDestination` is capped at 135 and `maxPropertiesPerRun` at 1000; leaving them unset uses the defaults (45 and 1000).
- `includeReviews` defaults to false. Turning it on adds one billed REVIEW_FETCHED event per review and writes to a second dataset.
- `maxReviewsPerProperty` is capped at 50 and only applies when `includeReviews` is true.

Billing: pay-per-event. `apify-actor-start` (about $0.00005), one `apify-default-dataset-item` per hotel row (about $0.0015, less at higher loyalty tiers) and one REVIEW_FETCHED per review (about $0.0009, less at higher tiers).

### Legal & Compliance Disclaimer

This actor is independent and is not affiliated with, endorsed by or sponsored by Agoda or Agoda Company Pte. Ltd. It reads only publicly available pages and the public JSON surfaces the site itself calls: it does not log in, does not bypass authentication and does not solve CAPTCHAs.

Users are responsible for complying with Agoda's Terms of Service and with applicable data-protection law (for example GDPR or CCPA) in their own jurisdiction. Where the output contains reviewer names or other personal data, that data must not be used for unsolicited commercial outreach in violation of applicable law.

# Actor input Schema

## `destinations` (type: `array`):

City / place names to search, e.g. "Bangkok", "Paris", "New York". Each is resolved to an Agoda city ID automatically.

## `cityIds` (type: `array`):

Optional. Search these Agoda city IDs directly (e.g. 9395 = Bangkok, 15470 = Paris). Use this if a destination name does not resolve correctly.

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

Check-in date in YYYY-MM-DD format. Defaults to ~30 days from today.

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

Check-out date in YYYY-MM-DD format. Defaults to one day after check-in.

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

ISO currency code for prices, e.g. USD, EUR, GBP.

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

Number of adults per room.

## `children` (type: `integer`):

Number of children.

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

Number of rooms.

## `maxResultsPerDestination` (type: `integer`):

Maximum number of properties to return per destination (max 135).

## `maxPropertiesPerRun` (type: `integer`):

Hard safety cap for the whole run, across all destinations (max 1000).

## `destinationConcurrency` (type: `integer`):

How many destinations are searched at the same time. Higher = faster, but more likely to hit Agoda rate limits.

## `pageConcurrency` (type: `integer`):

How many search pages are fetched in parallel per destination (1-3).

## `reviewConcurrency` (type: `integer`):

How many review requests run in parallel (only used when guest reviews are enabled).

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

Fetch guest reviews for each property and write them to a separate "reviews" dataset (one item per review, joined to Hotels on propertyId). Adds one or more requests per property and is billed per review on pay-per-event accounts.

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

Maximum number of guest reviews to fetch per property (max 50). Only used when "Include guest reviews" is enabled.

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

Select proxies to be used by your crawler.

## Actor input object example

```json
{
  "destinations": [
    "Bangkok"
  ],
  "cityIds": [],
  "currency": "USD",
  "adults": 2,
  "children": 0,
  "rooms": 1,
  "maxResultsPerDestination": 45,
  "maxPropertiesPerRun": 1000,
  "destinationConcurrency": 6,
  "pageConcurrency": 3,
  "reviewConcurrency": 10,
  "includeReviews": false,
  "maxReviewsPerProperty": 10,
  "proxy": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `hotels` (type: `string`):

Properties found by the search, with nightly prices, ratings, photos, amenities and geo-coordinates.

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

Guest reviews, one item per review. Empty unless "Include guest reviews" was enabled in the input.

# 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 = {
    "destinations": [
        "Bangkok"
    ],
    "cityIds": [],
    "proxy": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed_jasarevic/agoda-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 = {
    "destinations": ["Bangkok"],
    "cityIds": [],
    "proxy": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("ahmed_jasarevic/agoda-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 '{
  "destinations": [
    "Bangkok"
  ],
  "cityIds": [],
  "proxy": {
    "useApifyProxy": false
  }
}' |
apify call ahmed_jasarevic/agoda-scraper --silent --output-dataset

```

## MCP server setup

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