{
  "openapi": "3.0.1",
  "info": {
    "title": "Google Hotels Scraper",
    "description": "Google Hotels API for hotel prices by city and dates: nightly rate, stay total, star class, rating, reviews and deals, checked against the dates you asked for.",
    "version": "0.1",
    "x-build-id": "lonaDv5FdfoZwPlva"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/finaldynamics~google-hotels-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-finaldynamics-google-hotels-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/finaldynamics~google-hotels-scraper/runs": {
      "post": {
        "operationId": "runs-sync-finaldynamics-google-hotels-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/finaldynamics~google-hotels-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-finaldynamics-google-hotels-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": {
          "locations": {
            "title": "Locations",
            "maxItems": 100,
            "type": "array",
            "description": "Cities or areas to search, such as Miami or Moab, Utah. Add the state or country when a name is common. You can mix locations with specific hotels below. If you give no location, hotel ID, hotel link or hotel name, the run does a sample search for Miami (up to Maximum hotels per location) and says so in its status.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "hotelIds": {
            "title": "Specific hotel IDs",
            "type": "array",
            "description": "Google hotel IDs from the hotelId output, or Google Maps place IDs that start with ChIJ. You get one row per hotel for your stay. Use this to track a fixed set of competitors.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "hotelUrls": {
            "title": "Hotel links (Google Hotels or Google Maps)",
            "maxItems": 100,
            "type": "array",
            "description": "Paste Google Hotels property links (https://www.google.com/travel/hotels/entity/...), Google Maps links to the hotel, or Maps share links (https://maps.app.goo.gl/...). A share link takes one extra request to see where it points. The actor uses your dates and guests, not the ones in the link. A Maps place that isn't a hotel returns an error for that line.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "hotelNames": {
            "title": "Hotel names",
            "maxItems": 100,
            "type": "array",
            "description": "Type a hotel's name, with the city for common names, such as Hotel Plaza Athenee Paris. Google's search picks the hotel and the row shows the name it matched. A city name alone isn't a hotel and returns an error for that line.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "maxResults": {
            "title": "Maximum hotels per location",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Most hotels to return for each location, from 1 to 1,000. Up to 20 reads one results page. Higher values read more pages until Google runs out. In a Paris test Google stopped after 552 different properties. Specific hotels always return one row each. Big inputs take time: requests go out at least 2 seconds apart, and booking sites, hotel details, reviews and the price calendar each add requests per hotel. A run allows up to 10,000 Google requests and stops before its timeout. If it can't finish, it says so up front and in its status, and keeps the rows it has.",
            "default": 20
          },
          "checkInDate": {
            "title": "Check-in date",
            "pattern": "^(\\d{4}-\\d{2}-\\d{2})?$",
            "type": "string",
            "description": "YYYY-MM-DD. Leave empty to search 14 days from today, which suits a daily schedule. Past dates aren't allowed.",
            "default": ""
          },
          "checkOutDate": {
            "title": "Check-out date",
            "pattern": "^(\\d{4}-\\d{2}-\\d{2})?$",
            "type": "string",
            "description": "YYYY-MM-DD. Leave empty for a 2-night stay. Stays can be up to 30 nights.",
            "default": ""
          },
          "priceWindowEnd": {
            "title": "Track prices until (price calendar)",
            "pattern": "^(\\d{4}-\\d{2}-\\d{2})?$",
            "type": "string",
            "description": "Optional. Reprices the same length of stay for every check-in day from your check-in date up to this date, at most 60 days later. Each extra check-in day is one more row per hotel, charged as a normal hotel row. Best with a short list of specific hotels. Leave empty for one stay.",
            "default": ""
          },
          "adults": {
            "title": "Adults",
            "minimum": 1,
            "maximum": 12,
            "type": "integer",
            "description": "Number of adults, from 1 to 12. Google's quote is checked against your guest count.",
            "default": 2
          },
          "children": {
            "title": "Children",
            "minimum": 0,
            "maximum": 11,
            "type": "integer",
            "description": "Number of children. Give one age per child in Children ages. The actor accepts up to 12 guests in total.",
            "default": 0
          },
          "childrenAges": {
            "title": "Children ages",
            "type": "array",
            "description": "Each child's age at check-in, from 0 to 17. For two children aged 7 and 10, enter [7, 10]. The count must match Children.",
            "items": {
              "type": "integer",
              "minimum": 0,
              "maximum": 17
            },
            "default": []
          },
          "currency": {
            "title": "Currency",
            "pattern": "^[A-Za-z]{3}$",
            "type": "string",
            "description": "Three-letter code Google accepts, such as USD, EUR, GBP or JPY. Every quote must confirm this currency. The actor never converts prices.",
            "default": "USD"
          },
          "sortBy": {
            "title": "Sort results",
            "enum": [
              "google",
              "lowestPrice",
              "highestRating",
              "mostReviewed"
            ],
            "type": "string",
            "description": "Google's own order, or Google's sort by lowest price, highest rating or most reviews. Google sorts its whole list, and the actor keeps the rows it collected in that order.",
            "default": "google"
          },
          "minPrice": {
            "title": "Minimum nightly price",
            "minimum": 0,
            "type": "number",
            "description": "Lowest nightly rate in your currency. Zero means no minimum. Google applies it and each row is checked again. Hotels without a price are left out when you set a limit.",
            "default": 0
          },
          "maxPrice": {
            "title": "Maximum nightly price",
            "minimum": 0,
            "type": "number",
            "description": "Highest nightly rate in your currency. Zero means no maximum. It compares the base rate, which may leave out taxes.",
            "default": 0
          },
          "minRating": {
            "title": "Minimum guest rating",
            "minimum": 0,
            "maximum": 5,
            "type": "number",
            "description": "Lowest guest rating on Google's 0 to 5 scale. Zero means any. Values of 3.5, 4.0 or 4.5 and up also use Google's own rating filter, so more pages hold matches. Every row is checked against your exact number.",
            "default": 0
          },
          "hotelClass": {
            "title": "Minimum hotel stars",
            "minimum": 0,
            "maximum": 5,
            "type": "integer",
            "description": "Lowest published star class: 2, 3, 4 or 5, or 0 for any class. Google has no 1-star filter, so 1 is refused. Google applies it and each row is checked. Properties with no star class are left out. Use this or Exact hotel classes, not both.",
            "default": 0
          },
          "hotelClasses": {
            "title": "Exact hotel classes",
            "type": "array",
            "description": "Pick one or more star classes, such as 3 and 4 without 5. Google applies them and each row is checked. From the API, send them as strings, such as [\"3\", \"4\"].",
            "items": {
              "type": "string",
              "enum": [
                "2",
                "3",
                "4",
                "5"
              ],
              "enumTitles": [
                "2 stars",
                "3 stars",
                "4 stars",
                "5 stars"
              ]
            },
            "default": []
          },
          "amenities": {
            "title": "Hotel amenities",
            "type": "array",
            "description": "Keep hotels that have all the amenities you pick. All but Airport shuttle are the options in Google's own filter panel: Google applies them, and each results page must confirm the filter before rows are saved. Google's panel has no airport shuttle, so the actor keeps only hotels whose amenity list names one, which can mean fewer rows per page. Applies to location searches, not to specific hotels.",
            "items": {
              "type": "string",
              "enum": [
                "freeWifi",
                "freeBreakfast",
                "restaurant",
                "bar",
                "kidFriendly",
                "petFriendly",
                "freeParking",
                "parking",
                "evCharger",
                "roomService",
                "fitnessCenter",
                "spa",
                "pool",
                "indoorPool",
                "outdoorPool",
                "airConditioned",
                "wheelchairAccessible",
                "beachAccess",
                "allInclusive",
                "airportShuttle"
              ],
              "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 available",
                "Airport shuttle (checked by the actor)"
              ]
            },
            "default": []
          },
          "propertyTypes": {
            "title": "Hotel types",
            "type": "array",
            "description": "Narrow hotels to these types. Google applies the filter and each page must confirm it. Only types whose live results matched are offered, checked by name or by the Google Maps category of every result. Minshuku, Japanese-style business hotels and ryokan are for Japan. Applies to location searches, not to specific hotels.",
            "items": {
              "type": "string",
              "enum": [
                "beachHotels",
                "hostels",
                "inns",
                "motels",
                "resorts",
                "spaHotels",
                "bedAndBreakfasts",
                "minshuku",
                "japaneseBusinessHotels",
                "ryokan"
              ],
              "enumTitles": [
                "Beach hotels",
                "Hostels",
                "Inns",
                "Motels",
                "Resorts",
                "Spa hotels",
                "Bed and breakfasts",
                "Minshuku",
                "Japanese-style business hotels",
                "Ryokan"
              ]
            },
            "default": []
          },
          "freeCancellation": {
            "title": "Free cancellation only",
            "type": "boolean",
            "description": "Ask Google for rates you can cancel for free. Each quote must confirm the selection. Booking sites without free cancellation are left out, and each one shows its deadline when Google gives it.",
            "default": false
          },
          "vacationRentals": {
            "title": "Vacation rentals",
            "enum": [
              "include",
              "only",
              "exclude"
            ],
            "type": "string",
            "description": "Include vacation rentals with hotels as Google mixes them, ask Google for vacation rentals only, or leave rentals out. Leaving them out is the actor's own check on each row, so a page can hold fewer than 20 hotels. Every row's property type is checked.",
            "default": "include"
          },
          "rentalTypes": {
            "title": "Vacation rental types",
            "type": "array",
            "description": "With Vacation rentals set to only: the rental types to keep. Google applies them and each page must confirm the filter. Applies to location searches, not to specific hotels.",
            "items": {
              "type": "string",
              "enum": [
                "apartments",
                "houses",
                "villas",
                "cottages",
                "cabins",
                "chalets",
                "gites",
                "holidayVillages",
                "houseboats",
                "other"
              ],
              "enumTitles": [
                "Apartments",
                "Houses",
                "Villas",
                "Cottages",
                "Cabins",
                "Chalets",
                "Gîtes",
                "Holiday villages",
                "Houseboats",
                "Other"
              ]
            },
            "default": []
          },
          "rentalAmenities": {
            "title": "Vacation rental amenities",
            "type": "array",
            "description": "With Vacation rentals set to only: require these amenities from Google's rental filter panel. Applies to location searches, not to specific hotels.",
            "items": {
              "type": "string",
              "enum": [
                "freeWifi",
                "fitnessCenter",
                "airConditioned",
                "kidFriendly",
                "pool",
                "petFriendly",
                "hotTub",
                "kitchen",
                "patioOrDeck",
                "outdoorGrill",
                "crib",
                "fireplace"
              ],
              "enumTitles": [
                "Free Wi-Fi",
                "Fitness center",
                "Air-conditioned",
                "Kid-friendly",
                "Pool",
                "Pet-friendly",
                "Hot tub",
                "Kitchen",
                "Patio or deck",
                "Outdoor grill",
                "Crib",
                "Fireplace"
              ]
            },
            "default": []
          },
          "bedrooms": {
            "title": "Minimum bedrooms",
            "minimum": 0,
            "maximum": 5,
            "type": "integer",
            "description": "With Vacation rentals set to only: at least this many bedrooms, from 0 to 5. Google applies it and confirms it on each page, and each row is checked too. Rentals that don't state a bedroom count are left out. Needs language code en, because room counts are read from English labels.",
            "default": 0
          },
          "bathrooms": {
            "title": "Minimum bathrooms",
            "minimum": 0,
            "maximum": 5,
            "type": "integer",
            "description": "With Vacation rentals set to only: at least this many bathrooms, from 0 to 5. Google applies it and confirms it on each page, and each row is checked too. Rentals that don't state a bathroom count are left out. Needs language code en, because room counts are read from English labels.",
            "default": 0
          },
          "includeBookingSources": {
            "title": "Include booking site prices",
            "type": "boolean",
            "description": "Adds the booking sites Google lists for your stay that come with a rate and a booking link: name, logo, official-site flag, nightly rate, stay total, prices with taxes, guest count, free cancellation and booking link. A site without a rate or link, or without free cancellation when you ask for it, is left out with a warning. A location result needs one extra request per hotel. There's no extra charge.",
            "default": false
          },
          "includeRoomRates": {
            "title": "Include room rates",
            "type": "boolean",
            "description": "Adds each booking site's rooms with every rate: room name, nightly and total price, taxes, breakfast, free cancellation deadline and booking link. Google gives rooms for the sites that send them. No extra request beyond booking sites and no extra charge. Rows get much larger.",
            "default": false
          },
          "includeHotelDetails": {
            "title": "Include hotel details for location results",
            "type": "boolean",
            "description": "Looks up each hotel from a location search on its own Google page, like specific hotels get: more photos (13 to 28 in tests instead of 9), neighborhood, place ID, other review sites' scores and the typical price range. One extra request per hotel, no extra charge. Booking sites and room rates already include this.",
            "default": false
          },
          "maxPhotos": {
            "title": "Maximum photos per hotel",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "Most entries to keep in each row's photos list, from 0 to 100. Each photo has its link and, when Google has them, the original image link, size, caption, source and date. The actor reads the photos in the data it already fetches; it doesn't open Google's full gallery.",
            "default": 25
          },
          "includeReviews": {
            "title": "Include guest reviews",
            "type": "boolean",
            "description": "Adds a reviews list to each hotel row. Each review costs $0.0005, charged after the row holding it is saved. If that charge doesn't go through, you keep the reviews for free. Each 50 reviews take one request.",
            "default": false
          },
          "maxReviews": {
            "title": "Maximum reviews per hotel",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Most reviews to save for each hotel, from 1 to 1,000. If your run's maximum charge can't cover them all after the hotel row, the actor fetches fewer for that hotel, or none, and says so in OUTPUT.",
            "default": 20
          },
          "reviewsSort": {
            "title": "Review order",
            "enum": [
              "mostHelpful",
              "newest",
              "highestScore",
              "lowestScore"
            ],
            "type": "string",
            "description": "Google's review order: most helpful, newest, highest score or lowest score.",
            "default": "mostHelpful"
          },
          "reviewsTopic": {
            "title": "Review topic",
            "type": "string",
            "description": "Optional. Only reviews about one topic, using a name from the hotel's reviewsBreakdown, such as Service, Location or Breakfast. Leave empty for all reviews.",
            "default": ""
          },
          "reviewsSources": {
            "title": "Review sources",
            "maxItems": 10,
            "type": "array",
            "description": "Optional. Keep reviews from these sources only, such as Google or Tripadvisor, as named in each review's source. The actor reads Google's review pages and keeps the matches, reading at most 500 reviews per hotel. Leave empty for every source.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "includeMarkdown": {
            "title": "Add a text summary to each row",
            "type": "boolean",
            "description": "Adds markdownContent, a short readable summary of each hotel row and its reviews, handy for search indexes and AI tools.",
            "default": false
          },
          "languageCode": {
            "title": "Language code",
            "type": "string",
            "description": "Google's interface language, such as en or fr. Room counts for vacation rentals are read from English labels only.",
            "default": "en"
          },
          "countryCode": {
            "title": "Country code",
            "pattern": "^[A-Za-z]{2}$",
            "type": "string",
            "description": "Google's search region, such as us or gb.",
            "default": "us"
          },
          "device": {
            "title": "Prices as seen on",
            "enum": [
              "desktop",
              "mobile"
            ],
            "type": "string",
            "description": "Desktop or mobile. In a live test Google showed a phone some offers a desktop didn't get, such as a lower Vio.com rate and a Tripadvisor.com offer.",
            "default": "desktop"
          },
          "requestTimeoutSecs": {
            "title": "Request timeout (seconds)",
            "minimum": 5,
            "maximum": 120,
            "type": "integer",
            "description": "How long to wait for each Google response, from 5 to 120 seconds, before retrying. Requests go straight to Google from Apify's servers, without proxies. A proxyConfiguration pasted from another actor's input is accepted, ignored and noted in the log.",
            "default": 45
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}