{
  "openapi": "3.0.1",
  "info": {
    "title": "Expedia Scraper [$2💰] | Reviews | Hotels.com",
    "description": "Extract Expedia & Hotels.com guest reviews, room rates, and hotel search results for reputation monitoring, competitive intelligence, and market research. No Expedia API key needed.",
    "version": "0.2",
    "x-build-id": "1eSzc6a48YlBG5qM6"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/ahmed_jasarevic~expedia-reviews-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-ahmed_jasarevic-expedia-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/ahmed_jasarevic~expedia-reviews-scraper/runs": {
      "post": {
        "operationId": "runs-sync-ahmed_jasarevic-expedia-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/ahmed_jasarevic~expedia-reviews-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-ahmed_jasarevic-expedia-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": {
          "startUrls": {
            "title": "Start URLs / property IDs",
            "type": "array",
            "description": "Any mix of: Expedia hotel URLs (long slug, short path, or minimal slug), Hotels.com hotel URLs (/ho{id}/), bare property IDs (600217 or h600217), and Expedia deeplinks (expe.app.link / expe.onelink.me). All regional Expedia TLDs work (.co.uk, .de, .com.sg, ...).",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "searchLocations": {
            "title": "Search by location",
            "type": "array",
            "description": "Search for hotels by city or region name. Each entry can be a string (city name) or an object { location, checkIn, checkOut }. Requires checkIn/checkOut dates.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "checkIn": {
            "title": "Check-in date",
            "type": "string",
            "description": "Default check-in date for search locations (YYYY-MM-DD). Can be overridden per location."
          },
          "checkOut": {
            "title": "Check-out date",
            "type": "string",
            "description": "Default check-out date for search locations (YYYY-MM-DD). Can be overridden per location."
          },
          "searchSort": {
            "title": "Search sort order",
            "enum": [
              "RECOMMENDED",
              "PRICE_LOW_TO_HIGH",
              "PRICE_HIGH_TO_LOW",
              "GUEST_RATING",
              "STAR_RATING_HIGH_TO_LOW"
            ],
            "type": "string",
            "description": "How to sort hotel search results.",
            "default": "RECOMMENDED"
          },
          "searchAmenities": {
            "title": "Amenity filters",
            "type": "array",
            "description": "Filter search results by amenities. Common values: pool, gym, hot_tub, spa, parking, free_parking, pet_friendly, restaurant, breakfast, wifi, airport_shuttle, kitchen, indoor_pool.",
            "items": {
              "type": "string"
            }
          },
          "minStars": {
            "title": "Minimum star rating",
            "minimum": 0,
            "maximum": 5,
            "type": "integer",
            "description": "Minimum hotel star class (1-5). Set 0 to disable.",
            "default": 0
          },
          "minRating": {
            "title": "Minimum guest rating",
            "minimum": 0,
            "maximum": 10,
            "type": "number",
            "description": "Minimum guest rating out of 10 (e.g. 7.0). Set 0 to disable.",
            "default": 0
          },
          "excludeVacationRentals": {
            "title": "Exclude vacation rentals",
            "type": "boolean",
            "description": "Filter out Vrbo/Airbnb-style vacation rentals from search results.",
            "default": true
          },
          "maxResults": {
            "title": "Max results per location",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "Maximum hotel results per search location (for search mode).",
            "default": 50
          },
          "maxItems": {
            "title": "Max reviews per URL",
            "minimum": 1,
            "maximum": 10000,
            "type": "integer",
            "description": "Maximum review rows per Start URL (newest first) - not a run total. A run with N URLs returns up to maxItems x N rows.",
            "default": 1000
          },
          "reviewsFrom": {
            "title": "Only reviews from date",
            "type": "string",
            "description": "Format YYYY-MM-DD. Only emit reviews on/after this date; pagination stops early once older reviews are reached (reviews are sorted newest-first). Leave empty for all reviews."
          },
          "sortBy": {
            "title": "Review sort order",
            "enum": [
              "newest",
              "highest",
              "lowest",
              "mostHelpful"
            ],
            "type": "string",
            "description": "Order of the review list. newest is the site default and the safest for date filtering. \"Most relevant\" is not offered because Expedia's server errors on it over this GraphQL path.",
            "default": "newest"
          },
          "includeReviewPhotos": {
            "title": "Include review photos",
            "type": "boolean",
            "description": "Set false to strip reviewPhotos[] from every row (useful for compact CSV exports).",
            "default": true
          },
          "includeOwnerResponses": {
            "title": "Include management responses",
            "type": "boolean",
            "description": "Set false to strip hotelResponse (management replies) from every row.",
            "default": true
          },
          "includeRoomRates": {
            "title": "Include room rates",
            "type": "boolean",
            "description": "Fetch and output room types, pricing, and availability via GraphQL alongside reviews.",
            "default": false
          },
          "includeHotelInfo": {
            "title": "Include hotel info lookup",
            "type": "boolean",
            "description": "Fetch hotel name/rating via the property-info GraphQL operation. Off by default - that operation is the flakiest call in the chain (HTTP 400/429) and reviews don't need it.",
            "default": false
          },
          "includePropertyDetails": {
            "title": "Include property details block",
            "type": "boolean",
            "description": "Fetch the hotel's descriptive block (address, coordinates, description, amenities, highlights, languages, photo gallery) and merge it onto every review row. Sets off a chain of extra GraphQL calls per property.",
            "default": false
          },
          "includeCategoryRatings": {
            "title": "Include 5-category ratings",
            "type": "boolean",
            "description": "Fetch per-category ratings (Cleanliness, Staff & service, Amenities, Property conditions, Eco-friendliness) and overall rating + total reviews. Requires includePropertyDetails.",
            "default": false
          },
          "includeRatingDistribution": {
            "title": "Include rating distribution",
            "type": "boolean",
            "description": "Fetch the verified review distribution (count + % per band: Excellent, Very good, Good, Alright, Poor). Requires includePropertyDetails.",
            "default": false
          },
          "includePropertyImages": {
            "title": "Include property photo gallery",
            "type": "boolean",
            "description": "Fetch the property photo gallery with URL, category, and caption per image, attached to every row as propertyImages[]. On by default when includePropertyDetails is on.",
            "default": true
          },
          "maxPropertyImages": {
            "title": "Max property images",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "Maximum number of gallery photos to collect per property.",
            "default": 200
          },
          "skipReviews": {
            "title": "Skip reviews (hotel info only)",
            "type": "boolean",
            "description": "True = do not scrape review rows; emit one hotel-summary row (+ rooms when includeRoomRates) instead. Useful for overnight pricing/availability runs.",
            "default": false
          },
          "roomsCheckIn": {
            "title": "Room rates check-in",
            "type": "string",
            "description": "Check-in date for room availability queries (YYYY-MM-DD). Defaults to today."
          },
          "roomsCheckOut": {
            "title": "Room rates check-out",
            "type": "string",
            "description": "Check-out date for room availability queries (YYYY-MM-DD). Defaults to tomorrow."
          },
          "roomsAdults": {
            "title": "Room rates adults",
            "minimum": 1,
            "maximum": 30,
            "type": "integer",
            "description": "Number of adults for room availability queries.",
            "default": 2
          },
          "roomsRegion": {
            "title": "Room rates region (country code)",
            "type": "string",
            "description": "ISO country code for the quoted-for country (e.g. US, DE, SG). Defaults to the context country of the start URL."
          },
          "roomsLanguage": {
            "title": "Room rates language",
            "type": "string",
            "description": "en_US-style locale override for room availability queries. Defaults to the context locale of the start URL."
          },
          "requestDelayMs": {
            "title": "Delay between review pages (ms)",
            "minimum": 0,
            "maximum": 30000,
            "type": "integer",
            "description": "Pause between consecutive GraphQL review-page requests per property (jitter added). 2500ms default survives shared proxies; lower to 1000-1500 only on dedicated residential IPs.",
            "default": 2500
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "minimum": 1,
            "maximum": 50,
            "type": "integer",
            "description": "Parallel properties scraped at once. The GraphQL endpoint rate-limits PER IP - each property gets its own proxy IP, but keep at 1-2 on shared proxy plans.",
            "default": 2
          },
          "maxRequestRetries": {
            "title": "Max retries per request",
            "minimum": 1,
            "type": "integer",
            "description": "Retry budget for GraphQL review pages per property. Each 429 rotates to a fresh session + proxy IP and honors the server Retry-After header.",
            "default": 20
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Residential proxies are strongly recommended - datacenter IPs are rate-limited by Expedia Group.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "RESIDENTIAL"
              ]
            }
          },
          "debug": {
            "title": "Debug mode",
            "type": "boolean",
            "description": "Stores the fallback property-page HTML per property in the key-value store for troubleshooting response-shape changes.",
            "default": false
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}