# Agoda Hotel Rates Scraper (`xtracto/agoda-hotels-scraper`) Actor

Scrape Agoda hotels by destination or hotel ID: name, star rating, review score and count, live nightly price (with/without tax, before-discount), coordinates, address, and room offers. Pick your dates, guests, and currency. No login.

- **URL**: https://apify.com/xtracto/agoda-hotels-scraper.md
- **Developed by:** [Farhan Febrian Nauval](https://apify.com/xtracto) (community)
- **Categories:** Lead generation, Real estate
- **Features:** Limited permissions
- **Stats:** 54 total users, 11 monthly users, 87.5% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.99 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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 Hotel Rates Scraper

Extract hotels and live nightly prices from Agoda — by destination, by specific hotel, or as a **daily rate calendar per room type**. For every hotel you get its name, star rating, guest review score and review count, exact coordinates, address, the cheapest available price (with and without taxes/fees, plus the before-discount price), and the cheapest room offers with their cancellation policy. Choose your own check-in/check-out dates, number of guests, and currency.

### Why use this actor

- **No account, no login, no API key** required.
- **Real, dated prices** — the price for the exact stay dates, guests, and currency you ask for, not a vague "from" figure.
- **Three ways to search** — sweep every hotel in a destination, track specific hotels by their Agoda property ID, or pull a **daily rate calendar**: every room type and rate plan for every night in a date range (ideal for revenue management, rate parity and competitor monitoring).
- **Rich structured fields** — star rating, guest review score and count, latitude/longitude, full address, and per-room offers.
- **Any currency** — prices come back in the currency you choose (USD, EUR, SGD, GBP, …).
- **Stable JSON output** ready for spreadsheets, databases, dashboards, or pipelines. Export to JSON, CSV, or Excel.
- **Runs on a schedule** with automatic retries — no scrapers, browsers, or blocks to babysit.

### How it works

1. Choose a **mode**: *Search* a destination, or pull *Property* detail + rates for specific hotel IDs.
2. Enter your **destinations** (city or place names) or **hotel property IDs**, your **check-in / check-out** dates, **guests**, and **currency**.
3. The actor matches each place name to the right Agoda destination automatically, then collects every hotel with its live price and review data.
4. Each hotel becomes one clean row in your dataset, which you can download or feed into another system.

You do not manage any of the retrieval, retries, or formatting — just the inputs above.

### Input

#### Search mode

```json
{
  "mode": "search",
  "destinations": ["Singapore"],
  "checkIn": "2026-08-10",
  "checkOut": "2026-08-11",
  "adults": 2,
  "children": 0,
  "rooms": 1,
  "currency": "USD",
  "fetchRooms": true,
  "maxItems": 100,
  "maxItemsPerSearch": 200,
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}
```

#### Property mode (detail + rates for specific hotels)

```json
{
  "mode": "property",
  "propertyIds": ["185945"],
  "checkIn": "2026-08-10",
  "checkOut": "2026-08-11",
  "adults": 2,
  "children": 0,
  "rooms": 1,
  "currency": "EUR",
  "fetchRooms": true
}
```

| Field | Type | Description |
| --- | --- | --- |
| `mode` | string | `search` (find hotels in a destination) or `property` (detail + rates for specific hotel IDs). |
| `destinations` | array | City / place names to search, e.g. `Singapore`, `Tokyo`, `Bali`. Search mode. |
| `searchUrls` | array | Optional Agoda search URLs that contain a city id, e.g. `https://www.agoda.com/search?city=4064`. Search mode. |
| `propertyIds` | array | Agoda numeric hotel IDs, e.g. `185945` (Marina Bay Sands). Property mode. |
| `checkIn` | string | Check-in date `YYYY-MM-DD`. Defaults to ~30 days out. |
| `checkOut` | string | Check-out date `YYYY-MM-DD`. One night after check-in by default. |
| `adults` | integer | Adult guests to price for (default 2). |
| `children` | integer | Children in the party (default 0). |
| `rooms` | integer | Rooms to price (default 1). |
| `currency` | string | Currency code the prices are returned in, e.g. `USD`, `EUR`, `SGD`. |
| `fetchRooms` | boolean | Include the cheapest room offers (price + cancellation policy) on each record. |
| `maxItems` | integer | Overall cap on hotel records for the run (0 = no limit). |
| `maxItemsPerSearch` | integer | Cap per destination. Agoda serves 45 hotels per page. |
| `proxyConfiguration` | object | Residential proxy recommended for stable, geo-consistent results. |

#### Room rates mode (daily rates per room type)

```json
{
  "mode": "roomRates",
  "hotelUrls": ["https://www.agoda.com/harris-hotel-tuban/hotel/bali-id.html"],
  "propertyIds": ["64410066"],
  "dateFrom": "2026-11-01",
  "dateTo": "2026-11-30",
  "nights": 1,
  "adults": 2,
  "currency": "IDR"
}
```

| Field | Type | Description |
| --- | --- | --- |
| `hotelUrls` | array | Agoda hotel page URLs. The property ID is read from the page. |
| `propertyIds` | array | Agoda numeric hotel IDs (can be combined with `hotelUrls`). |
| `dateFrom` / `dateTo` | string | First and last check-in date of the calendar, `YYYY-MM-DD` (inclusive, up to 366 nights). Defaults to the next 30 nights. |
| `nights` | integer | Length of stay priced for each check-in date (default 1 = nightly rate). |
| `childAges` | array | Age of each child when `children` > 0. |
| `maxConcurrency` | integer | Nights fetched in parallel per hotel (default 4). |

### Output

#### Search mode — one row per hotel

```json
{
  "_input": "Singapore",
  "_source": "S1-citysearch",
  "_scrapedAt": "2026-07-09T20:36:50Z",
  "recordType": "HOTEL",
  "propertyId": 335555,
  "hotelName": "Dorsett Changi City Singapore",
  "starRating": 4.0,
  "reviewScore": 8.6,
  "reviewCount": 7860,
  "latitude": 1.3343963623046875,
  "longitude": 103.96414184570312,
  "address": "Changi, Singapore",
  "city": "Singapore",
  "cityId": 4064,
  "propertyType": "Hotel",
  "url": "https://www.agoda.com/dorsett-changi-city-singapore/hotel/singapore-sg.html",
  "checkIn": "2026-08-10",
  "checkOut": "2026-08-11",
  "occupancy": { "adults": 2, "children": 0, "rooms": 1 },
  "currency": "USD",
  "isAvailable": true,
  "soldOut": false,
  "cheapestPrice": 164.67,
  "priceInclusive": 197.43,
  "priceExclusive": 164.67,
  "beforeDiscountPrice": 164.67,
  "rooms": [
    {
      "roomName": null,
      "price": 164.67,
      "priceInclusive": 197.43,
      "beforeDiscountPrice": 164.67,
      "currency": "USD",
      "cancellation": "NonRefundable",
      "availableRooms": 65,
      "supplierId": 332
    }
  ]
}
```

#### Property mode — one row per hotel (detail + rates)

```json
{
  "_input": "185945",
  "_source": "S1-property",
  "_scrapedAt": "2026-07-09T20:37:12Z",
  "recordType": "PROPERTY",
  "propertyId": 185945,
  "hotelName": "Marina Bay Sands",
  "starRating": 5.0,
  "reviewScore": 8.9,
  "reviewCount": 48807,
  "latitude": 1.2836209535598755,
  "longitude": 103.86072540283203,
  "address": "10 Bayfront Avenue, Marina Bay, Singapore",
  "city": "Singapore",
  "cityId": 4064,
  "propertyType": "Hotel",
  "url": "https://www.agoda.com/marina-bay-sands/hotel/singapore-sg.html",
  "checkIn": "2026-08-10",
  "checkOut": "2026-08-11",
  "occupancy": { "adults": 2, "children": 0, "rooms": 1 },
  "currency": "EUR",
  "isAvailable": true,
  "soldOut": false,
  "cheapestPrice": 744.45,
  "priceInclusive": 892.60,
  "priceExclusive": 744.45,
  "beforeDiscountPrice": 744.45,
  "rooms": [
    {
      "roomName": null,
      "price": 744.45,
      "priceInclusive": 892.60,
      "beforeDiscountPrice": 744.45,
      "currency": "EUR",
      "cancellation": "FreeCancellation",
      "availableRooms": 50,
      "supplierId": 332
    }
  ]
}
```

| Field | Type | Description |
| --- | --- | --- |
| `propertyId` | integer | Agoda's unique hotel ID. |
| `hotelName` | string | Hotel name. |
| `starRating` | number | Official star rating (1–5). |
| `reviewScore` | number | Guest review score out of 10. |
| `reviewCount` | integer | Number of guest reviews. |
| `latitude` / `longitude` | number | Hotel coordinates. |
| `address` | string | Street/area, city, country. |
| `city` / `cityId` | string / integer | City name and Agoda city ID. |
| `propertyType` | string | e.g. Hotel, Resort, Apartment. |
| `url` | string | Agoda hotel page. |
| `checkIn` / `checkOut` | string | The dates the price applies to. |
| `occupancy` | object | Adults, children, rooms the price is for. |
| `currency` | string | Currency of all prices in the record. |
| `isAvailable` / `soldOut` | boolean | Availability for the requested stay. |
| `cheapestPrice` | number | Cheapest nightly price, excluding taxes/fees. |
| `priceInclusive` | number | Cheapest nightly price including taxes/fees. |
| `priceExclusive` | number | Cheapest nightly price excluding taxes/fees. |
| `beforeDiscountPrice` | number | Nightly price before any discount. |
| `rooms` | array | Cheapest available room offers (price, taxes, cancellation policy, rooms left). Present when `fetchRooms` is on. |

#### Room rates mode — one row per hotel x night x room type x rate plan

```json
{
  "_source": "S2-roomgrid",
  "recordType": "ROOM_RATE",
  "propertyId": 48690,
  "hotelName": "HARRIS Hotel Kuta Tuban Bali",
  "starRating": 4.0,
  "area": "Kuta",
  "checkIn": "2026-11-01",
  "checkOut": "2026-11-02",
  "roomTypeId": 3144655,
  "roomType": "HARRIS Room",
  "ratePlanId": 612127,
  "maxOccupancy": 2,
  "roomsLeft": 5,
  "breakfastIncluded": false,
  "freeCancellation": false,
  "cancellationPolicy": "Non-refundable (Low price!)",
  "payLater": false,
  "supplierId": 332,
  "supplier": "Agoda.com",
  "currency": "IDR",
  "price": 785124,
  "priceInclusive": 950000,
  "beforeDiscountPrice": 2539500,
  "totalStayInclusive": 950000,
  "soldOut": false
}
```

| Field | Type | Description |
| --- | --- | --- |
| `checkIn` / `checkOut` | string | The night (stay) this rate is for. |
| `roomTypeId` / `roomType` | number / string | Agoda room type. |
| `ratePlanId` | number | Rate plan of this offer (a room type usually has several: with/without breakfast, refundable or not). |
| `breakfastIncluded`, `freeCancellation`, `payLater` | boolean | Conditions of the rate plan. |
| `cancellationPolicy` | string | Short cancellation text as shown on Agoda. |
| `roomsLeft` | number | Rooms Agoda still sells at this rate. |
| `price` / `priceInclusive` | number | Nightly price without / with taxes and fees, in `currency` (exactly as Agoda shows it). |
| `beforeDiscountPrice` | number | Crossed-out nightly price (with taxes). |
| `totalStayInclusive` | number | Whole stay with taxes (equals `priceInclusive` when `nights` is 1). |
| `supplierId`, `supplier` | number / string | Who supplies the rate (`332` = Agoda.com). |
| `soldOut` | boolean | `true` on a row with no price: the room type is offered on other nights of the range but not on this one. |

### Notes & limits

- **Prices are per night** for the requested dates, guests, and rooms, in your chosen currency.
- **Search returns 45 hotels per page**; raise `maxItemsPerSearch` for more, or use several destinations for volume.
- A small share of hotels can show as sold out (no price) for a given date/occupancy — those rows carry `isAvailable: false`.
- In search results, room offers reflect the **cheapest** available option, so `roomName` may be blank; use **room rates mode** for every room type and rate plan of a hotel.
- Room rates mode makes one request per hotel per night: 30 nights for one hotel take well under a minute.
- For **rate-parity / price tracking**, run property mode on a schedule with the same `propertyIds` across different dates — each run captures that day's live price.
- Residential proxy (any country) is recommended for the most consistent results.

### Other travel actors

| Actor | What it does |
| --- | --- |
| Booking.com Hotels Scraper | Hotel search results from Booking.com by destination and dates. |
| Agoda Hotel Rates Scraper | This actor — Agoda hotels, live rates, and review data. |

# Actor input Schema

## `mode` (type: `string`):

'Search' finds all hotels in a destination with live prices. 'Property' pulls rich detail + the cheapest rates for specific hotels by their Agoda property ID. 'Room rates' lists every room type and rate plan (breakfast, cancellation, rooms left) for every night in a date range: a daily rate calendar per hotel.

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

City, region, or place names to search, e.g. Singapore, Tokyo, Bali. Each is matched to an Agoda destination automatically.

## `searchUrls` (type: `array`):

Paste Agoda search URLs that contain a city id, e.g. https://www.agoda.com/search?city=4064 . Used in Search mode alongside (or instead of) destinations.

## `propertyIds` (type: `array`):

Agoda numeric property IDs, e.g. 185945 (Marina Bay Sands). Used in Property and Room rates modes.

## `hotelUrls` (type: `array`):

Agoda hotel page URLs, e.g. https://www.agoda.com/harris-hotel-tuban/hotel/bali-id.html . The property ID is read from the page. Used in Room rates mode alongside (or instead of) property IDs.

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

Check-in date in YYYY-MM-DD format. Leave blank to default to about 30 days from today (Agoda rejects a past check-in date).

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

Check-out date in YYYY-MM-DD format. One night after check-in by default.

## `dateFrom` (type: `string`):

First check-in date of the daily rate calendar, YYYY-MM-DD. Defaults to tomorrow.

## `dateTo` (type: `string`):

Last check-in date of the daily rate calendar, YYYY-MM-DD (inclusive). Defaults to 30 nights from the first night. Up to 366 nights.

## `nights` (type: `integer`):

Nights per stay priced for every check-in date. 1 gives the nightly rate.

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

Number of adult guests to price the stay for.

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

Number of children in the party.

## `childAges` (type: `array`):

Age of each child, e.g. 5, 9. Missing ages default to 8. Used in Room rates mode.

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

Number of rooms to price.

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

ISO currency code the prices are returned in, e.g. USD, EUR, SGD, GBP.

## `fetchRooms` (type: `boolean`):

Add a list of the cheapest available room offers (price, cancellation policy) to each hotel record.

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

Overall cap on the number of hotels for the whole run. In Room rates mode each hotel gives many rows (one per night x rate plan).

## `maxItemsPerSearch` (type: `integer`):

Cap on hotels returned per destination. Agoda serves 45 hotels per page.

## `maxConcurrency` (type: `integer`):

How many nights are fetched at the same time per hotel.

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

Residential proxy is recommended for stable, geo-consistent results.

## Actor input object example

```json
{
  "mode": "search",
  "destinations": [
    "Singapore"
  ],
  "searchUrls": [],
  "propertyIds": [
    "185945"
  ],
  "hotelUrls": [],
  "nights": 1,
  "adults": 2,
  "children": 0,
  "childAges": [],
  "rooms": 1,
  "currency": "USD",
  "fetchRooms": true,
  "maxItems": 100,
  "maxItemsPerSearch": 200,
  "maxConcurrency": 4,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

One row per scraped record, stored in the run's default dataset.

# 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": [
        "Singapore"
    ],
    "searchUrls": [],
    "propertyIds": [
        "185945"
    ],
    "hotelUrls": [],
    "childAges": [],
    "currency": "USD"
};

// Run the Actor and wait for it to finish
const run = await client.actor("xtracto/agoda-hotels-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": ["Singapore"],
    "searchUrls": [],
    "propertyIds": ["185945"],
    "hotelUrls": [],
    "childAges": [],
    "currency": "USD",
}

# Run the Actor and wait for it to finish
run = client.actor("xtracto/agoda-hotels-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": [
    "Singapore"
  ],
  "searchUrls": [],
  "propertyIds": [
    "185945"
  ],
  "hotelUrls": [],
  "childAges": [],
  "currency": "USD"
}' |
apify call xtracto/agoda-hotels-scraper --silent --output-dataset

```

## MCP server setup

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