Google Hotels API
Scrape Google Hotels listings with ratings, amenities, classes, and images as structured JSON
The Google Hotels API is a specialized plugin that searches Google Hotels and returns property listings with names, descriptions, ratings, star classes, amenities, GPS coordinates, and images, all as structured JSON. It's designed for the listing-scope view: 18–20 properties per page with filters for price, rating, hotel class, brand, eco-certification, and free cancellation.
Credit Usage: Each successful request costs 10 credits. For bulk processing, use the Async API with plugins.
Key Features
- Structured JSON Output: Each property returns name, description, GPS coordinates, hotel class (numeric + label), guest rating, review count, amenities, and images.
- Currency Localization: Per-request
currency(USD,EUR,GBP,TRY, …) for region-specific pricing. Combine withhlandglfor full regional search. - Sort Modes: Lowest price, highest rating, or most reviewed (
sort_by=3 / 8 / 13). - Filters:
min_price/max_price, minimumrating(3.5+ / 4.0+ / 4.5+),hotel_class(2–5 stars),brands,amenities,property_types,free_cancellation,eco_certified,special_offers. - Vacation Rentals Mode:
property_types=12switches the listing to vacation rentals when available. - Pagination: Token-based. Fetch the next page by passing the previous response's
next_page_token. - No Blocks or CAPTCHAs: All anti-bot measures are handled automatically by Scrape.do.
Endpoint
GET https://api.scrape.do/plugin/google/hotelsOccupancy parameters are not supported. Results always reflect the default occupancy of 2 adults, 0 children. Adults / children / children-ages cannot be customized.
Query Guidelines
For best results, use simple location-based queries:
| Recommended | Avoid |
|---|---|
Paris hotels | Paris luxury hotels near Eiffel Tower |
Tokyo hotels | Tokyo traditional ryokan hotels |
Edinburgh hotels | Edinburgh Royal Mile hotels |
Overly specific queries may return empty results because Google resolves the query text to a location internally. Simple "<City> hotels" queries have the highest success rate.
Request Parameters
Required
| Parameter | Type | Description |
|---|---|---|
token | string | Your Scrape.do API authentication token |
q | string | Hotel search query. Use simple "<City> hotels" form for best results |
check_in_date | string | Check-in date in YYYY-MM-DD |
check_out_date | string | Check-out date in YYYY-MM-DD. Should be after check_in_date (not validated server-side) |
Localization
| Parameter | Type | Default | Description |
|---|---|---|---|
hl | string | en | Language code |
gl | string | us | Country code |
currency | string | USD | Currency code (EUR, GBP, TRY, …) |
Sorting
| Parameter | Type | Default | Description |
|---|---|---|---|
sort_by | integer | 0 (relevance) | 3 = lowest price, 8 = highest rating, 13 = most reviewed |
Filters
| Parameter | Type | Default | Description |
|---|---|---|---|
min_price | integer | — | Minimum price filter (≥ 0) |
max_price | integer | — | Maximum price filter (≥ 0 and ≥ min_price) |
rating | integer | — | Minimum rating: 7 (3.5+), 8 (4.0+), 9 (4.5+) |
hotel_class | string | — | Comma-separated star ratings (4,5 for 4★ and 5★). Each value 2–5 |
brands | string | — | Comma-separated brand IDs (e.g. 33 for Accor). Parent brand IDs expand to children automatically |
amenities | string | — | Comma-separated amenity codes (see Amenity Codes below) |
property_types | string | — | Comma-separated property type codes. 12 = vacation rentals (switches mode) |
free_cancellation | boolean | false | Only properties with free cancellation. Accepts true or 1 |
eco_certified | boolean | false | Only eco-certified properties |
special_offers | boolean | false | Only properties with special offers |
Pagination
| Parameter | Type | Default | Description |
|---|---|---|---|
next_page_token | string | — | From the previous response's pagination.next_page_token. Pass back unchanged |
Example Usage
Basic Search
curl --location --request GET 'https://api.scrape.do/plugin/google/hotels?token=<SDO-token>&q=Bali+hotels&check_in_date=2026-05-01&check_out_date=2026-05-03'import requests
import json
token = "<SDO-token>"
url = f"https://api.scrape.do/plugin/google/hotels?token={token}&q=Bali+hotels&check_in_date=2026-05-01&check_out_date=2026-05-03"
response = requests.request("GET", url)
print(json.dumps(response.json(), indent=2))const axios = require('axios');
const token = "<SDO-token>";
const url = `https://api.scrape.do/plugin/google/hotels?token=${token}&q=Bali+hotels&check_in_date=2026-05-01&check_out_date=2026-05-03`;
axios.get(url)
.then(response => {
console.log(JSON.stringify(response.data, null, 2));
})
.catch(error => {
console.error(error);
});package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
token := "<SDO-token>"
url := fmt.Sprintf(
"https://api.scrape.do/plugin/google/hotels?token=%s&q=Bali+hotels&check_in_date=2026-05-01&check_out_date=2026-05-03",
token,
)
resp, err := http.Get(url)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}require 'net/http'
require 'json'
token = "<SDO-token>"
url = URI("https://api.scrape.do/plugin/google/hotels?token=#{token}&q=Bali+hotels&check_in_date=2026-05-01&check_out_date=2026-05-03")
response = Net::HTTP.get(url)
puts JSON.pretty_generate(JSON.parse(response))import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class GoogleHotels {
public static void main(String[] args) throws Exception {
String token = "<SDO-token>";
String url = String.format(
"https://api.scrape.do/plugin/google/hotels?token=%s&q=Bali+hotels&check_in_date=2026-05-01&check_out_date=2026-05-03",
token
);
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setRequestMethod("GET");
BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream())
);
String line;
StringBuilder response = new StringBuilder();
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
System.out.println(response.toString());
}
}using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
string token = "<SDO-token>";
string url = $"https://api.scrape.do/plugin/google/hotels?token={token}&q=Bali+hotels&check_in_date=2026-05-01&check_out_date=2026-05-03";
using HttpClient client = new HttpClient();
string response = await client.GetStringAsync(url);
Console.WriteLine(response);
}
}<?php
$token = "<SDO-token>";
$url = "https://api.scrape.do/plugin/google/hotels?token={$token}&q=Bali+hotels&check_in_date=2026-05-01&check_out_date=2026-05-03";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo json_encode(json_decode($response), JSON_PRETTY_PRINT);
?>curl "https://api.scrape.do/plugin/google/hotels?q=Bali+hotels&check_in_date=2026-05-01&check_out_date=2026-05-03&token=$TOKEN"Turkish Locale + TRY Currency
curl "https://api.scrape.do/plugin/google/hotels?q=Istanbul+hotels&check_in_date=2026-05-01&check_out_date=2026-05-03&hl=tr&gl=tr¤cy=TRY&token=$TOKEN"Sort by Lowest Price + Range
curl "https://api.scrape.do/plugin/google/hotels?q=London+hotels&check_in_date=2026-05-01&check_out_date=2026-05-03&sort_by=3&min_price=100&max_price=300¤cy=GBP&token=$TOKEN"4–5 Star with Free Cancellation
curl "https://api.scrape.do/plugin/google/hotels?q=Dubai+hotels&check_in_date=2026-05-01&check_out_date=2026-05-03&hotel_class=4,5&free_cancellation=true&token=$TOKEN"Eco-Certified, High Rating, Pool
curl "https://api.scrape.do/plugin/google/hotels?q=Maldives+hotels&check_in_date=2026-05-01&check_out_date=2026-05-03&rating=9&eco_certified=true&amenities=22&token=$TOKEN"Vacation Rentals
curl "https://api.scrape.do/plugin/google/hotels?q=Santorini+hotels&check_in_date=2026-05-01&check_out_date=2026-05-03&property_types=12&token=$TOKEN"Pagination
# Page 1
curl "https://api.scrape.do/plugin/google/hotels?q=Paris+hotels&check_in_date=2026-05-01&check_out_date=2026-05-03&token=$TOKEN"
# → response includes pagination.next_page_token
# Page 2
curl "https://api.scrape.do/plugin/google/hotels?q=Paris+hotels&check_in_date=2026-05-01&check_out_date=2026-05-03&next_page_token=CgsI...&token=$TOKEN"Response
Top-Level Structure
{
"search_parameters": { ... },
"search_information": { ... },
"properties": [ ... ],
"pagination": { ... }
}search_parameters
{
"engine": "google_hotels",
"q": "Bali hotels",
"check_in_date": "2026-05-01",
"check_out_date": "2026-05-03",
"currency": "USD",
"gl": "us",
"hl": "en"
}Optional fields appear when set: sort_by, min_price, max_price, rating, hotel_class, brands, amenities, property_types, free_cancellation, eco_certified, special_offers, next_page_token.
search_information
{ "total_results": 18 }properties[]
{
"type": "hotel",
"name": "The Anvaya Beach Resort Bali",
"description": "Sophisticated resort offering 8 pools, 2 restaurants & a spa, plus a private beach & a kids' club.",
"gps_coordinates": { "latitude": -8.7322535, "longitude": 115.1659877 },
"hotel_class": "5-star hotel",
"extracted_hotel_class": 5,
"overall_rating": 4.7,
"reviews": 14342,
"amenities": [6, 29, 16, 22, 2, 8, 26, 5, 4, 23, 24, 14, 1, 31, 27, 7, 11],
"images": [
{
"thumbnail": "https://lh3.googleusercontent.com/...",
"original_image": "https://lh3.googleusercontent.com/..."
}
],
"property_token": "ChkI0Nqb_63cnPoTGg0vZy8xMWJ4ZjNoMXloEAE",
"property_details_link": "https://api.scrape.do/plugin/google/hotels/detail?property_token=ChkI0Nqb_63cnPoTGg0vZy8xMWJ4ZjNoMXloEAE&token=TOKEN&gl=us&hl=en¤cy=USD"
}Field Reference
| Field | Type | Always present | Description |
|---|---|---|---|
type | string | yes | "hotel" or "vacation rental" |
name | string | yes | Property name |
description | string | Short description | |
gps_coordinates | object | yes | { latitude, longitude } |
hotel_class | string | Star rating label (e.g. "5-star hotel") | |
extracted_hotel_class | int | Numeric star rating | |
overall_rating | float | Guest rating out of 5 | |
reviews | int | Number of guest reviews | |
amenities | int[] | yes | Amenity codes (see Amenity Codes). Empty array when none |
images | object[] | yes | [{ thumbnail, original_image }]. Empty array when none |
property_token | string | yes | Opaque token identifying the property. Use with the detail endpoint |
property_details_link | string | yes | Ready-to-call URL for the detail endpoint with property_token and localization pre-filled. Replace TOKEN with your API token |
pagination
Included when more pages exist. Omitted on the last page.
{
"current_from": 1,
"current_to": 20,
"next_page_token": "CgsI..."
}| Field | Type | Description |
|---|---|---|
current_from | int | 1-based index of the first property on this page |
current_to | int | 1-based index of the last property on this page |
next_page_token | string | Pass back as next_page_token for the next page |
Property Types
| Value | When returned |
|---|---|
"hotel" | Traditional hotel, resort, inn, or hostel |
"vacation rental" | Vacation rental, apartment, or villa. Returned when property_types=12 is set |
The mode-switching behavior of property_types=12 depends on inventory at the destination. Some queries continue to return type: "hotel" even when vacation rentals are requested.
Filter Reference
The Hotels API provides three filter layers: scalar filters (price range, rating threshold), comma-separated category filters (hotel_class, brands, amenities, property_types), and boolean toggles (free_cancellation, eco_certified, special_offers).
Price Filters
# Hotels between $100 and $300 per night
curl "https://api.scrape.do/plugin/google/hotels?q=London+hotels&check_in_date=2026-05-01&check_out_date=2026-05-03&min_price=100&max_price=300&token=$TOKEN"| Parameter | Type | Description |
|---|---|---|
min_price | int | Minimum nightly price (≥ 0) |
max_price | int | Maximum nightly price (≥ 0, ≥ min_price) |
Either bound can be omitted. Currency follows the currency parameter.
Rating Threshold
| Value | Meaning |
|---|---|
7 | 3.5+ stars |
8 | 4.0+ stars |
9 | 4.5+ stars |
# Only 4.5+ rated hotels
curl "...&rating=9&..."Hotel Class
Comma-separated star ratings. Each value must be 2–5.
| Value | Meaning |
|---|---|
2 | 2-star |
3 | 3-star |
4 | 4-star |
5 | 5-star |
# 4-star and 5-star only
curl "...&hotel_class=4,5&..."Sort Modes
sort_by | Meaning |
|---|---|
0 (default) | Relevance |
3 | Lowest price |
8 | Highest rating |
13 | Most reviewed |
curl "...&sort_by=3&..." # cheapest first
curl "...&sort_by=8&..." # highest rated first
curl "...&sort_by=13&..." # most reviewed firstBoolean Filters
| Parameter | Effect |
|---|---|
free_cancellation=true | Only properties with free cancellation |
eco_certified=true | Only eco-certified properties |
special_offers=true | Only properties with active special offers |
All accept true or 1. They combine freely.
# Eco-certified, free-cancellation, special offers
curl "...&eco_certified=true&free_cancellation=true&special_offers=true&..."Brands
brands accepts comma-separated brand IDs. Parent brand IDs (e.g. 33 for Accor) automatically expand to their child brands.
# Accor properties
curl "...&brands=33&..."Brand IDs are integers; pass each as it appears in Google's classification.
Property Types
property_types accepts comma-separated property type codes.
| Value | Meaning |
|---|---|
12 | Vacation rentals (switches mode) |
| Other | Remain in hotels mode (filter to specific property kinds) |
# Vacation rentals only
curl "...&property_types=12&..."Mode switching depends on inventory. Some destinations continue to return type: "hotel" even when property_types=12 is set if no vacation rentals are listed.
Amenities
amenities accepts comma-separated amenity codes: raw integers from Google's classification.
Amenity Codes
| Code | Amenity |
|---|---|
| 1 | Fitness center |
| 2 | Bar |
| 4 | Restaurant |
| 5 | Room service |
| 6 | Free breakfast |
| 7 | Kids' club |
| 8 | Spa |
| 9 | Business center |
| 10 | Child-friendly |
| 11 | Accessible |
| 14 | Beach access |
| 15 | Parking |
| 16 | Outdoor pool |
| 17 | Pet-friendly |
| 20 | Indoor pool |
| 22 | Pool |
| 23 | Air-conditioned |
| 24 | Kitchen / kitchenette |
| 25 | Smoke-free |
| 26 | Full-service laundry |
| 27 | Free Wi-Fi |
| 29 | Wi-Fi |
| 31 | Airport shuttle |
# Pool + Free Wi-Fi
curl "...&amenities=22,27&..."Codes may change without notice. Raw integer values are forwarded as-is from Google. The same codes are returned in properties[].amenities[] on the response, so they round-trip safely.
Combining Filters
All filters compose freely. The most restrictive query wins; if no properties match, properties: [] is returned along with total_results: 0.
# 4-5 star, eco-certified, $200-500/night, with pool, sorted by rating
curl "https://api.scrape.do/plugin/google/hotels?\
q=Maldives+hotels&\
check_in_date=2026-05-01&\
check_out_date=2026-05-03&\
hotel_class=4,5&\
eco_certified=true&\
min_price=200&\
max_price=500&\
amenities=22&\
sort_by=8&\
token=$TOKEN"Scope
This endpoint returns listing-scope data only. Per-property pricing (rate_per_night, total_rate, price breakdowns), check-in/check-out times, nearby places, and review breakdowns are available from the detail endpoint (/plugin/google/hotels/detail). Use the property_details_link returned on each property to fetch them.
Error Handling
{ "error": "error_code", "message": "Human readable error message" }Common Error Codes
| Status | Error | Description |
|---|---|---|
400 | token is required | Missing token |
400 | q (hotel search query) is required | Missing q |
400 | check_in_date is required (format: YYYY-MM-DD) | Missing or malformed check_in_date |
400 | check_out_date is required (format: YYYY-MM-DD) | Missing or malformed check_out_date |
400 | sort_by must be 3, 8, or 13 | Invalid sort_by |
400 | min_price must be a non-negative integer | Invalid min_price |
400 | max_price must be a non-negative integer | Invalid max_price |
400 | min_price must be <= max_price | Range inverted |
400 | rating must be 7, 8, or 9 | Invalid rating |
400 | hotel_class values must be 2-5 | Invalid hotel_class |
400 | hotel_class: invalid int "..." | Non-integer in hotel_class |
400 | brands: invalid int "..." | Non-integer in brands |
400 | amenities: invalid int "..." | Non-integer in amenities |
400 | property_types: invalid int "..." | Non-integer in property_types |
400 | failed to construct RPC body: ... | Invalid date format |
502 | request failed | Transient. Retry |
502 | unexpected response | Non-200 from Google |
500 | decompression failed / parse failed | Transient. Retry |
check_out_date is not validated against check_in_date. Sending a check-out date before the check-in date currently returns 200 with results (likely Google falls back to a default). Don't rely on the API as a guardrail; validate dates client-side.

