logo

Google Hotels API

Scrape Google Hotels listings and per-vendor pricing as structured JSON

Google Hotels API

The Google Hotels API returns structured property data from Google Hotels in two steps:

  1. Listing — search hotels and get property metadata (name, photos, GPS, ratings, amenities, per-night price) plus a detail_token for each property.
  2. Detail — pass that detail_token to fetch the full per-vendor offer shelf (Booking.com, Hotels.com, Agoda, …) with live rate_per_night and total_rate.

Credit Usage: Each successful request costs 10 credits. For bulk processing, use the Async API with plugins.

Key Features

  • Two-step flow — listing call returns properties + detail_token; detail call returns the vendor pricing shelf.
  • Structured JSON — each property has name, description, GPS, hotel class, rating, reviews, amenities, images, per-night price, total rate, check-in/check-out times, nearby places, and a star-by-star ratings histogram.
  • Per-vendor pricing — the detail endpoint returns booking_sources[] with sponsored ("Featured options") and organic ("All options") entries unified into one ranked list.
  • Currency localization — per-request currency (USD, EUR, GBP, TRY, …). Combine with hl and gl for full regional search.
  • Sort & filter — lowest price / highest rating / most reviewed; price range, minimum rating, hotel class, amenities, free cancellation, eco-certified, special offers.
  • Vacation rentals modeproperty_types=12 switches to vacation rentals where available.
  • Pagination — token-based with next_page_token.
  • No blocks or CAPTCHAs — handled automatically.

Listing Endpoint

GET https://api.scrape.do/plugin/google/hotels

Basic Example

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?token=$TOKEN&q=Bali+hotels&check_in_date=2026-05-01&check_out_date=2026-05-03"

Occupancy parameters are not supported. Results always reflect the default occupancy of 2 adults, 0 children.

Query Guidelines

Use simple location-based queries for best results:

RecommendedAvoid
Paris hotelsParis luxury hotels near Eiffel Tower
Tokyo hotelsTokyo traditional ryokan hotels
Edinburgh hotelsEdinburgh Royal Mile hotels

Overly specific queries can return empty results. Simple "<City> hotels" queries have the highest success rate.

Request Parameters

Required

ParameterTypeDescription
tokenstringYour Scrape.do API authentication token
qstringHotel search query. Use simple "<City> hotels" form for best results
check_in_datestringCheck-in date in YYYY-MM-DD
check_out_datestringCheck-out date in YYYY-MM-DD. Must be after check_in_date

Localization

ParameterTypeDefaultDescription
hlstringenLanguage code
glstringusCountry code
currencystringUSDCurrency code (EUR, GBP, TRY, …)

Sorting

ParameterTypeDefaultDescription
sort_byinteger0 (relevance)3 = lowest price, 8 = highest rating, 13 = most reviewed

Filters

ParameterTypeDescription
min_priceintegerMinimum nightly price (≥ 0) in the requested currency
max_priceintegerMaximum nightly price (≥ 0 and ≥ min_price) in the requested currency
ratingintegerMinimum rating: 7 (3.5+), 8 (4.0+), 9 (4.5+)
hotel_classstringComma-separated star ratings (4,5 for 4★ and 5★). Each value 2–5
amenitiesstringComma-separated amenity codes (see Amenity Codes)
property_typesstringComma-separated property type codes. 12 = vacation rentals (switches mode)
free_cancellationbooleanOnly properties with free cancellation. Accepts true or 1
eco_certifiedbooleanOnly eco-certified properties
special_offersbooleanOnly properties with special offers

Pagination & Page Size

ParameterTypeDefaultDescription
next_page_tokenstringFrom the previous response's pagination.next_page_token. Pass back unchanged
limitinteger20Maximum properties to return on the page. Range: 1–20

More Examples

# 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&currency=TRY&token=$TOKEN"

# Cheapest first within £100–£300
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&currency=GBP&token=$TOKEN"

# 4–5 star, 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, 4.5+ rating, with 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"

# Page 2 (token from a previous response)
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": { "total_results": 18 },
  "properties": [ ... ],
  "ads": [ ... ],
  "brands": [ ... ],
  "pagination": { ... }
}

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/..." }
  ],
  "detail_token": "Q2hrSXZfSHlpTktIcGY2eUFSb01MMmN2TVhvemRHSm5aM0J6RUFFfDB4MTRiZTZkN2IxYjkwM2VjMTowYzZkMjFhMzRiMDgwNGNkZQ",
  "check_in_time": "3:00 PM",
  "check_out_time": "12:00 PM",
  "ratings": [
    { "stars": 5, "percent": 91, "count": 4546 },
    { "stars": 4, "percent": 7,  "count": 363 },
    { "stars": 3, "percent": 1,  "count": 96 }
  ],
  "reviews_breakdown": [
    { "name": "Cleanliness", "sentiment": 0.42, "total_mentioned": 88, "positive": 71, "negative": 8, "neutral": 9 }
  ],
  "price": { "display": "USD 187", "amount": 187.42, "currency": "USD" },
  "total_rate": { "display": "USD 374", "amount": 374, "currency": "USD" },
  "nearby_places": [
    { "name": "Beach", "transportations": [{ "type": 0, "duration": "10 min" }] }
  ]
}
FieldTypeAlways presentDescription
typestringyes"hotel" or "vacation rental"
namestringyesProperty name
descriptionstringShort description
gps_coordinatesobjectyes{ latitude, longitude }
hotel_classstringStar rating label (e.g. "5-star hotel")
extracted_hotel_classintNumeric star rating
overall_ratingfloatGuest rating out of 5
reviewsintNumber of guest reviews
amenitiesint[]yesAmenity codes (see Amenity Codes). Empty array when none
imagesobject[]yes[{ thumbnail, original_image }]. Empty array when none
detail_tokenstringyesOpaque token. Pass to the detail endpoint to fetch per-vendor pricing
check_in_timestringProperty check-in clock time (e.g. "3:00 PM")
check_out_timestringProperty check-out clock time
ratingsobject[]5→1 star histogram entries: { stars, percent, count }
reviews_breakdownobject[]Guest sentiment by category (Cleanliness, Service, …)
priceobjectPer-night rate in the requested currency. See Price
total_rateobjectTotal stay cost across the date range. See Price
nearby_placesobject[]Points of interest with transit-mode durations
Price
FieldTypeDescription
displaystringFormatted price as returned (e.g., "USD 187", "TRY 1,895")
amountfloatNumeric value (e.g., 187.42)
currencystringISO 4217 code reflecting the request's currency

ads[]

Sponsored hotel results attached to the listing, when present. Each entry is flagged with "sponsored": true.

{
  "sponsored": true,
  "name": "The LINQ - A Caesars Rewards Destination",
  "source": "Booking.com",
  "source_icon": "//www.gstatic.com/travel-hotels/branding/icon_184.png",
  "click": "/aclk?sa=l&ai=...",
  "gps_coordinates": { "latitude": 36.1206, "longitude": -115.1717 },
  "hotel_class": 4,
  "thumbnail": "//lh3.googleusercontent.com/proxy/...",
  "reviews": 42322,
  "amenities": [11, 23, 4, 24, 8, 29, 2],
  "price": { "display": "$291", "amount": 290.81, "currency": "USD" },
  "total_rate": { "display": "$582", "amount": 582, "currency": "USD" }
}

brands[]

Hotel chain / brand index attached to the listing, when present.

[
  { "id": 21, "name": "Ibis" },
  { "id": 61, "name": "Marriott Hotels & Resorts" }
]

pagination

Included when more pages exist. Omitted on the last page.

{ "current_from": 1, "current_to": 20, "next_page_token": "CgsI..." }

Pages 2+ may overlap by up to 2 entries — dedupe across pages by name + gps_coordinates. The detail_token is not stable across pages, so the same property may receive a different detail_token on each page.


Detail Endpoint

GET https://api.scrape.do/plugin/google/hotels/detail

Returns the per-vendor offer shelf for a single property — each booking source's rate_per_night, total_rate, and quoted occupancy in the requested currency, with sponsored ("Featured options") and organic ("All options") entries unified into one ranked list.

Property metadata (name, photos, GPS, ratings, amenities) is not repeated in the detail response — it was already returned by the listing call. Merge client-side using the detail_token as the join key.

Two-Step Example

# Step 1 — listing
curl "https://api.scrape.do/plugin/google/hotels?token=$TOKEN&q=Bali+hotels&check_in_date=2026-05-01&check_out_date=2026-05-03&currency=USD"
# → response.properties[i].detail_token

# Step 2 — detail (per-vendor pricing for one property)
curl "https://api.scrape.do/plugin/google/hotels/detail?token=$TOKEN&detail_token=Q2hrSXZfSHlpTktIcGY2eUFSb01MMmN2TVhvemRHSm5aM0J6RUFFfDB4MTRiZTZkN2IxYjkwM2VjMTowYzZkMjFhMzRiMDgwNGNkZQ&check_in_date=2026-05-01&check_out_date=2026-05-03&currency=USD"

Use the same check_in_date, check_out_date, and currency in both calls.

Detail Parameters

Required

ParameterTypeDescription
tokenstringYour Scrape.do API token
detail_tokenstringFrom a listing response's properties[].detail_token. Pass it back unchanged
check_in_datestringYYYY-MM-DD
check_out_datestringYYYY-MM-DD. Must be after check_in_date

Optional

ParameterTypeDefaultDescription
currencystringUSDISO 4217 currency code
glstringusCountry code
hlstringenLanguage code

Detail Response

{
  "search_parameters": {
    "engine": "google_hotels_detail",
    "detail_token": "Q2hrSXZfSHlp...",
    "check_in_date": "2026-05-01",
    "check_out_date": "2026-05-03",
    "currency": "USD",
    "gl": "us",
    "hl": "en"
  },
  "property": {
    "detail_token": "Q2hrSXZfSHlp...",
    "booking_sources": [
      {
        "sponsored": true,
        "name": "Booking.com",
        "id": 184,
        "click": "/aclk?...",
        "icon": "//www.gstatic.com/travel-hotels/branding/icon_184.png",
        "rate_per_night": { "display": "$221", "amount": 221.04, "currency": "USD" },
        "total_rate":     { "display": "$442", "amount": 442.08, "currency": "USD" },
        "num_guests": 2
      },
      {
        "name": "Hotels.com",
        "id": 1162912808,
        "click": "/aclk?...",
        "icon": "//www.gstatic.com/travel-hotels/branding/...",
        "rate_per_night": { "display": "$227", "amount": 227.33, "currency": "USD" },
        "total_rate":     { "display": "$455", "amount": 454.67, "currency": "USD" },
        "num_guests": 2
      }
    ]
  }
}

booking_sources[]

Each entry is one vendor's quote for the requested dates and currency. Sponsored entries appear first and carry "sponsored": true; organic entries follow.

FieldTypeAlways presentDescription
sponsoredbooleantrue on paid placements ("Featured options"); omitted on organic offers
namestringyesVendor brand (e.g. "Booking.com", "Hotels.com", "Agoda")
idintegerInternal source identifier
clickstringClick-through URL that redirects to the vendor's listing
iconstringVendor brand icon URL
rate_per_nightobjectPer-night rate. See Price. Omitted when not quoted
total_rateobjectTotal stay cost. See Price. Omitted when not quoted
num_guestsintegerOccupancy the rate is quoted for — always 2 when present

rate_per_night.currency and total_rate.currency reflect the request's currency. Numeric amount values are normalized — thousands separators are stripped before parsing.


Amenity Codes

Raw integer codes from Google's classification. Common values:

CodeAmenityCodeAmenity
1Fitness center16Outdoor pool
2Bar17Pet-friendly
4Restaurant20Indoor pool
5Room service22Pool
6Free breakfast23Air-conditioned
7Kids' club24Kitchen / kitchenette
8Spa25Smoke-free
9Business center26Full-service laundry
10Child-friendly27Free Wi-Fi
11Accessible29Wi-Fi
14Beach access31Airport shuttle
15Parking

Codes may change without notice. Raw integer values are forwarded as-is from Google. The same codes are returned in properties[].amenities[], so they round-trip safely.


Property Types

ValueWhen returned
"hotel"Traditional hotel, resort, inn, or hostel
"vacation rental"Vacation rental, apartment, or villa. Returned when property_types=12 is set

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.


Error Handling

{ "error": "error_code", "message": "Human readable error message" }

Common Error Codes

StatusErrorDescription
400token is requiredMissing token
400q (hotel search query) is requiredMissing q
400check_in_date is required (format: YYYY-MM-DD)Missing or malformed check_in_date
400check_out_date is required (format: YYYY-MM-DD)Missing or malformed check_out_date
400check_out_date must be after check_in_dateDate range inverted
400sort_by must be 3, 8, or 13Invalid sort_by
400min_price must be a non-negative integerInvalid min_price
400max_price must be a non-negative integerInvalid max_price
400min_price must be <= max_priceRange inverted
400rating must be 7, 8, or 9Invalid rating
400hotel_class values must be 2-5Invalid hotel_class
400detail_token is requiredDetail endpoint called without detail_token
400invalid detail_token: ...detail_token malformed or not base64url
502request failedTransient. Retry
502unexpected responseNon-200 upstream
500decompression failed / parse failedTransient. Retry

On this page