# TripAdvisor All-in-One API (`romy/tripadvisor-all-in-one-api`) Actor

Unofficial always-on REST API for live TripAdvisor data: destination search, hotels, restaurants, attractions (search with price/amenity/rating filters + sort), paginated reviews, and photo galleries. Real prices and ratings, no account needed.

- **URL**: https://apify.com/romy/tripadvisor-all-in-one-api.md
- **Developed by:** [Romy](https://apify.com/romy) (community)
- **Categories:** Travel
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $35.10 / 1,000 hotels

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

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

### What does TripAdvisor All-in-One API do?

**TripAdvisor All-in-One API** is a REST endpoint for live TripAdvisor data — destination search, hotels, restaurants, attractions/things-to-do, paginated reviews with rating filters, and photo galleries. All from a single always-on API powered by [Apify Standby](https://docs.apify.com/platform/actors/development/programming-interface/standby).

It talks directly to the same internal API the official [TripAdvisor](https://www.tripadvisor.com/) Android app uses, reverse-engineered by capturing live traffic from a real device. Unlike many reverse-engineered mobile APIs, TripAdvisor needs **no per-request signature at all** — just a static API key and self-generated device/session ids, confirmed live and standalone-reproducible. No TripAdvisor account, no API key of your own — call the endpoint, get JSON back.

### Why use TripAdvisor All-in-One API?

- **One search, three verticals** — hotels, restaurants, and attractions are all served by the exact same underlying operations (confirmed live by replaying with each content type and getting real, distinct results) — consistent behavior across every listing type, not three different quirky endpoints
- **Real filters that genuinely work** — price range, amenities, minimum rating, sort — confirmed live: a price=\[150,190] filter returned only hotels priced £157-£179, not an ignored parameter
- **The filter schema comes free** — every search response's `filters.availableFilterGroups` field carries the live id+label options for that exact query, no separate schema call needed
- **Real paginated reviews, not a 20-item cap** — confirmed live end-to-end: page 2 returns 20 genuinely new reviews with zero overlap with page 1, using TripAdvisor's own real (non-trivial) pagination cursor, wrapped so you don't have to reverse-engineer it yourself
- **Always-on** — Standby mode means no cold start, responds in milliseconds
- **No account needed** — every endpoint works fully anonymously
- **Use cases:** travel content aggregation, price/rating monitoring, review analysis, destination research bots

### Endpoints

| Method | Path | Description |
| ------ | ---- | ----------- |
| `GET` | `/search` | Destination/POI autocomplete |
| `GET` | `/home` | Home tab feed |
| `GET` | `/hotels` | Hotel search for a destination |
| `GET` | `/hotels/{id}` | Full hotel detail |
| `GET` | `/hotels/{id}/reviews` | Paginated hotel reviews |
| `GET` | `/restaurants` | Restaurant search for a destination |
| `GET` | `/restaurants/{id}` | Full restaurant detail |
| `GET` | `/restaurants/{id}/reviews` | Paginated restaurant reviews |
| `GET` | `/attractions` | Attraction/things-to-do search for a destination |
| `GET` | `/attractions/{id}` | Full attraction detail |
| `GET` | `/attractions/{id}/reviews` | Paginated attraction reviews |
| `GET` | `/listings/{id}/photos` | Photo gallery for any listing |

### How to use TripAdvisor All-in-One API

1. Open this Actor's Standby API URL (shown on the Actor's page, under the API tab).
2. Call any endpoint — for example:
   ```bash
   curl "https://romy--tripadvisor-all-in-one-api.apify.actor/search?query=Bangkok"
   curl "https://romy--tripadvisor-all-in-one-api.apify.actor/home"
   curl "https://romy--tripadvisor-all-in-one-api.apify.actor/hotels?geo_id=293916"
   curl "https://romy--tripadvisor-all-in-one-api.apify.actor/hotels?geo_id=293916&price_min=50&price_max=200&sort=PRICE_LOW_TO_HIGH"
   curl "https://romy--tripadvisor-all-in-one-api.apify.actor/hotels/25246100"
   curl "https://romy--tripadvisor-all-in-one-api.apify.actor/hotels/25246100/reviews?min_rating=5"
   curl "https://romy--tripadvisor-all-in-one-api.apify.actor/restaurants?geo_id=293916"
   curl "https://romy--tripadvisor-all-in-one-api.apify.actor/attractions?geo_id=293916"
   curl "https://romy--tripadvisor-all-in-one-api.apify.actor/listings/25246100/photos"
   # Pagination: pass the previous response's next_page_token back as page_token
   curl "https://romy--tripadvisor-all-in-one-api.apify.actor/hotels/25246100/reviews?page_token=<token from previous response>"
   ```
   Every call needs your Apify API token, either as `Authorization: Bearer <token>` or `?token=<token>` — the Actor's page API tab has a ready-to-copy version with your token filled in.
3. Read the JSON response — no setup required.

### Parameters

**`GET /search`** — `query` required (free-text destination name). `currency` optional, default `GBP`.

**`GET /home`** — no required parameters. `currency` optional.

**`GET /hotels`**, **`GET /restaurants`**, **`GET /attractions`** — `geo_id` required (from `/search`).

| Param | Type | Example | Meaning |
| ----- | ---- | ------- | ------- |
| `geo_id` | string | `293916` | From `/search` |
| `price_min` | int | `50` | Minimum nightly price — confirmed live to genuinely filter (hotels/restaurants only) |
| `price_max` | int | `200` | Maximum nightly price |
| `amenities` | comma-separated string | `9176` | Amenity tag ids — confirmed live as a real filter (hotels only). Get ids from a prior response's `filters.availableFilterGroups` |
| `min_rating` | string | `4` | Minimum star rating, confirmed live values `"1"`-`"5"` |
| `sort` | string | `PRICE_LOW_TO_HIGH` | Confirmed live values: `BEST_VALUE`, `PRICE_LOW_TO_HIGH` |
| `currency` | string, default `GBP` | `USD` | Confirmed live to change returned prices |

**`GET /hotels/{id}`**, **`GET /restaurants/{id}`**, **`GET /attractions/{id}`** — `id` required (a content id from the matching search endpoint). `currency` optional.

**`GET /hotels/{id}/reviews`**, **`GET /restaurants/{id}/reviews`**, **`GET /attractions/{id}/reviews`** — `id` required.

| Param | Type | Example | Meaning |
| ----- | ---- | ------- | ------- |
| `min_rating` | string | `5` | Filter to one star rating |
| `page_token` | string | | `next_page_token` from a previous response — omit for page 1 |
| `currency` | string, default `GBP` | `USD` | |

**`GET /listings/{id}/photos`** — `id` required (any hotel/restaurant/attraction content id). `offset` optional (default `0`).

### Output

```json
{
    "success": true,
    "hotel": {
        "AppPresentation_queryAppDetailV2": [{
            "container": { "navTitle": "Villa Deva Resort & Hotel Bangkok" }
        }]
    }
}
```

Reviews responses include a `next_page_token` alongside the review data:

```json
{
    "success": true,
    "reviews": { "AppPresentation_queryPoiReviews": { "sections": [ "..." ] } },
    "next_page_token": "eyJ1cGRhdGVUb2tlbiI6Ii4uLiIsInBhZ2VlIjoyMH0"
}
```

### Data notes

- **No request signing exists at all** — confirmed by capturing the real app's traffic and finding just static identity headers (no per-request signature or hash) that aren't validated against any server-side registry (confirmed: a freshly generated device identity works immediately). Verified fully standalone-reproducible — no device or live app session needed at runtime.
- **One internal API endpoint, persisted queries.** Every request goes to a single internal endpoint, distinguished by an operation name plus a fixed persisted-query hash instead of a full query string — confirmed live that these hashes are reusable across devices/sessions.
- **List, detail, and reviews are genuinely generic across hotel/restaurant/attraction** — confirmed live by replaying the exact same underlying operation with each content-type value and getting back real, distinct results every time, not guessed.
- **Detail is richer than list-screen prefetching.** The app's list screens batch-prefetch 4 items at once into a lighter ~100-130KB payload; `/hotels/{id}` etc. use the single-item call the app's own detail screen makes instead, up to ~265KB for one hotel.
- **Review pagination is genuinely non-trivial, and this Actor handles it for you.** Confirmed live: a raw page-number/offset parameter alone silently re-returns page 1 — real pagination requires threading an opaque continuation cursor from the previous response back into the next request, alongside an internal page-depth counter. This Actor extracts and re-encodes that state into one opaque `next_page_token`/`page_token` pair so callers don't need to reverse-engineer it themselves. Verified end-to-end: page 2 returned 20 genuinely new review ids with zero overlap with page 1.
- **`currency` changes real prices**, not just a symbol — the same behavior pattern discovered in this developer's Klook All-in-One API. Not part of any request signature (there isn't one here), so any ISO code is always safe to pass.

### Pricing

Pay-per-event, billed on each successful call. See the Actor's Pricing tab for current rates.

### Known limitations

- **Hotel/restaurant/attraction list pagination beyond the first page isn't fully wrapped yet.** The `update_token` query param on `/hotels`, `/restaurants`, `/attractions` is exposed but requires the caller to already understand TripAdvisor's own opaque list-pagination cursor format — unlike the reviews endpoints, this Actor doesn't yet re-encode it into a clean `next_page_token`. Noted here rather than silently left half-working; likely a fast follow-up given the reviews endpoint's pagination wrapper already solves the same underlying problem shape.
- **This Actor only wraps guest-accessible endpoints.** No login flow is implemented or planned — features requiring a real TripAdvisor account (saved trips, writing reviews, booking) are out of scope by design.
- **DataDome telemetry is present but doesn't block data** — the app calls a device-check telemetry SDK alongside its real requests, but every data endpoint this Actor wraps returns real content regardless (unlike this developer's Klook All-in-One API, where DataDome genuinely blocks several endpoints).
- This is an unofficial, reverse-engineered integration, not affiliated with or endorsed by Tripadvisor LLC. Behavior may change if TripAdvisor changes its API.

Found a bug or have a feature request? Use the Issues tab on this Actor's page.

# Actor input Schema

## Actor input object example

```json
{}
```

# Actor output Schema

## `api` (type: `string`):

This Actor doesn't write to a dataset — every response is returned directly over HTTP by its Standby web server. See the README / web server OpenAPI schema (webServerSchema) for the full endpoint list and response shapes (GET /search).

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("romy/tripadvisor-all-in-one-api").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("romy/tripadvisor-all-in-one-api").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 '{}' |
apify call romy/tripadvisor-all-in-one-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,romy/tripadvisor-all-in-one-api"
        }
    }
}

```

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/a42g1vo6HK6lCIvOs/builds/X2dc08VXQ3pc9aWEh/openapi.json
