{
  "openapi": "3.0.1",
  "info": {
    "title": "Google Hotels Prices Scraper & API — OTA Rates, Rate Parity",
    "description": "Google Hotels scraper & API: search hotels in any city and get hotel prices for exact dates — nightly rate, stay total, deals, availability, plus all OTA rates (Booking.com, Expedia, Agoda, official site). Hotel price comparison, price tracking, rate parity and competitor rate shopping. MCP-ready.",
    "version": "1.9",
    "x-build-id": "zBOxj77WqfhGGNsXP"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/kestrel~google-hotels-prices/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-kestrel-google-hotels-prices",
        "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/kestrel~google-hotels-prices/runs": {
      "post": {
        "operationId": "runs-sync-kestrel-google-hotels-prices",
        "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/kestrel~google-hotels-prices/run-sync": {
      "post": {
        "operationId": "run-sync-kestrel-google-hotels-prices",
        "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": [
          "checkIn",
          "checkOut"
        ],
        "properties": {
          "queries": {
            "title": "Places",
            "uniqueItems": true,
            "type": "array",
            "description": "Free-text place searches, exactly as you would type them into Google Hotels: \"hotels in Lisbon\", \"hotels near Times Square\", \"5-star hotels Bangkok\". Google's results are paged 20 at a time; maxHotels sets how many distinct hotels to collect per place. Google always answers a place search: an unrecognised or misspelt place is silently matched to somewhere else rather than failing, and those hotels are delivered and billed. Pass an exact place name or a Google Hotels entity URL, and check the status row's spread_km (and each hotel's lat/lng) before trusting the results.",
            "items": {
              "type": "string"
            }
          },
          "hotels": {
            "title": "Specific hotels",
            "uniqueItems": true,
            "type": "array",
            "description": "Track exact properties without a search: Google Hotels URLs (https://www.google.com/travel/hotels/entity/ChkI…) or bare entity tokens, e.g. from an earlier run's `google_url`/`entity_id`. One offers call per hotel and stay; the hotel row comes from that page.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "hotelNames": {
            "title": "Hotels by name",
            "uniqueItems": true,
            "type": "array",
            "description": "Track exact properties by name, no URL needed: \"Hyatt Regency Lisbon\", \"Altis Grand Hotel Lisbon\" — add the city so the name is unambiguous. A Google Maps place link works too, and so do names in Chinese, Japanese, Korean or Thai (香港半島酒店). Each name is looked up once per run; a name nothing matches is reported in a status row and costs nothing, and only a property whose name matches yours is ever billed. Rows carry star class, rating, review count and coordinates.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "checkIn": {
            "title": "Check-in",
            "pattern": "^(\\d{4}-\\d{2}-\\d{2}|\\+?\\s*\\d+\\s*(d|days?|w|weeks?|m|months?|y|years?)|today|tomorrow)$",
            "type": "string",
            "description": "Check-in date: absolute YYYY-MM-DD or relative to the run date (e.g. 2026-10-03, or relative for schedules: \"40 days\", \"6 weeks\", \"+40d\"). Relative dates keep a scheduled run valid forever."
          },
          "checkOut": {
            "title": "Check-out",
            "pattern": "^(\\d{4}-\\d{2}-\\d{2}|\\+?\\s*\\d+\\s*(d|days?|w|weeks?|m|months?|y|years?)|today|tomorrow)$",
            "type": "string",
            "description": "Check-out date: absolute YYYY-MM-DD or relative to the run date (e.g. 2026-10-06 or \"42 days\" — must be after check-in; nights = the difference). Relative dates keep a scheduled run valid forever."
          },
          "sweepDays": {
            "title": "Sweep check-in over N more days",
            "minimum": 0,
            "maximum": 60,
            "type": "integer",
            "description": "0 = only the stay above. N = also fetch the same length of stay starting on each of the next N days (a 3-night stay with sweepDays 6 = 7 stays, one per check-in day). Each stay is a separate list call.",
            "default": 0
          },
          "adults": {
            "title": "Adults",
            "minimum": 1,
            "maximum": 6,
            "type": "integer",
            "description": "Adults per room (prices scale with occupancy exactly as on Google).",
            "default": 2
          },
          "childrenAges": {
            "title": "Children (ages)",
            "type": "array",
            "description": "Ages of children sharing the room, e.g. [4, 9]. Leave empty for none.",
            "default": []
          },
          "currency": {
            "title": "Currency",
            "pattern": "^[A-Z]{3}$",
            "minLength": 3,
            "maxLength": 3,
            "type": "string",
            "description": "3-letter currency code for every price: USD, EUR, GBP, SGD, HKD, CNY, TWD, JPY, KRW, IDR, THB, MYR, VND, AUD, AED, … All rows are in this one currency.",
            "default": "USD"
          },
          "language": {
            "title": "Language",
            "type": "string",
            "description": "Google UI language (hl): en, zh-CN (简体中文), zh-TW / zh-HK (繁體中文), ja, ko, id, th, vi, ms, es, de, fr, … Affects hotel names, room names, star-class labels and deal notes. Queries and hotel names may be written in any language.",
            "default": "en"
          },
          "country": {
            "title": "Market",
            "type": "string",
            "description": "Google market (gl): which country's Google Hotels answers — us, gb, sg, hk, cn, tw, jp, kr, id, th, my, vn, au, ae, … Prices and the booking sites listed differ by market (Klook, Wego or Traveloka appear in Asian markets).",
            "default": "us"
          },
          "maxHotels": {
            "title": "Max hotels per place",
            "minimum": 1,
            "maximum": 200,
            "type": "integer",
            "description": "Distinct hotels to collect per place and stay. Google returns 20 per page; the actor pages on (one list call per 20) until this many or the results end.",
            "default": 20
          },
          "sortBy": {
            "title": "Sort by",
            "enum": [
              "relevance",
              "lowest_price",
              "highest_rating",
              "most_reviewed"
            ],
            "type": "string",
            "description": "Google Hotels' own sort order for place searches. With maxHotels this gives you, for example, the 50 cheapest or the 50 best-rated hotels of a city.",
            "default": "relevance"
          },
          "freeCancellation": {
            "title": "Free cancellation only",
            "type": "boolean",
            "description": "Only hotels with a free-cancellation rate for your dates. Google then quotes the refundable rate where it has one, so the nightly price can be higher than the unfiltered one.",
            "default": false
          },
          "minPrice": {
            "title": "Minimum price per night",
            "minimum": 0,
            "type": "integer",
            "description": "Lowest nightly price to include, in your currency. 0 = no minimum.",
            "default": 0
          },
          "maxPrice": {
            "title": "Maximum price per night",
            "minimum": 0,
            "type": "integer",
            "description": "Highest nightly price to include, in your currency. 0 = no maximum.",
            "default": 0
          },
          "minRating": {
            "title": "Guest rating",
            "enum": [
              "any",
              "3.5",
              "4.0",
              "4.5"
            ],
            "type": "string",
            "description": "Minimum Google guest rating (out of 5).",
            "default": "any"
          },
          "hotelClass": {
            "title": "Hotel class (stars)",
            "uniqueItems": true,
            "type": "array",
            "description": "Only these star classes, e.g. 4 and 5. Empty = any class.",
            "items": {
              "type": "string",
              "enum": [
                "2",
                "3",
                "4",
                "5"
              ],
              "enumTitles": [
                "2-star",
                "3-star",
                "4-star",
                "5-star"
              ]
            },
            "default": []
          },
          "amenities": {
            "title": "Amenities",
            "uniqueItems": true,
            "type": "array",
            "description": "Only hotels that have ALL of these amenities, as Google Hotels lists them. Empty = no amenity filter.",
            "items": {
              "type": "string",
              "enum": [
                "free_wifi",
                "free_breakfast",
                "restaurant",
                "bar",
                "kid_friendly",
                "pet_friendly",
                "free_parking",
                "parking",
                "ev_charger",
                "room_service",
                "fitness_center",
                "spa",
                "pool",
                "indoor_pool",
                "outdoor_pool",
                "air_conditioned",
                "wheelchair_accessible",
                "beach_access",
                "all_inclusive"
              ],
              "enumTitles": [
                "Free Wi-Fi",
                "Free breakfast",
                "Restaurant",
                "Bar",
                "Kid friendly",
                "Pet friendly",
                "Free parking",
                "Parking",
                "EV charger",
                "Room service",
                "Fitness center",
                "Spa",
                "Pool",
                "Indoor pool",
                "Outdoor pool",
                "Air conditioned",
                "Wheelchair accessible",
                "Beach access",
                "All inclusive"
              ]
            },
            "default": []
          },
          "specialOffers": {
            "title": "Special offers only",
            "type": "boolean",
            "description": "Only hotels Google marks as a deal for your dates (“23% less than usual”); the `deal` field carries the note.",
            "default": false
          },
          "includeOffers": {
            "title": "Fetch every source's rates",
            "type": "boolean",
            "description": "For each priced hotel also fetch its offers page (one extra call per hotel): the rates from every source — Booking.com, Expedia, Agoda, the official site… — with free-cancellation flag, stay total and deep link.",
            "default": true
          },
          "offerLevel": {
            "title": "Offer rows per hotel",
            "enum": [
              "sources",
              "rooms"
            ],
            "type": "string",
            "description": "sources = one row per source with its lowest rate (rate parity; ~5–15 rows per hotel). rooms = every source × room × rate, with room names and cancellation deadlines (~50–100 rows per hotel).",
            "default": "sources"
          },
          "maxOffersPerHotel": {
            "title": "Max offer rows per hotel",
            "minimum": 0,
            "maximum": 500,
            "type": "integer",
            "description": "0 = every source. N = keep only the N cheapest rows per hotel (cost control; the official site row is kept only if it is among them).",
            "default": 0
          },
          "includeDetails": {
            "title": "Hotel details",
            "type": "boolean",
            "description": "Add what Google's property page says about each hotel: address, phone, Google Maps place ID, long description, the 5-4-3-2-1 star rating breakdown, review topics with positive and negative mention counts (Service, Location, Breakfast, …), ratings on Tripadvisor and other sites, amenities by name (Wi-Fi, pool, parking, pets, accessibility… about 120 of them, with notes such as free or extra charge), and photos. One small extra call per hotel, at no extra charge. It also completes rows for hotels given by URL, which otherwise have no star class, rating or coordinates.",
            "default": false
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "Google accepts Apify datacenter proxies for these calls; keep the default. Residential is unnecessary.",
            "default": {
              "useApifyProxy": true
            }
          },
          "sessions": {
            "title": "Parallel proxy sessions",
            "minimum": 1,
            "maximum": 16,
            "type": "integer",
            "description": "Concurrent egress IPs; each is paced at perIp requests per second.",
            "default": 4
          },
          "perIp": {
            "title": "Requests per second per IP",
            "minimum": 0.1,
            "maximum": 2,
            "type": "number",
            "description": "Pace per proxy session. 0.5 is safe; raise carefully.",
            "default": 0.5
          }
        }
      },
      "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}