# Agoda Hotel Scraper — Prices, Reviews & Amenities (`bovi/agoda-scraper`) Actor

Scrape **Agoda** hotel property pages to extract **hotel name, star rating, review score, room types, amenities, coordinates, and images**. Input: property URLs or hotel IDs. Uses Agoda's internal **Cronos JSON API** — structural, no CSS classes, robust to HTML changes.

- **URL**: https://apify.com/bovi/agoda-scraper.md
- **Developed by:** [Vitalii Bondarev](https://apify.com/bovi) (community)
- **Categories:** Other
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 hotels

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 Hotel Scraper — Rooms, Reviews & Amenities | from $2/1K | No Login

**For travel tech teams, hotel chains, OTA intelligence platforms, and hospitality researchers** that need deep Agoda property data — rooms, amenities, sub-scores — without managing browser infrastructure.

**$2.00 per 1,000 hotels. Guest review comments (optional) add $0.50/1,000 reviews.** No Cloudflare, no login, no proxy required for standard volumes — Agoda's internal Cronos API has no anti-bot.

**Pricing example:** 50 hotels = **$0.10**. 500 hotels = **$1.00**. 500 hotels + 10 reviews each (5,000 reviews) = **$1.00 + $2.50 = $3.50** total.

**Standout feature: 6-sub-score `category_scores`** — cleanliness, facilities, location, roomComfort, service, valueForMoney. Most competitors return only the overall rating.

| Scraper | Price / 1k | Score distribution? | Per-room bed/size/view? | `parse_confidence`? |
|---|---|---|---|---|
| **This actor** | **$2** hotel + $0.50 reviews | **Yes** | **Yes** | **Yes** |
| huggable_quote/fast-agoda-hotel-scraper | from $3.50 | No | No | No |
| knagymate/fast-agoda-scraper | $5.00 | No | No | No (search-page, Cloudflare-exposed) |

Scrape **Agoda hotel data** at the field-completeness level competitors charge double for — and with a reliability guarantee none of them publish. Extract **hotel name, star rating, guest review score, per-category sub-scores, room types with bed/size/view, full amenity lists, nearby attractions, coordinates, and every photo URL** for any Agoda property. Search by **hotel name**, paste **property URLs**, or feed **hotel IDs** — your choice. **Pay per hotel result.**

Built on Agoda's internal **Cronos JSON API** — the same structured endpoint Agoda's own website calls. No fragile CSS-class scraping, no HTML parsing for data fields. Every record carries a `parse_confidence` score so you know instantly if anything drifted.

---

### Why This Agoda Scraper Wins

Most Agoda scrapers parse the rendered HTML or scrape the Cloudflare-protected search page — both break the moment Agoda reskins or tightens anti-bot. This actor takes a different path:

1. It resolves your input to a numeric **hotel ID** (from a name search, a URL, or directly).
2. It calls Agoda's **Cronos BelowFold JSON API** — one GET request returning the entire hotel record as structured JSON.
3. It maps that JSON with a **dual-path parser**: a primary path on the known keys, and a **structural fallback** that finds fields by shape (not by fixed location) if Agoda re-nests its payload.

| Endpoint | Anti-bot | Status |
|----------|----------|--------|
| Property page HTML | None detected | 200 OK confirmed |
| BelowFold JSON API | None detected | 200 OK confirmed |
| Suggest (name search) API | None detected | 200 OK confirmed |
| Review comments API | None detected | 200 OK confirmed |
| Search results page | Cloudflare | Not used (we don't need it) |

If Agoda ever changes its JSON shape, you don't get silent empty rows — you get a record with a **lowered `parse_confidence` and machine-readable `warnings`** telling you exactly which field fell back. That is the difference between a scraper you can trust in production and one you have to babysit.

---

### Why this beats the alternatives

The Agoda field on the Apify Store splits into two kinds of scraper, and this actor beats both:

- **Search-page scrapers** like `knagymate/fast-agoda-scraper` ($5/1k) scrape the one Agoda surface that *is* Cloudflare-protected, and return a thin record (name, price, rating, location) — **no rooms, no amenities, no score distribution, no confidence**. When Agoda tightens anti-bot, they stop. We never touch that page: we go straight to the Cronos **BelowFold JSON API** (no anti-bot, confirmed 200 OK), and rotate IP + retry on the rare block.
- **Detail scrapers** like `huggable_quote/fast-agoda-hotel-scraper` (from $3.50/1k, "22+ fields") are the strong incumbent — they *do* return per-category `reviewCategoryScores` and nearby `placesOfInterest` (so we don't pretend to uniquely own those). But their docs confirm **no score distribution, no per-room breakdown, no parse-confidence**.

| Capability | This actor | huggable_quote detail scraper | knagymate search scraper |
|---|---|---|---|
| Avoids Cloudflare search page | **Yes** (Cronos JSON API) | Yes (detail API) | **No** (scrapes search page) |
| Per-category sub-scores | Yes (6) | Yes (5) | No |
| **`score_distribution`** (counts per band) | **Yes** | No | No |
| **Per-room `bed` / `size` / `view`** | **Yes** | No | No |
| `amenity_groups` (grouped) | Yes | Flat list | No |
| `nearby_essentials` w/ `distance_km` | Yes | Attractions only | No |
| **`parse_confidence` + drift `warnings`** | **Yes** | No | No |
| Base price / 1k | **$2** | from $3.50 | $5 |

**The one-sentence edge:** the Agoda scraper that skips the Cloudflare search page entirely, adds the **score distribution** and **per-room (bed/size/view)** breakdown the best competitor omits, and tells you — via `parse_confidence` — the moment Agoda's JSON drifts, at **$2/1k** (vs $3.50–$5). Full breakdown in [`COMPETITIVE_EDGE.md`](./COMPETITIVE_EDGE.md).

---

### Three Ways to Input

#### Option A — search by hotel name (no URL hunting)

```json
{ "searchTerms": ["The Peninsula Bangkok", "Marina Bay Sands"] }
````

Each term is resolved through Agoda's suggest API to the matching hotel ID, then scraped. Best with a specific hotel name; broad city names return only the few top properties Agoda surfaces.

#### Option B — property URLs

```json
{
  "propertyUrls": [
    "https://www.agoda.com/the-peninsula-bangkok/hotel/bangkok-th.html"
  ]
}
```

#### Option C — hotel IDs

```json
{ "hotelIds": [10715, 197181] }
```

Mix and match all three in one run. Add `"includeReviews": true` and `"reviewsPerHotel": 20` to pull guest comments.

***

### Output Schema — Per Hotel

| Field | Type | Description |
|-------|------|-------------|
| `hotel_id` | integer | Agoda internal hotel ID |
| `hotel_name` | string | Hotel name |
| `former_name` | string | Previous name, if any |
| `accommodation_type` | string | "Hotel", "Apartment", "Villa", etc. |
| `address` | string | Full address |
| `city` / `country` / `area_name` | string | Location parts |
| `postal_code` | string | Postal/ZIP code |
| `location_highlight` | string | e.g. "800 meters from city center" |
| `star_rating` | float | Official star rating (1–5) |
| `review_score` | float | Agoda guest score (0–10) |
| `review_count` | integer | Number of verified reviews |
| `review_text` | string | Score label ("Exceptional", "Superb") |
| `category_scores` | object | Per-category 0–10: cleanliness, facilities, location, roomComfort, service, valueForMoney |
| `score_distribution` | object | Review counts per band (9+, 8–9, …) |
| `awards` | string | Awards & accolades, if listed |
| `price` / `currency` | float / string | Dateless baseline price (null if Agoda returns none) |
| `room_types` | array | Room type names |
| `rooms` | array | Rich per-room objects: name, bed, size, view, features, image\_count, thumbnail |
| `amenities` | array | Flat, de-duplicated amenity list |
| `amenity_groups` | object | Amenities grouped by category |
| `highlights` | array | Notable highlights |
| `nearby_attractions` | array | Attractions with distance text |
| `nearby_essentials` | array | Airports/transport with `distance_km` |
| `check_in_time` / `check_out_time` | string | When available |
| `description` | string | Full property overview |
| `image_url` | string | Hero image (CDN) |
| `image_count` | integer | Total photos available |
| `all_images` | array | Every photo URL |
| `lat` / `lng` | float | Coordinates |
| `property_url` | string | Agoda property page URL |
| `parse_confidence` | float | 0.0–1.0 structural parse-quality score |
| `warnings` | array | Machine-readable drift signals |
| `scraped_at` | string | ISO-8601 UTC timestamp |
| `reviews` | array | Guest comments (when `includeReviews=true`) |

#### Review record fields (when `includeReviews=true`)

`review_id`, `rating`, `title`, `comment`, `positives`, `negatives`, `check_in_month`, `review_date`, `reviewer_type`, `reviewer_country`, `room_type`, `stay_length`.

***

### Use Cases

#### Competitive hotel benchmarking

Compare star rating, overall score, and **per-category sub-scores** (cleanliness vs service vs value) across rival properties in one city. The `category_scores` field surfaces exactly where a competitor wins or loses — data most scrapers omit entirely.

#### Travel app & map enrichment

Hydrate hotel listings with amenities, room configurations, `nearby_attractions`, `nearby_essentials` (airport distance in km), `lat`/`lng`, and the full `all_images` gallery.

#### Reputation & sentiment monitoring

Track `review_score`, `review_count`, and `score_distribution` over time, and pull `includeReviews=true` to feed `comment`/`positives`/`negatives` into sentiment or theme-extraction pipelines.

#### Hospitality market research

Build datasets by city, country, or accommodation type. Filter on star rating, score, amenities, or room attributes (bed type, room size, view).

***

### Notes on Pricing Data

Agoda's BelowFold endpoint is dateless — it returns hotel metadata without a check-in window. The `price` field is `null` unless Agoda surfaces a dateless promotional price. The actor is honest about this: it never invents a `0`. For date-specific room rates, supply dates via the roadmap pricing option.

***

### Proxy

Defaults to **Apify Residential** proxy (`useApifyProxy: true`, groups `["RESIDENTIAL"]`) — recommended for production scale. The JSON API works from datacenter IPs in testing, but residential ensures reliability at volume. On a block, the actor **rotates to a fresh exit IP and retries with backoff** automatically. Proxy usage is billed to the run owner.

***

### Pricing

Pay per hotel result successfully scraped (`hotel-result` event, **$2.00/1k**). Guest review comments (`review-item` event, **$0.50/1k**) are charged separately when `includeReviews=true` — you only pay for reviews you actually pull. **Failed or blocked fetches are never charged.**

***

### FAQ

**Does this work outside Asia?** Yes. Agoda lists hotels globally; the API returns data for any indexed property.

**How do I find a property URL?** Open any hotel on agoda.com and copy the browser URL — or just use `searchTerms` with the hotel name.

**Is pricing real-time?** The `price` field reflects Agoda's dateless response. Date-specific rates require the pricing endpoint (roadmap).

**What is `parse_confidence`?** A 0.0–1.0 score per record. 1.0 means every expected field resolved on the primary path. A lower score with `warnings` means Agoda's structure drifted and a fallback path was used — your early-warning signal.

***

### parse\_confidence trust score

Every record carries a `parse_confidence` score (0.0–1.0) and a `warnings` list. The Cronos API dual-path parser flags drift loudly instead of returning silent empty rows.

### Use with AI agents (MCP)

This actor is available as an MCP tool for Claude, GPT-4o, or any MCP-compatible agent.

Config: https://mcp.apify.com/?tools=bovi/agoda-scraper

*Not affiliated with Agoda. Data is retrieved from publicly accessible Agoda property pages and internal APIs.*

### Integrations

Built for travel-tech teams and OTA intelligence platforms benchmarking hotel rates, amenities, and per-category guest scores — the JSON/dataset output drops into the tools you already run, no glue code:

- **n8n / Make / Zapier** — trigger a run or pipe every new dataset item into 500+ apps (Google Sheets, Airtable, Slack, HubSpot, your database) with no code: [n8n](https://docs.apify.com/platform/integrations/n8n), [Make](https://docs.apify.com/platform/integrations/make), [Zapier](https://docs.apify.com/platform/integrations/zapier).
- **Webhooks** — fire your own endpoint the moment a run finishes, to push results straight into your pipeline ([docs](https://docs.apify.com/platform/integrations/webhooks)).
- **MCP server** — expose this actor as a tool to Claude, Cursor, or any [MCP client](https://mcp.apify.com) so an AI agent can pull this data mid-conversation ([guide](https://blog.apify.com/how-to-use-mcp/)).
- **API & SDKs** — fetch the dataset as JSON, CSV, or Excel through the Apify REST API or the Python / JS SDKs.

See all [Apify integrations](https://apify.com/integrations).

# Actor input Schema

## `searchTerms` (type: `array`):

Free-text hotel names or destinations to look up — no URL hunting needed. Each term is resolved via Agoda's suggest API to one or more hotel IDs, then scraped. Works best with a specific hotel name (e.g. "Peninsula Bangkok", "Marina Bay Sands"). Broad city names (e.g. "Bangkok") return only the few top properties Agoda surfaces in its suggest box — for full city coverage, supply propertyUrls or hotelIds. Combine freely with the other inputs.

## `propertyUrls` (type: `array`):

List of Agoda hotel property page URLs to scrape. Each URL must be the full Agoda property page, e.g. https://www.agoda.com/the-peninsula-bangkok/hotel/bangkok-th.html. The actor extracts the hotel ID from the page and calls the internal JSON API — no HTML parsing needed. Find URLs by searching Agoda normally and copying the property link.

## `hotelIds` (type: `array`):

Alternative input: list of Agoda numeric hotel IDs. Each ID is the integer found in the Agoda Cronos API, e.g. \[10715, 197181]. Use this when you already know the hotel IDs from a previous run or from the Agoda URL structure. Example: \[10715]

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

When enabled, fetches up to reviewsPerHotel individual review comments for each hotel via the Agoda reviews API. Each review adds an extra API call. Reviews include reviewer rating, title, comment text, and check-in date. Default: false.

## `reviewsPerHotel` (type: `integer`):

Maximum number of review comments to fetch per hotel (only applies when includeReviews is enabled). Reviews are sorted by most recent. Range: 1–50. Default: 10.

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

Maximum total hotel records to return across all inputs. 0 = unlimited. Use to control cost — each hotel is one PPE charge regardless of how many reviews are fetched.

## `requestDelay` (type: `number`):

Seconds to wait between consecutive property fetches. Default 1.5s is polite and reduces ban risk. Increase for large batches.

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

Proxy settings. Default: Apify RESIDENTIAL proxy (recommended for production scale). Property pages and JSON API calls work from datacenter IPs in testing, but RESIDENTIAL ensures reliability at volume. Set useApifyProxy:true with groups:\["RESIDENTIAL"].

## Actor input object example

```json
{
  "searchTerms": [
    "The Peninsula Bangkok"
  ],
  "includeReviews": false,
  "reviewsPerHotel": 10,
  "maxItems": 0,
  "requestDelay": 1.5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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 = {
    "searchTerms": [
        "The Peninsula Bangkok"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("bovi/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 = { "searchTerms": ["The Peninsula Bangkok"] }

# Run the Actor and wait for it to finish
run = client.actor("bovi/agoda-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchTerms": [
    "The Peninsula Bangkok"
  ]
}' |
apify call bovi/agoda-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=bovi/agoda-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Agoda Hotel Scraper — Prices, Reviews & Amenities",
        "description": "Scrape **Agoda** hotel property pages to extract **hotel name, star rating, review score, room types, amenities, coordinates, and images**. Input: property URLs or hotel IDs. Uses Agoda's internal **Cronos JSON API** — structural, no CSS classes, robust to HTML changes.",
        "version": "0.1",
        "x-build-id": "HyJsJEUhBwL3rX3fB"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/bovi~agoda-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-bovi-agoda-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/bovi~agoda-scraper/runs": {
            "post": {
                "operationId": "runs-sync-bovi-agoda-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/bovi~agoda-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-bovi-agoda-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "searchTerms": {
                        "title": "Search by hotel name or destination",
                        "type": "array",
                        "description": "Free-text hotel names or destinations to look up — no URL hunting needed. Each term is resolved via Agoda's suggest API to one or more hotel IDs, then scraped. Works best with a specific hotel name (e.g. \"Peninsula Bangkok\", \"Marina Bay Sands\"). Broad city names (e.g. \"Bangkok\") return only the few top properties Agoda surfaces in its suggest box — for full city coverage, supply propertyUrls or hotelIds. Combine freely with the other inputs.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "propertyUrls": {
                        "title": "Hotel Property URLs",
                        "type": "array",
                        "description": "List of Agoda hotel property page URLs to scrape. Each URL must be the full Agoda property page, e.g. https://www.agoda.com/the-peninsula-bangkok/hotel/bangkok-th.html. The actor extracts the hotel ID from the page and calls the internal JSON API — no HTML parsing needed. Find URLs by searching Agoda normally and copying the property link.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "hotelIds": {
                        "title": "Hotel IDs (numeric)",
                        "type": "array",
                        "description": "Alternative input: list of Agoda numeric hotel IDs. Each ID is the integer found in the Agoda Cronos API, e.g. [10715, 197181]. Use this when you already know the hotel IDs from a previous run or from the Agoda URL structure. Example: [10715]",
                        "items": {
                            "type": "integer"
                        }
                    },
                    "includeReviews": {
                        "title": "Include Review Comments",
                        "type": "boolean",
                        "description": "When enabled, fetches up to reviewsPerHotel individual review comments for each hotel via the Agoda reviews API. Each review adds an extra API call. Reviews include reviewer rating, title, comment text, and check-in date. Default: false.",
                        "default": false
                    },
                    "reviewsPerHotel": {
                        "title": "Reviews per hotel",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Maximum number of review comments to fetch per hotel (only applies when includeReviews is enabled). Reviews are sorted by most recent. Range: 1–50. Default: 10.",
                        "default": 10
                    },
                    "maxItems": {
                        "title": "Max hotels (total)",
                        "minimum": 0,
                        "maximum": 100000,
                        "type": "integer",
                        "description": "Maximum total hotel records to return across all inputs. 0 = unlimited. Use to control cost — each hotel is one PPE charge regardless of how many reviews are fetched.",
                        "default": 0
                    },
                    "requestDelay": {
                        "title": "Delay between requests (seconds)",
                        "minimum": 0,
                        "maximum": 30,
                        "type": "number",
                        "description": "Seconds to wait between consecutive property fetches. Default 1.5s is polite and reduces ban risk. Increase for large batches.",
                        "default": 1.5
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Proxy settings. Default: Apify RESIDENTIAL proxy (recommended for production scale). Property pages and JSON API calls work from datacenter IPs in testing, but RESIDENTIAL ensures reliability at volume. Set useApifyProxy:true with groups:[\"RESIDENTIAL\"].",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ]
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
