{
  "openapi": "3.0.1",
  "info": {
    "title": "Tripadvisor Review Scraper — Sentiment & Analytics",
    "description": "Tripadvisor Review Scraper: Extract hotel, restaurant, and attraction reviews with ratings, reviewer details, dates, text, and engagement data. Analyze sentiment, identify trends, compare businesses, monitor reputation, and build structured datasets for travel and hospitality research.",
    "version": "0.2",
    "x-build-id": "1GIOh8u93ZYehB7zS"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/scrapier~tripadvisor-review-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-scrapier-tripadvisor-review-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/scrapier~tripadvisor-review-scraper/runs": {
      "post": {
        "operationId": "runs-sync-scrapier-tripadvisor-review-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/scrapier~tripadvisor-review-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-scrapier-tripadvisor-review-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",
        "required": [
          "startUrls"
        ],
        "properties": {
          "startUrls": {
            "title": "🔗 TripAdvisor URLs, Hotel Names, or Keywords",
            "type": "array",
            "description": "📌 Drop one or more of the following — mix & match freely:\n\n🌐 **Direct URLs** — best results, fastest extraction\n   ↳ e.g. `https://www.tripadvisor.com/Hotel_Review-g60763-d208453-Reviews-Hilton_New_York_Times_Square-New_York_City_New_York.html`\n\n🏨 **Hotel names** — auto-resolved via Google Search\n   ↳ e.g. `Hilton New York Times Square`\n\n🔍 **Keywords** — broader matches, may pick the most relevant hotel\n   ↳ e.g. `luxury hotel New York`\n\n💡 **Tip:** Direct URLs always give the most accurate results — keyword search can be hit-or-miss.",
            "items": {
              "type": "string"
            }
          },
          "maxComments": {
            "title": "📊 Maximum Reviews per URL",
            "minimum": 1,
            "maximum": 10000,
            "type": "integer",
            "description": "🎯 How many reviews to extract from each hotel.\n\n⚡ Small runs (1–100) → seconds\n🚀 Large runs (1000+) → minutes\n💎 Enterprise (up to 10,000) → fully supported\n\n📥 The scraper auto-paginates — no need to click 'Next Page'.",
            "default": 10
          },
          "sortOrder": {
            "title": "🔀 Review Sort Order",
            "enum": [
              "newest",
              "oldest",
              "relevant",
              "rating"
            ],
            "type": "string",
            "description": "🗂️ Choose the order in which reviews are fetched.\n\n🆕 **newest** — most recent first (default, best for monitoring)\n📜 **oldest** — earliest reviews first\n⭐ **relevant** — TripAdvisor's own API does not expose a separate relevance ranking on this endpoint, so this currently returns the same order as \"newest\" (kept as its own option for forward compatibility if TripAdvisor adds one later)\n🏆 **rating** — highest rating first",
            "default": "newest"
          },
          "reviewsLanguages": {
            "title": "🌍 Review Language",
            "enum": [
              "ALL_REVIEW_LANGUAGES",
              "English",
              "Spanish",
              "French",
              "German",
              "Italian",
              "Portuguese",
              "Dutch",
              "Russian",
              "Japanese",
              "Korean",
              "Chinese (Simplified)",
              "Chinese (Traditional)",
              "Arabic",
              "Turkish",
              "Hebrew",
              "Swedish",
              "Norwegian",
              "Danish",
              "Finnish",
              "Polish",
              "Czech",
              "Hungarian",
              "Romanian",
              "Greek",
              "Thai",
              "Vietnamese",
              "Indonesian",
              "Malay",
              "Hindi"
            ],
            "type": "string",
            "description": "🗣️ Pick which language to extract reviews in.\n\n🌐 Choose **All Languages** to keep every locale, or pick a specific language for a focused dataset.",
            "default": "English"
          },
          "reviewRatings": {
            "title": "⭐ Review Rating Filter",
            "enum": [
              "ALL_REVIEW_RATINGS",
              "POSITIVE",
              "NEGATIVE",
              "AVERAGE",
              "5",
              "4",
              "3",
              "2",
              "1"
            ],
            "type": "string",
            "description": "🎯 Choose which star ratings to extract.\n\n🌟 **All Ratings** — keep every review (default)\n👍 **Positive** — combine 4 + 5 star reviews\n👎 **Negative** — combine 1 + 2 star reviews\n😐 **Average** — only 3 star reviews\n\nOr pick a specific star count for a single-tier dataset.",
            "default": "ALL_REVIEW_RATINGS"
          },
          "scrapeReviewerInfo": {
            "title": "👤 Include Reviewer Profile Info",
            "type": "boolean",
            "description": "🪪 When enabled, each review row includes the full reviewer profile (name, username, location, avatar, contribution counts, profile link).\n\n🔒 Disable for privacy-sensitive runs or when you only need review text + ratings — the `user` field becomes `null` in the output.",
            "default": true
          },
          "enableAiAnalysis": {
            "title": "🤖 Enable AI Sentiment & Response-Tone Analysis",
            "type": "boolean",
            "description": "🧠 When enabled, every review is classified for sentiment/emotion/topics, and any owner (management) response is scored for tone.\n\n🔑 Requires a provider API key below (or a matching env var). Off by default — with no key, every AI field is simply `null`; nothing is ever guessed or faked.\n\n💰 Uses your own AI provider account — billed by that provider, not by this actor.",
            "default": false
          },
          "aiModel": {
            "title": "🤖 AI Model / Provider",
            "enum": [
              "claude-haiku-4-5",
              "claude-sonnet-5",
              "claude-opus-4-8",
              "claude-fable-5",
              "gpt-4o-mini",
              "gpt-4o",
              "gpt-4.1-mini",
              "gpt-4.1",
              "o3-mini",
              "o1",
              "gemini-2.0-flash-lite",
              "gemini-2.0-flash",
              "gemini-1.5-pro",
              "gemini-2.5-flash",
              "gemini-2.5-pro",
              "grok-2-latest",
              "grok-3-mini",
              "grok-3",
              "grok-beta",
              "deepseek-chat",
              "deepseek-reasoner",
              "sonar",
              "sonar-pro",
              "sonar-reasoning",
              "mistral-small-latest",
              "mistral-large-latest"
            ],
            "type": "string",
            "description": "Provider auto-detected from the name: claude-*=Anthropic, gpt-*/o1/o3=OpenAI, gemini-*=Google, grok-*=xAI, deepseek-*=DeepSeek, sonar*=Perplexity, mistral-*=Mistral. Cheaper mini/flash/haiku/lite models are recommended for classification.",
            "default": "claude-haiku-4-5"
          },
          "aiApiKey": {
            "title": "🔑 AI Provider API Key",
            "type": "string",
            "description": "Secret key for the provider matching `aiModel` above (e.g. an Anthropic key for claude-* models). Falls back to the matching environment variable (ANTHROPIC_API_KEY / OPENAI_API_KEY / GEMINI_API_KEY / XAI_API_KEY / DEEPSEEK_API_KEY / PERPLEXITY_API_KEY / MISTRAL_API_KEY) if left blank. Ignored entirely when AI analysis is disabled above."
          },
          "includePropertyAnalytics": {
            "title": "📊 Include Derived Property Analytics Row",
            "type": "boolean",
            "description": "📈 When enabled (default), one extra summary row per property is pushed after its reviews finish — `ratingHistogramPercent`, `responseRate`, `avgResponseTimeDays`, and `avgSubratingsByCategory`, computed locally from data already collected (zero extra requests, not AI, not billed as an extra result).\n\n🔕 Disable if you only want plain review rows in the output table.",
            "default": true
          },
          "proxyConfiguration": {
            "title": "🌐 Proxy Configuration (Residential Recommended) 🛡️",
            "type": "object",
            "description": "🔒 TripAdvisor is protected by anti-bot defenses. Datacenter IPs get blocked within seconds — so this scraper defaults to **🏘️ Apify Residential Proxy** if you leave this blank.\n\n✅ **Residential** (recommended) — bypasses anti-bot protection reliably\n⚠️ **Datacenter** — works briefly, then gets challenged\n❌ **No proxy** — almost always blocked\n\n🧠 The scraper uses sticky sessions automatically, so cookies stay valid across every step of one property's collection."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}