# Agoda Scraper (`normdata/agoda-scraper`) Actor

Scrape Agoda: every hotel, apartment and hostel in any city with live prices for your dates, discounts, free cancellation, stars, guest scores, facilities, GPS and photos. Gets past the 1,000-result cap. Filter by price, stars, score, type, area. Optional reviews.

- **URL**: https://apify.com/normdata/agoda-scraper.md
- **Developed by:** [Norm Data](https://apify.com/normdata) (community)
- **Categories:** Travel, E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $13.00 / 1,000 properties

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

![Norm Data](https://raw.githubusercontent.com/FabriAV/normdata/refs/heads/main/assets/banner_norm2.png)

## 🏨 Agoda Scraper

Extract every hotel, apartment, resort, hostel and villa Agoda lists in any city, with **live prices for your dates**: price per night, total for your stay, the price before discount and the discount %, rooms left, free cancellation and its deadline, pay later, pay at the hotel and no-credit-card options. Each property comes with stars, guest score, review count, type, neighbourhood, address, GPS, distance from the centre, facilities, highlights, check-in times, spoken languages and photos. Turn on **reviews** to get guest reviews (Agoda and Booking.com) in the same row. Goes **past Agoda's 1,000-result cap**, so you get the whole city, not just the first pages.

### 🎯 Who uses it?

#### 🏨 Hotel owners and revenue managers

See what every competitor in your city charges for your dates, who is discounting, and who is almost sold out.

#### 📈 Travel and hospitality analysts

Compare supply, prices, star mix and guest scores across cities and neighbourhoods, or track prices toward an event.

#### 🧳 Travel startups, OTAs and content sites

Build "best hotels in X" lists, price maps, deal alerts or hotel databases with fresh data, GPS and photos.

#### 💬 Reputation teams

Pull the newest guest reviews with score, pros and cons, room type, traveller type and country.

### ✨ What it does

- **Cities or links.** Type city names, paste agoda.com city or search links, or both. Several cities in one run.
- **Live prices for your stay.** Check-in date (exact or "+14 days"), nights, rooms, adults and child ages. Prices in **36 currencies**.
- **The whole city.** Agoda stops at 1,000 results per search. This Actor splits the search by neighbourhood, property type and stars to collect everything, without duplicates.
- **Filters:** property type (32 types: hotel, apartment, resort, villa, hostel, ryokan, capsule hotel...), star rating, minimum guest score, minimum reviews, min and max price per night, 16 facilities (pool, gym, spa, parking, airport transfer, pets allowed...), neighbourhoods, free cancellation, pay at the hotel, no credit card, deals only.
- **Sorting:** recommended (Agoda's own order), lowest or highest price, best rated, most reviews, most stars, closest to the centre.
- **Sold-out properties** on request, to map total supply.
- **Optional photos and reviews** in the same row.

### 🏆 Why this scraper

- **Whole cities.** About 1,260 bookable properties in Lisbon in 2 minutes, 2,200 in Paris in 4 minutes. Other Agoda scrapers stop where Agoda's search stops.
- **Fast.** 300 properties in about 8 seconds, 1,000 in under a minute.
- **Everything in one row.** Prices, deal, cancellation and payment terms, scores, facilities, location, photos and reviews together.
- **Clean numbers.** Prices are numbers in your currency, distances in km, facilities and types with readable names.
- **No proxy needed.** Runs on Agoda's own public search, nothing extra to set up or pay for.

### ⚖️ How it compares

Based on each Actor's public input options (October 2026).

| Capability | This actor | knagymate Fast | bovi | bestscraper Property | datawebot Hotel |
|---|:--:|:--:|:--:|:--:|:--:|
| Several cities in one run | **yes** | no | yes | yes | no (hotel URLs) |
| Date, nights, rooms, adults | **yes** | yes | yes | yes | yes |
| Child ages | **yes** | count only | no | count only | count only |
| Currency | **36** | no | no | yes | 5 |
| Star rating filter | **yes** | no | no | no | no |
| Property type filter | **32 types** | no | no | no | no |
| Price filter (min and max) | **yes** | no | no | no | no |
| Guest score filter | **yes** | yes | no | no | no |
| Facility filter | **16** | no | no | no | no |
| Neighbourhood filter | **yes** | no | no | no | no |
| Free cancellation / pay at hotel / no card | **yes** | no | no | no | no |
| Sort order | **7 options** | 5 | no | 4 | no |
| Guest reviews in the same run | **yes** | no | yes | no | no |
| Proxy needed | **no** | | optional | optional | optional |

### 📦 What data you get

| Field | Description |
| --- | --- |
| `propertyId`, `name`, `localName`, `url`, `type` | Agoda ID, name (and local-language name), property page for your dates, and type (Hotel, Apartment, Resort, Hostel...). |
| `starRating` | Stars (0 for unrated). |
| `city`, `area`, `state`, `country`, `countryCode` | Location, with the neighbourhood Agoda files it under. |
| `address`, `postalCode`, `latitude`, `longitude` | Street address and GPS. |
| `distanceFromCenterKm`, `inCityCenter`, `nearPublicTransport` | Distance from the city centre and Agoda's location badges. |
| `searchCity` | Which of your cities found it. |
| `checkIn`, `checkOut`, `nights`, `rooms`, `adults`, `children`, `currency` | The stay the prices are for. |
| `available` | Bookable for your stay (false only with sold-out included). |
| `pricePerNight`, `totalPrice` | Price per room per night, and the total for all rooms and nights, before taxes as Agoda shows it. |
| `originalPricePerNight`, `discountPercent` | The crossed-out price and the % saved, when there is a deal. |
| `roomsLeft` | Rooms left at this price, when Agoda shows it. |
| `freeCancellation`, `freeCancellationUntil` | Whether the cheapest offer cancels for free, and until which date. |
| `payLater`, `payAtHotel`, `noCreditCard`, `insiderDeal` | Payment options and Agoda's member deal. |
| `roomBenefits` | What the cheapest offer includes (breakfast, Wi-Fi, parking...). |
| `reviewScore`, `reviewCount` | Guest score out of 10 and number of reviews. |
| `checkInTime`, `checkOutTime`, `spokenLanguages` | Check-in and check-out times and the staff's languages. |
| `facilities`, `highlights` | Facilities with readable names and Agoda's highlights. |
| `luxury`, `popular` | Agoda's luxury and popular badges. |
| `hostLevel`, `bedrooms`, `bathrooms`, `beds`, `sizeSqm` | For homes and apartments: host level and layout. |
| `image`, `images` | Main photo, plus up to 10 photo links *(optional)*. |
| `reviews` | *(optional)* `reviewId`, `rating`, `title`, `text`, `positives`, `negatives`, `date`, `stayedFrom`, `stayedTo`, `nights`, `roomType`, `travellerType`, `reviewerName`, `reviewerCountry`, `source` (Agoda or Booking.com), `helpfulVotes`, `language`. |
| `scrapedAt` | When the row was collected (UTC). |
| `error` | Only present when a property's reviews didn't load. |

#### Example row (trimmed)

```json
{
  "propertyId": 47948599,
  "name": "MASA Hotel & Spa Campo Grande Collection",
  "url": "https://www.agoda.com/masa-hotel-campo-grande/hotel/lisbon-pt.html?checkIn=2026-10-17&los=1&rooms=1&adults=2&children=0&currency=USD",
  "type": "Hotel",
  "starRating": 4,
  "city": "Lisbon",
  "area": "Sao Domingos de Benefica",
  "country": "Portugal",
  "countryCode": "PT",
  "address": "Campo Grande 56",
  "postalCode": "1700-093",
  "latitude": 38.75,
  "longitude": -9.1499996,
  "distanceFromCenterKm": 2.42,
  "nearPublicTransport": true,
  "checkIn": "2026-10-17",
  "checkOut": "2026-10-18",
  "currency": "USD",
  "available": true,
  "pricePerNight": 146.43,
  "totalPrice": 146.43,
  "originalPricePerNight": 182.61,
  "discountPercent": 20,
  "roomsLeft": 1,
  "freeCancellation": true,
  "freeCancellationUntil": "2026-10-12",
  "payLater": true,
  "roomBenefits": ["Breakfast for 2", "Free WiFi", "Free fitness center access"],
  "reviewScore": 8.7,
  "reviewCount": 13843,
  "checkInTime": "03:00 PM",
  "checkOutTime": "12:00 PM",
  "spokenLanguages": ["English", "French", "Spanish", "Portuguese", "..."],
  "facilities": ["Swimming pool", "Gym / fitness", "Spa / sauna", "Car park", "Airport transfer", "..."],
  "highlights": ["Swimming pool", "Free Wi-Fi in all rooms!", "Close to public transportation"],
  "image": "https://pix8.agoda.net/hotelImages/47948599/0/c13709c80274eb879bb4a30c865abde5.jpeg?ce=0",
  "reviews": [
    { "rating": 9.6, "title": "Great place to stay", "text": "Very nice and clean hotel with great value for the price. Would definitely return", "date": "2026-09-28", "nights": 2, "roomType": "Deluxe Double or Twin Room", "travellerType": "Solo traveler", "reviewerCountry": "Norway", "source": "Agoda" }
  ],
  "scrapedAt": "2026-10-03T23:29:10.588Z"
}
```

### 💡 Use cases

#### 🗺️ Every bookable property in Lisbon two weeks from now

```json
{ "cities": ["Lisbon"], "checkIn": "+14 days", "maxItems": null }
```

#### 💸 Cheapest 4 and 5 star hotels with free cancellation in Bangkok and Singapore

```json
{ "cities": ["Bangkok", "Singapore"], "checkIn": "2026-12-10", "nights": 3, "starRatings": ["4", "5"], "propertyTypes": ["34"], "freeCancellationOnly": true, "sortBy": "price_asc", "maxItems": 200 }
```

#### 👨‍👩‍👧 Family apartments with a pool in Paris, in euros

```json
{ "cities": ["Paris"], "checkIn": "+30 days", "nights": 5, "adults": 2, "childAges": ["4", "9"], "currency": "EUR", "propertyTypes": ["29", "120"], "facilities": ["93"], "minReviewScore": "8" }
```

#### 📍 One neighbourhood only, best rated first

```json
{ "cities": ["Tokyo"], "areas": ["Shinjuku"], "minReviews": 100, "sortBy": "rating" }
```

#### 💬 Most reviewed hotels with their latest reviews and photos

```json
{ "cities": ["Bali"], "sortBy": "reviews", "maxItems": 50, "includeReviews": true, "maxReviews": 50, "includeImages": true }
```

### ⚙️ How the input is organised

| Section | What it's for |
| --- | --- |
| **Maximum properties** | Always first, caps the whole run. Empty means no limit. |
| **Where** | Cities and agoda.com links. |
| **When and who** | Check-in date, nights, rooms, adults, child ages and currency. |
| **Filters** | Type, stars, guest score, reviews, price, facilities, neighbourhoods, payment and cancellation terms, deals, sold-out, sort order. |
| **What to include** | Photos and reviews (optional). |

### 💰 Pricing

Pay-per-event: a one-time **$0.003** when the run starts, plus a price per property saved to your dataset. The price depends on your Apify plan tier:

| Your Apify plan | Price per property |
| --- | --- |
| Free | $0.019 |
| Bronze | $0.017 |
| Silver | $0.015 |
| Gold / Platinum / Diamond | $0.013 |

Approximate total cost:

| Properties collected | Free | Bronze | Silver | Gold+ |
| --- | --- | --- | --- | --- |
| 100 | $1.30 | $1.20 | $1.10 | $1.00 |
| 1,000 | $19.00 | $17.00 | $15.00 | $13.00 |
| 10,000 | $130.00 | $120.00 | $110.00 | $100.00 |

**Guest reviews add-on:** when **Reviews** is on, each property saved with its reviews adds one more charge, however many reviews you ask for:

| Your Apify plan | Reviews add-on, per property |
| --- | --- |
| Free | $0.007 |
| Bronze | $0.006 |
| Silver | $0.0055 |
| Gold / Platinum / Diamond | $0.005 |

So 1,000 properties with reviews cost $18 on Gold ($13 + $5). Properties with no reviews, and runs with reviews off, pay only the base price. Photos are always included. No proxy costs. New Apify accounts start with $5 in free credit. On the Free plan a run saves up to 10 properties.

**Speed:** 300 properties in about 8 seconds, 1,000 in under a minute. A whole large city takes a few minutes, because Agoda limits how fast one visitor can search. Reviews add about a second per property.

### 🚀 Run it

1. Create a free Apify account with $5 in credit.
2. Open the Agoda Scraper.
3. Type a city (or keep the prefilled one), set your dates and guests, add filters, then click **Start**.
4. Export the results as CSV, Excel, JSON, or XML from the Dataset tab.

Run it programmatically through the Apify API (`run-sync-get-dataset-items`) or the ApifyClient for JavaScript and Python, and schedule it with Apify's built-in Scheduler to track prices daily.

### 🤖 Use with AI agents (MCP)

Give an AI agent live access to hotel prices through the Model Context Protocol:

```
claude mcp add --transport http apify "https://mcp.apify.com?tools=normdata/agoda-scraper"
```

Then prompt it in plain language to run the scraper and read back the results.

### 🔧 Troubleshooting

**A city was skipped.**
Use the English name ("Munich", not "München"). For names shared by several places add the country or paste the agoda.com city link.

**The log says the city has more properties than I got.**
Agoda's count includes properties with no rooms for your dates. Turn on **Include sold-out properties** to get them too (without prices).

**An area name wasn't found.**
The log lists the neighbourhoods Agoda uses for that city. Copy one of those names.

**Prices differ a little from the website.**
Prices are per room per night before taxes, as Agoda's search shows them. Your country, login and the app can change what Agoda shows you.

**The run slows down for a while.**
Agoda limits how fast one visitor can search. The Actor waits and carries on by itself; nothing is lost.

**Some rows have an `error`.**
That property's reviews didn't load. The rest of the row is complete.

### ❓ FAQ

| Question | Answer |
| --- | --- |
| Do I need an Agoda account? | No. Only public data is read. |
| Does it need a proxy? | No. |
| Are prices live? | Yes, read fresh on every run for the dates and guests you set. |
| Why must there be a date? | Agoda only prices with dates. Leave it empty and the stay starts two weeks from today. |
| Can I get more than 1,000 properties? | Yes. Leave the maximum empty and the Actor collects the whole city. |
| Can I track prices over time? | Yes. Schedule the same input daily with Apify's Scheduler and compare runs. |

### 🛡️ Limits & responsible use

This Actor reads only public data from Agoda. It never signs in and never books. Reviews contain text written by travellers: handle them in line with privacy law in your country, and use the data in line with Agoda's terms.

### 📧 Contact

Need a scraper for a different site, or found something wrong with this one? norm.data.scrapers@gmail.com

### 🧪 Local development

```powershell
bun install
bun run typecheck
bun test/qa.mjs
apify run
```

Local results are stored in `storage/datasets/default`.

# Actor input Schema

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

Stop after this many properties. Leave empty for no limit (every property that matches, even past Agoda's 1,000-result cap). The Apify Free plan is always capped at 10.

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

City names in English, e.g. "Lisbon", "Bangkok", "Tokyo". Add the country for ambiguous names ("Paris, France"). A number is read as an Agoda city ID.

## `urls` (type: `array`):

City pages (agoda.com/city/lisbon-pt.html) or search pages that carry a city ID (agoda.com/search?city=16364).

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

A date (2026-11-20) or a relative one ("+14 days").

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

Length of the stay (1 to 30).

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

Rooms to book (1 to 9). Prices are per room per night.

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

Adults in total (at least one per room).

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

One age (0 to 17) per child, e.g. 5 and 9 for two children. Leave empty for none.

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

Currency for every price.

## `propertyTypes` (type: `array`):

Keep only these types. Leave empty for all.

## `starRatings` (type: `array`):

Keep only these star ratings. "Unrated" covers apartments and homes without stars.

## `minReviewScore` (type: `string`):

Out of 10.

## `minReviews` (type: `integer`):

Skip places with fewer reviews than this.

## `minPrice` (type: `integer`):

Per room per night, in the chosen currency, before taxes and fees.

## `maxPrice` (type: `integer`):

Per room per night, in the chosen currency, before taxes and fees.

## `facilities` (type: `array`):

Keep only places with ALL of these.

## `areas` (type: `array`):

Keep only these areas of the city, as Agoda names them, e.g. "Baixa", "Alfama" in Lisbon or "Sukhumvit" in Bangkok. A partial name works. The log lists the city's areas if a name isn't found.

## `freeCancellationOnly` (type: `boolean`):

Keep only offers you can cancel for free.

## `payAtHotelOnly` (type: `boolean`):

Keep only offers you pay at the property.

## `noCreditCardOnly` (type: `boolean`):

Keep only offers you can book without a credit card.

## `dealsOnly` (type: `boolean`):

Keep only places showing a discount against their usual price.

## `includeSoldOut` (type: `boolean`):

Also save places with no rooms left for your stay (without prices). Off by default.

## `sortBy` (type: `string`):

Order of the results. Matters most when you set a Maximum.

## `includeImages` (type: `boolean`):

Adds "images": up to 10 photo links with captions per property. The main photo is always included.

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

Adds "reviews": newest guest reviews with score, title, text, pros and cons, stay dates, room, traveller type and country. Paid add-on: one extra charge per property saved with reviews (see Pricing).

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

How many of the newest reviews to keep per property.

## Actor input object example

```json
{
  "maxItems": 10,
  "cities": [
    "Lisbon"
  ],
  "checkIn": "+14 days",
  "nights": 1,
  "rooms": 1,
  "adults": 2,
  "currency": "USD",
  "freeCancellationOnly": false,
  "payAtHotelOnly": false,
  "noCreditCardOnly": false,
  "dealsOnly": false,
  "includeSoldOut": false,
  "sortBy": "recommended",
  "includeImages": false,
  "includeReviews": false,
  "maxReviews": 20
}
```

# Actor output Schema

## `properties` (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 = {
    "maxItems": 10,
    "cities": [
        "Lisbon"
    ],
    "checkIn": "+14 days"
};

// Run the Actor and wait for it to finish
const run = await client.actor("normdata/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 = {
    "maxItems": 10,
    "cities": ["Lisbon"],
    "checkIn": "+14 days",
}

# Run the Actor and wait for it to finish
run = client.actor("normdata/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 '{
  "maxItems": 10,
  "cities": [
    "Lisbon"
  ],
  "checkIn": "+14 days"
}' |
apify call normdata/agoda-scraper --silent --output-dataset

```

## MCP server setup

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