{
  "openapi": "3.0.1",
  "info": {
    "title": "Expedia.com & Hotel.com [$2.5💰] Reviews/Ratings/Sentiment A.",
    "description": "[Only $2.5💰] Expedia + Hotels.com + Things-To-Do activities at $2.50/1k — only scraper covering all 3 brands. Deeplink auto-resolution, date filter, 10+ regional TLDs, bare property IDs. 25+ fields: sentiment, traveled-with, manager responses, category ratings. JSON or CSV. Pure HTTP.",
    "version": "0.0",
    "x-build-id": "NykpBMma5iM0Vdesb"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/memo23~expedia-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-memo23-expedia-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/memo23~expedia-scraper/runs": {
      "post": {
        "operationId": "runs-sync-memo23-expedia-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/memo23~expedia-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-memo23-expedia-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": "Start URLs",
            "type": "array",
            "description": "Hotel pages, activity (Things-To-Do) pages, Hotels.com pages, **or bare Expedia property IDs**. Expedia and Hotels.com URLs may be mixed in the same run.\n\n**Expedia hotels** — long slug (`.../City-Hotels-Name.h600217.Hotel-Information`), minimal slug (`.../Hotel.h600217.Hotel-Information`), short path (`.../h600217.Hotel-Information`), all regional TLDs (`expedia.co.uk`, `expedia.com.br`, `expedia.de`, `expedia.com.sg`, …), and deeplinks (`expe.app.link/...`, resolved automatically). Bare ids (digits or `h600217`) expand to `https://www.expedia.com/Hotel.h{id}.Hotel-Information`.\n\n**Expedia activities (Things-To-Do)** — `https://www.expedia.com/things-to-do/{slug}.a{id}.activity-details` (and regional equivalents). Returns activity reviews under `provider: \"expedia-activity\"`.\n\n**Hotels.com** — `https://{locale}.hotels.com/ho{id}/{slug}/`.\n\n**Not supported:** destination/region landing pages (`.../Name.d{id}.Place-To-Visit`) — those have no reviews of their own. If supplied, the run produces one explanatory row per such URL and skips the fetch entirely (no charges burned on dead URLs).",
            "items": {
              "type": "string"
            }
          },
          "maxItems": {
            "title": "Maximum number of items OR limit the results per crawl",
            "type": "integer",
            "description": "Maximum number of items that will be scraped.",
            "default": 1000
          },
          "reviewsFrom": {
            "title": "Only scrape reviews newer than [date]",
            "type": "string",
            "description": "Format should be YYYY-MM-DD, e.g., 2025-02-20"
          },
          "includeCategoryRatings": {
            "title": "Include hotel category ratings",
            "type": "boolean",
            "description": "Fetch hotel-level aggregate fields such as overall rating, rating label, total reviews, and category ratings.",
            "default": true
          },
          "includePropertyImages": {
            "title": "Include property photo gallery",
            "type": "boolean",
            "description": "Fetch every image URL in the hotel's photo gallery (typically 100-300 URLs per property) and attach them as `propertyImages` on every review row. **Charged per image** at $0.0001 each — for a 220-image hotel that's $0.022 extra per run. Set `false` to skip the gallery and pay nothing for images. Requires `includeCategoryRatings: true`.",
            "default": true
          },
          "includePropertyDetails": {
            "title": "Include property description & amenities",
            "type": "boolean",
            "description": "Attach rich hotel-level descriptive fields to every review row: `propertyName`, `starRating`, `propertyType`, `propertyAddress`, `propertyCoordinates`, `propertyDescription`, `propertyLanguages`, `propertyAmenities` (categorized), and `propertyHighlights`. Extracted from the same page-layout response as the photo gallery — **no extra per-item charge**. Set `false` to omit these fields. Requires `includeCategoryRatings: true`.",
            "default": true
          },
          "includeLocation": {
            "title": "Include location intelligence (nearby places)",
            "type": "boolean",
            "description": "Attach a `propertyLocation` block to every review row — nearby landmarks/attractions, transit & airports, and restaurants, each with walk/drive times (e.g. \"Utah State University — 18 min walk\"). **Opt-in**: this fires a separate request per hotel and is **charged one `additional-cost` event ($0.001) per hotel**. Leave off if you don't need location data.",
            "default": false
          },
          "includePolicies": {
            "title": "Include policies & important info",
            "type": "boolean",
            "description": "Attach a `propertyPolicies` block to every review row — check-in/check-out times & fees, minimum check-in age, pet policy, children & extra beds, deposits, accepted payment types, and 'You need to know' notes, grouped by section. **Opt-in**: fires a separate request per hotel and is **charged one `additional-cost` event ($0.001) per hotel**.",
            "default": false
          },
          "includeRooms": {
            "title": "Include room inventory & rates",
            "type": "boolean",
            "description": "Attach a `propertyRooms` block to every review row — each room type's name, bed config, occupancy, inclusions, nightly & total price, and cancellation terms. **Prices are a point-in-time snapshot** for the search window below (stamped in the output as `quotedFor`). **Opt-in**: fires a separate request per hotel and is **charged one `additional-cost` event ($0.001) per hotel**.",
            "default": false
          },
          "roomsCheckIn": {
            "title": "Room rates: check-in date",
            "type": "string",
            "description": "Check-in date for the room-rate quote, format YYYY-MM-DD. Only used when `includeRooms` is on. Leave empty to default to ~30 days from the run date."
          },
          "roomsCheckOut": {
            "title": "Room rates: check-out date",
            "type": "string",
            "description": "Check-out date for the room-rate quote, format YYYY-MM-DD. Only used when `includeRooms` is on. Leave empty to default to the night after check-in."
          },
          "roomsAdults": {
            "title": "Room rates: number of adults",
            "type": "integer",
            "description": "Number of adults for the room-rate quote. Only used when `includeRooms` is on. Defaults to 2.",
            "default": 2
          },
          "reviewSort": {
            "title": "Sort order for reviews",
            "enum": [
              "newest",
              "relevant",
              "highest",
              "lowest",
              "mostHelpful"
            ],
            "type": "string",
            "description": "Order in which to fetch reviews. **All five values are fully wired** via Expedia's GraphQL `sortBy` URN — buyers get the order they ask for. `mostHelpful` maps to Expedia's `Most relevant` URN (Expedia has no separate helpfulness dimension; relevance already accounts for helpful-vote weighting). The resolved URN is printed at run start so you can verify what's being sent.",
            "default": "newest"
          },
          "includeReviewPhotos": {
            "title": "Include review photos",
            "type": "boolean",
            "description": "When `false`, the actor strips the `reviewPhotos` array from each emitted row. Useful for CSV exports where flat structure matters, or to make rows smaller. Default `true`.",
            "default": true
          },
          "includeOwnerResponses": {
            "title": "Include hotel manager responses",
            "type": "boolean",
            "description": "When `false`, the actor strips the `hotelResponse` object from each emitted row. Set `false` when you only want guest-side review data. Default `true`.",
            "default": true
          },
          "googleMapsUrlNote": {
            "title": "Google Maps URL / Place ID input",
            "type": "string",
            "description": "**You can paste Google Maps URLs and place IDs directly into `Start URLs` above.** The actor recognizes them, parses the hotel name from the URL slug (e.g. `Hotel+Anastassiou+Kastoria`), and emits a row with the parsed name plus an Expedia hotel-search URL the buyer can use to find the canonical Expedia listing. **Full auto-resolution (Google Maps → Expedia hotel URL → reviews) is coming in v1.1** — for now this surfaces the hotel name + a search shortcut. Paste an actual Expedia hotel URL alongside if you want reviews fetched in the same run."
          },
          "maxConcurrency": {
            "title": "Max Concurrency",
            "type": "integer",
            "description": "Maximum number of pages that can be processed at the same time.",
            "default": 10
          },
          "minConcurrency": {
            "title": "Min Concurrency",
            "type": "integer",
            "description": "Minimum number of pages that will be processed at the same time.",
            "default": 1
          },
          "maxRequestRetries": {
            "title": "Max Request Retries",
            "type": "integer",
            "description": "Number of times the crawler will retry a failed request before giving up.",
            "default": 100
          },
          "proxy": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Specifies proxy servers that will be used by the scraper in order to hide its origin.<br><br>For details, see <a href='https://apify.com/apify/web-scraper#proxy-configuration' target='_blank' rel='noopener'>Proxy configuration</a> in README.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "RESIDENTIAL"
              ]
            }
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}