# Trip.com Reviews Scraper (`fetch_cat/trip-com-reviews-scraper`) Actor

Export bounded public Trip.com and Ctrip hotel review snapshots with ratings, guest text, stay details, replies, media URLs, and completeness warnings.

- **URL**: https://apify.com/fetch\_cat/trip-com-reviews-scraper.md
- **Developed by:** [Hanna Nosova](https://apify.com/fetch_cat) (community)
- **Categories:** Travel, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.35 / 1,000 review saveds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are 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/docs.md):

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

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.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/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

## Trip.com Reviews Scraper

Export bounded public Trip.com and Ctrip hotel review snapshots with ratings, guest text, stay details, owner replies, public media URLs, and explicit completeness warnings.

The Actor accepts hotel URLs or IDs and writes one paid dataset row per saved review. It is designed for small, permissioned public-page snapshots—not complete historical pagination.

### What does this Actor do?

- **Input:** Up to 100 public hotel URLs or numeric hotel IDs.
- **Output:** Review text, scores, stay and reviewer context, replies, media signals, source links, and snapshot completeness fields.
- **Public-page limit:** Trip.com normally embeds only a bounded newest-review page. `maxReviewsPerHotel` limits that page; it does not unlock older pages.
- **Diagnostics:** `RUN_SUMMARY` records every hotel outcome. `RUN_CHECKPOINT` preserves pending hotels before the safe deadline.
- **Access:** No login, cookies, CAPTCHA handling, automatic proxy escalation, or private account data.

### Use cases

- Export a small, permissioned hotel-review snapshot for service-quality analysis.
- Monitor newly embedded reviews with `sortBy: "newest"` and a `sinceDate` cutoff.
- Add public rating, stay, reply, and media context to an authorized hotel dataset.

### Ready-to-run examples

Each input example below is a tested public task that you can duplicate, adjust, and run with your own Apify account.

| Example | What it demonstrates |
| --- | --- |
| [Lowest-rated Trip.com reviews](https://apify.com/fetch_cat/trip-com-reviews-scraper/examples/trip-com-low-rating-reviews) | One hotel ID, 10 rows, `ratingLow`, and a compact review-only snapshot. |
| [Trip.com hotel reviews by ID](https://apify.com/fetch_cat/trip-com-reviews-scraper/examples/trip-com-hotel-reviews-by-id) | One hotel ID, 10 recommended rows, and hotel summary fields. |
| [Trip.com hotel reviews by URL](https://apify.com/fetch_cat/trip-com-reviews-scraper/examples/trip-com-hotel-reviews-by-url) | One public hotel URL, 10 newest rows, summary fields, and public image URLs when available. |

For interrupted multi-hotel work, rerun from the same key-value store with `resumeFromCheckpoint: true`. Only use resume after a prior attempt wrote pending targets to `RUN_CHECKPOINT`.

### Output fields

| Data group | Fields |
| --- | --- |
| Hotel identity | `hotelId`, `hotelName`, `hotelUrl`, `sourceDomain` |
| Review | `reviewId`, `reviewText`, `translatedReviewText`, `reviewDate`, `language` |
| Scores | `rating`, `ratingScale`, `ratingText`, `subRatings`, `helpfulVotes` |
| Stay | `stayDate`, `travelType`, `roomType` |
| Reviewer | `reviewerName`, `reviewerCountry`, `reviewerLevel`, `reviewerContributionCount` |
| Hotel reply | `ownerResponseText`, `ownerResponseDate` |
| Media | `imageUrls`, `videoUrls` |
| Provenance | `sourceUrl`, `scrapedAt`, `pageNumber`, `sortBy` |
| Completeness | `reviewsAvailable`, `reviewsExtracted`, `hasMoreReviews`, `warnings` |

Optional public fields are returned as `null` or an empty array. The Actor does not invent missing reviewer, stay, translation, reply, or media values.

### Example output

```json
{
  "hotelId": "129054778",
  "hotelName": "KOKO HOTEL Tokyo Nishikasai",
  "hotelUrl": "https://www.trip.com/hotels/tokyo-hotel-detail-129054778/koko-hotel-tokyo-nishikasai/",
  "sourceDomain": "www.trip.com",
  "reviewId": "2022013946",
  "reviewText": "A public guest review...",
  "translatedReviewText": null,
  "rating": 10,
  "ratingScale": 10,
  "ratingText": "Outstanding",
  "subRatings": { "cleanliness": 10, "service": 9.5 },
  "reviewDate": "2026-07-15",
  "stayDate": "2026-07-01",
  "travelType": "Business traveler",
  "roomType": "Standard Twin Room",
  "reviewerName": "Guest User",
  "reviewerCountry": "United States",
  "reviewerLevel": null,
  "reviewerContributionCount": 4,
  "ownerResponseText": null,
  "ownerResponseDate": null,
  "imageUrls": [],
  "videoUrls": [],
  "helpfulVotes": 2,
  "scrapedAt": "2026-07-20T00:00:00.000Z",
  "sourceUrl": "https://www.trip.com/hotels/tokyo-hotel-detail-129054778/koko-hotel-tokyo-nishikasai/",
  "pageNumber": 1,
  "sortBy": "newest",
  "reviewsAvailable": 922,
  "reviewsExtracted": 10,
  "hasMoreReviews": true,
  "warnings": [
    "Trip.com reports 922 reviews, but this public page exposed 15; output is a bounded page snapshot, not complete history."
  ]
}
````

### Input settings

| Setting | JSON key | Default | Description |
| --- | --- | --- | --- |
| Hotel URLs | `hotelUrls` | None | Public HTTPS Trip.com/Ctrip hotel URLs containing a numeric hotel ID. |
| Hotel IDs | `hotelIds` | None | Numeric hotel IDs with at least five digits. |
| Maximum reviews | `maxReviewsPerHotel` | `20` | Saves at most this many rows from each bounded public-page snapshot. Range: 1–1,000. |
| Sort | `sortBy` | `recommended` | Client-side order: `recommended`, `newest`, `ratingHigh`, or `ratingLow`. |
| Since date | `sinceDate` | None | Keeps embedded reviews on or after a valid `YYYY-MM-DD` date. |
| Include hotel summary | `includeHotelSummary` | `true` | Includes the public hotel name on review rows. Stable IDs and diagnostics remain present. |
| Include media URLs | `includeImages` | `true` | Includes public image and video URLs when present. No files are downloaded. |
| Locale | `locale` | `en-US,en;q=0.9` | `Accept-Language` value used for the public page request. |
| Currency | `currency` | `USD` | Compatibility field retained for existing workflows; review extraction does not depend on price currency. |
| Proxy configuration | `proxyConfiguration` | Disabled | Optional user-configured route. No proxy escalation occurs automatically. |
| Resume checkpoint | `resumeFromCheckpoint` | `false` | Reads pending hotels from `RUN_CHECKPOINT` in the same key-value store. |
| Work time | `maxRuntimeSecs` | `270` | Actor work budget from 31–270 seconds; at least 30 seconds remain for persistence and cleanup. |

At least one hotel URL or ID is required unless `resumeFromCheckpoint` is enabled. Missing input fails before the start charge or any network request.

### Run outcomes and completeness

The dataset contains paid review rows only. Hotel-level errors and legitimate empty outcomes stay in the unpaid `RUN_SUMMARY` record.

- **Confirmed empty:** Trip.com reports zero reviews. The hotel can finish with no rows and a successful summary.
- **Filtered empty:** The public page exposed reviews, but none matched `sinceDate`.
- **Incomplete snapshot:** `hasMoreReviews` is true and `warnings` explains the gap between the aggregate count and embedded rows.
- **Unexpected empty:** Trip.com reports reviews but exposes no recognized rows. That hotel is marked failed instead of silently succeeding.
- **Partial run:** Valid hotels retain their paid rows when another hotel fails.
- **Deadline stop:** Pending hotels and saved review keys are written to `RUN_CHECKPOINT` for idempotent resume.
- **Charge-limit stop:** Only rows accepted by the paid dataset operation count as saved. Remaining work is checkpointed when `maxTotalChargeUsd` is reached.

### Pricing

This Actor uses pay-per-event pricing. The start event is charged once after validation; the item event is coupled to each successfully persisted review row. Error and status diagnostics are not dataset rows and are not item-charged.

| Apify plan context | Start per run | Per saved review | Per 1,000 saved reviews |
| --- | ---: | ---: | ---: |
| Free | `$0.005` | `$0.000575` | `$0.575` |
| Starter / Bronze | `$0.005` | `$0.000500` | `$0.500` |
| Scale / Silver | `$0.005` | `$0.000425` | `$0.425` |
| Business / Gold | `$0.005` | `$0.000350` | `$0.350` |
| Platinum | `$0.005` | `$0.000275` | `$0.275` |
| Diamond | `$0.005` | `$0.000275` | `$0.275` |

The live Store pricing table controls the final charge shown before a run. This documentation reflects the active prices checked on July 20, 2026.

### Tips for reliable snapshots

- Start with one known public hotel and 5–10 reviews.
- Use `sortBy: "newest"` with `sinceDate` for repeat monitoring.
- Deduplicate appended snapshots downstream on `hotelId` plus `reviewId`.
- Inspect `hasMoreReviews` and `warnings`; never treat the dataset as complete review history when the public page exposes only a subset.
- If a page returns an access challenge, retry later with a smaller workload. The Actor does not solve CAPTCHAs or escalate routes automatically.

### Limits and responsible use

- This release supports the public server-rendered first-page snapshot only. It does not claim historical pagination.
- Trip.com/Ctrip can change page content, omit optional fields, return regional variants, or temporarily challenge requests.
- Hotel IDs and public payload availability vary between Trip.com and Ctrip surfaces. Check `RUN_SUMMARY` for each hotel outcome.
- The Actor does not use login sessions, private APIs, partner credentials, cookies, or account-only data.
- Trip.com’s current terms restrict commercial use of Website content without a licence. Use this Actor only when you have permission or another lawful basis covering your collection, export, retention, and commercial use. Public visibility alone is not permission.
- Review text is user-generated. Minimize retained personal data and use human review for consequential decisions.

### API usage

Node.js:

```js
import { ApifyClient } from "apify-client";

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor("fetch_cat/trip-com-reviews-scraper").call({
  hotelIds: ["129054778"],
  maxReviewsPerHotel: 10,
  sortBy: "newest"
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

Python:

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("fetch_cat/trip-com-reviews-scraper").call(run_input={
    "hotelIds": ["129054778"],
    "maxReviewsPerHotel": 10,
    "sortBy": "newest",
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

cURL:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/fetch_cat~trip-com-reviews-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"hotelIds":["129054778"],"maxReviewsPerHotel":10,"sortBy":"newest"}'
```

### Use with MCP and AI agents

Use the official Apify MCP server with a focused single-Actor URL:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=fetch_cat/trip-com-reviews-scraper"
```

Claude Desktop, Cursor, or VS Code configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=fetch_cat/trip-com-reviews-scraper"
    }
  }
}
```

Example prompts:

- “Export the newest 10 public reviews for hotel ID 129054778 and include completeness warnings.”
- “Compare the lowest-rating rows in these permissioned Trip.com hotel snapshots.”
- “Show which hotels returned incomplete snapshots by checking `hasMoreReviews`.”

### Schedule hotel review monitoring

Run a small input daily or weekly with `sortBy: "newest"`. Append each dataset to long-term storage and compare stable `reviewId` values. Use a webhook to notify your workflow when a new review meets your own score or text criteria.

### FAQ

**Does the Actor return every historical Trip.com review?**

No. It returns the bounded review rows exposed in the public server-rendered page. `reviewsAvailable`, `reviewsExtracted`, `hasMoreReviews`, and `warnings` make that distinction explicit.

**Does it require login, cookies, or a Trip.com API key?**

No. It supports anonymous public hotel pages only.

**Can I use a proxy?**

You can explicitly provide an Apify proxy configuration when your permission and use case allow it. Direct access is the default, and the Actor never switches routes automatically.

**Why did a hotel return no paid rows?**

Open `RUN_SUMMARY`. It distinguishes confirmed zero reviews, date-filtered empty results, removed URLs, access errors, malformed responses, and changed public-page shapes.

**Can I export CSV, Excel, JSON, XML, RSS, or use an API?**

Yes. Apify datasets support those exports and programmatic access.

**Is commercial use permitted?**

Trip.com’s current terms say Website content cannot be used commercially without a licence. Obtain appropriate permission and assess applicable privacy, copyright, and database rules before commercial use.

### Related Actors

- [Trip.com Hotels Scraper](https://apify.com/fetch_cat/trip-com-hotels-scraper) — collect public hotel listing records before a permissioned review workflow.
- [Agoda Reviews Scraper](https://apify.com/fetch_cat/agoda-reviews-scraper) — export public Agoda guest-review data.
- [Booking Reviews Scraper](https://apify.com/fetch_cat/booking-reviews-scraper) — collect public Booking.com review records.
- [Google Maps Reviews Scraper](https://apify.com/fetch_cat/google-maps-reviews-scraper) — export public place-review data.
- [Trustpilot Reviews Scraper](https://apify.com/fetch_cat/trustpilot-reviews-scraper) — collect public business-review records.

### Support

If a run fails or the output looks wrong, open an issue or report a bug from the Actor page. Include:

- the Apify run ID or run URL;
- the input JSON;
- the expected output;
- the actual output or `RUN_SUMMARY` error;
- one reproducible public URL that you are permitted to test.

# Actor input Schema

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

Trip.com or Ctrip hotel detail URLs to scrape reviews from.

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

Optional Trip.com/Ctrip hotel IDs. Use when you already have IDs from another dataset.

## `maxReviewsPerHotel` (type: `integer`):

Caps review rows saved for each hotel. The public page normally exposes only a bounded newest-review snapshot; values above that snapshot do not enable historical pagination.

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

Sort the review rows embedded in the public page before saving. This does not change Trip.com's server-side result set.

## `sinceDate` (type: `string`):

Optional YYYY-MM-DD cutoff. Reviews older than this date are skipped.

## `includeHotelSummary` (type: `boolean`):

Repeat the public hotel name on each review row. Stable hotel ID, source URL, and completeness diagnostics are always retained.

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

Include public image URLs attached to each review when available.

## `locale` (type: `string`):

Preferred language header, for example en-US,en;q=0.9 or ja-JP,ja;q=0.9.

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

Reserved for compatibility with Trip.com hotel workflows; review extraction does not currently depend on price currency.

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

Optional user-configured route. Direct public-page access is used when disabled. No proxy escalation happens automatically.

## `resumeFromCheckpoint` (type: `boolean`):

Process only hotel targets saved in RUN\_CHECKPOINT by a prior deadline-limited attempt in the same key-value store.

## `maxRuntimeSecs` (type: `integer`):

Stops admitting new network work before the platform timeout and reserves at least 30 seconds for checkpoints and the run summary.

## Actor input object example

```json
{
  "hotelUrls": [
    {
      "url": "https://www.trip.com/hotels/tokyo-hotel-detail-129054778/koko-hotel-tokyo-nishikasai/"
    }
  ],
  "hotelIds": [
    "129054778"
  ],
  "maxReviewsPerHotel": 20,
  "sortBy": "recommended",
  "includeHotelSummary": true,
  "includeImages": true,
  "locale": "en-US,en;q=0.9",
  "currency": "USD",
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "resumeFromCheckpoint": false
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

## `runCheckpoint` (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 = {
    "hotelUrls": [
        {
            "url": "https://www.trip.com/hotels/tokyo-hotel-detail-129054778/koko-hotel-tokyo-nishikasai/"
        }
    ],
    "hotelIds": [
        "129054778"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("fetch_cat/trip-com-reviews-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "hotelUrls": [{ "url": "https://www.trip.com/hotels/tokyo-hotel-detail-129054778/koko-hotel-tokyo-nishikasai/" }],
    "hotelIds": ["129054778"],
}

# Run the Actor and wait for it to finish
run = client.actor("fetch_cat/trip-com-reviews-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 '{
  "hotelUrls": [
    {
      "url": "https://www.trip.com/hotels/tokyo-hotel-detail-129054778/koko-hotel-tokyo-nishikasai/"
    }
  ],
  "hotelIds": [
    "129054778"
  ]
}' |
apify call fetch_cat/trip-com-reviews-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Trip.com Reviews Scraper",
        "description": "Export bounded public Trip.com and Ctrip hotel review snapshots with ratings, guest text, stay details, replies, media URLs, and completeness warnings.",
        "version": "0.1",
        "x-build-id": "tu0o9jDgpAK47lMzZ"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/fetch_cat~trip-com-reviews-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-fetch_cat-trip-com-reviews-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/fetch_cat~trip-com-reviews-scraper/runs": {
            "post": {
                "operationId": "runs-sync-fetch_cat-trip-com-reviews-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/fetch_cat~trip-com-reviews-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-fetch_cat-trip-com-reviews-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": {
                    "hotelUrls": {
                        "title": "Hotel URLs",
                        "maxItems": 100,
                        "type": "array",
                        "description": "Trip.com or Ctrip hotel detail URLs to scrape reviews from.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "hotelIds": {
                        "title": "Hotel IDs",
                        "maxItems": 100,
                        "type": "array",
                        "description": "Optional Trip.com/Ctrip hotel IDs. Use when you already have IDs from another dataset.",
                        "items": {
                            "type": "string",
                            "pattern": "^[0-9]{5,}$"
                        }
                    },
                    "maxReviewsPerHotel": {
                        "title": "Maximum reviews per hotel",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Caps review rows saved for each hotel. The public page normally exposes only a bounded newest-review snapshot; values above that snapshot do not enable historical pagination.",
                        "default": 20
                    },
                    "sortBy": {
                        "title": "Sort reviews by",
                        "enum": [
                            "recommended",
                            "newest",
                            "ratingHigh",
                            "ratingLow"
                        ],
                        "type": "string",
                        "description": "Sort the review rows embedded in the public page before saving. This does not change Trip.com's server-side result set.",
                        "default": "recommended"
                    },
                    "sinceDate": {
                        "title": "Since date",
                        "type": "string",
                        "description": "Optional YYYY-MM-DD cutoff. Reviews older than this date are skipped."
                    },
                    "includeHotelSummary": {
                        "title": "Include hotel summary fields",
                        "type": "boolean",
                        "description": "Repeat the public hotel name on each review row. Stable hotel ID, source URL, and completeness diagnostics are always retained.",
                        "default": true
                    },
                    "includeImages": {
                        "title": "Include review image URLs",
                        "type": "boolean",
                        "description": "Include public image URLs attached to each review when available.",
                        "default": true
                    },
                    "locale": {
                        "title": "Locale / Accept-Language",
                        "type": "string",
                        "description": "Preferred language header, for example en-US,en;q=0.9 or ja-JP,ja;q=0.9.",
                        "default": "en-US,en;q=0.9"
                    },
                    "currency": {
                        "title": "Currency",
                        "type": "string",
                        "description": "Reserved for compatibility with Trip.com hotel workflows; review extraction does not currently depend on price currency.",
                        "default": "USD"
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Optional user-configured route. Direct public-page access is used when disabled. No proxy escalation happens automatically.",
                        "default": {
                            "useApifyProxy": false
                        }
                    },
                    "resumeFromCheckpoint": {
                        "title": "Resume pending hotels",
                        "type": "boolean",
                        "description": "Process only hotel targets saved in RUN_CHECKPOINT by a prior deadline-limited attempt in the same key-value store.",
                        "default": false
                    },
                    "maxRuntimeSecs": {
                        "title": "Maximum work time (seconds)",
                        "minimum": 31,
                        "maximum": 270,
                        "type": "integer",
                        "description": "Stops admitting new network work before the platform timeout and reserves at least 30 seconds for checkpoints and the run summary."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
