🎉Developer Free Trial — Get 1 week of full API access, no credit card required. Claim your trial →
DocumentationAPI Reference

Hotel Pricing API Reference

Programmatic access to real-time hotel pricing data from Google Hotels. Async job-based architecture — submit, poll, retrieve.

Base URL: https://gumo.co.in/api/v1/scraper/Auth: X-API-Key header

Overview

The ScrapeGuys Hotel Pricing API provides programmatic access to real-time hotel pricing data from Google Hotels. It extracts OTA (Online Travel Agency) booking links, prices, and hotel metadata for any hotel worldwide.

The API uses an async job-based architecture: submit a scrape request and receive a job_id, then poll for results. Jobs are processed by Celery workers using residential proxies for Google Hotels data extraction.

PropertyValue
Base URLhttps://gumo.co.in/api/v1/scraper/
AuthenticationAPI key via X-API-Key header
ArchitectureAsync job-based (submit → poll → results)
Data sourceGoogle Hotels via residential proxies
Response formatJSON

Authentication

All requests require the X-API-Key header. API keys are prefixed with gsk_ and are 68 characters long.

http
X-API-Key: gsk_your_api_key_here

Contact the ScrapeGuys team to obtain an API key.

CodeMeaning
401 UnauthorizedMissing or invalid API key
403 ForbiddenAPI key is deactivated

Rate Limits & Quotas

Default limits are configurable per client. Contact us to adjust limits for your plan.

LimitDefaultConfigurable
Per-minute rate limit10 requests/minYes
Daily quota1,000 requests/dayYes
Monthly quota20,000 requests/monthYes
When a limit is exceeded, the API returns 429 Too Many Requests with a descriptive message.

Lookup Modes

The API supports two lookup modes:

ModeInputSpeedBandwidthReliability
Place ID recommendedplace_id + hotel_name~3–5s~25 KB100% deterministic
Name Searchhotel_name + city~8–12s~300 KB~87%
Place ID mode uses the Google Maps Preview API for a direct, deterministic lookup. No name matching — the Place ID uniquely identifies the hotel. You can provide both place_id and city — the API uses Place ID first and falls back to name search if needed.

Endpoints

Request Body

FieldTypeRequiredDefaultConstraints
hotel_namestringYesMax 300 chars
place_idstringNo""Google Place ID
citystringNo""City for name-based search
check_indateYesYYYY-MM-DD, not past, <1yr ahead
check_outdateYesAfter check_in, max 30 nights
adultsintegerNo21–10
childrenintegerNo00–6
Either place_id or city must be provided.

Response 202 Accepted

json
{
  "job_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "pending",
  "poll_url": "/api/v1/scraper/scrape/a1b2c3d4-e5f6-7890-abcd-ef1234567890/"
}

Job Statuses

StatusMeaningAction
pendingJob queued, not yet startedPoll again in 2s
processingScraper is runningPoll again in 2s
completedResults available in result fieldRead result
failedScraper encountered an errorCheck error_message

Response 200 OK

json
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "completed",
  "hotel_name": "Rambagh Palace",
  "city": "",
  "place_id": "ChIJm14which9bDkRXF7ciSSR4eA",
  "check_in": "2026-04-10",
  "check_out": "2026-04-12",
  "adults": 2,
  "children": 0,
  "result": {
    "hotel_metadata": {
      "name": "Rambagh Palace",
      "hotel_class": 5,
      "user_rating": 4.7,
      "review_count": 8234,
      "address": "Bhawani Singh Road, Jaipur, Rajasthan 302005",
      "amenities": ["Free breakfast", "Pool", "Spa", "Free Wi-Fi"],
      ...
    },
    "pricing": [
      {
        "platform_name": "Booking.com",
        "price": 45000.0,
        "price_display": "₹45,000",
        "currency": "INR",
        "booking_url": "https://www.booking.com/hotel/in/...",
        "free_cancellation": true,
        "is_official": false,
        ...
      }
    ],
    "navigation_mode": "maps_preview",
    "timings": { "total": 3.2 }
  },
  "error_message": "",
  "created_at": "2026-04-08T10:30:00Z",
  "completed_at": "2026-04-08T10:30:03.7Z",
  "duration_seconds": 3.2,
  "bandwidth_kb": 21.5
}

Request Body

FieldTypeRequiredConstraints
check_indateYesYYYY-MM-DD
check_outdateYesAfter check_in
hotelsarrayYes1–20 items
hotels[].hotel_namestringYesMax 300 chars
hotels[].place_idstringNoRecommended
hotels[].citystringNoFallback for name search
hotels[].adultsintegerNo1–10, default 2
hotels[].childrenintegerNo0–6, default 0

Response 202 Accepted

json
{
  "jobs": [
    {
      "job_id": "uuid-1",
      "hotel_name": "Rambagh Palace",
      "city": "",
      "poll_url": "/api/v1/scraper/scrape/uuid-1/"
    },
    {
      "job_id": "uuid-2",
      "hotel_name": "Taj Lake Palace",
      "city": "",
      "poll_url": "/api/v1/scraper/scrape/uuid-2/"
    }
  ]
}

Request Body

json
{
  "job_ids": ["uuid-1", "uuid-2", "uuid-3"]
}

Response 200 OK

json
{
  "results": [
    { "id": "uuid-1", "status": "completed", "result": { ... } },
    { "id": "uuid-2", "status": "processing", "result": null },
    { "id": "uuid-3", "status": "completed", "result": { ... } }
  ]
}

Response 200 OK

json
{
  "client": "Your Company Name",
  "lifetime": {
    "total_requests": 12450,
    "total_bandwidth_kb": 3245678.5
  },
  "limits": {
    "rate_limit_per_minute": 10,
    "daily_quota": 1000,
    "monthly_quota": 20000
  },
  "usage": [
    {
      "date": "2026-04-08",
      "request_count": 142,
      "success_count": 138,
      "failure_count": 4,
      "total_duration_seconds": 856.3,
      "total_bandwidth_kb": 36890.2
    }
  ]
}

Response Schemas

pricing Array

Each entry represents one OTA's offer. Typical count: 12–25 per hotel.

FieldTypeDescription
platform_namestringOTA name (e.g., "Booking.com", "Agoda")
pricefloatNumeric price
price_displaystringFormatted price string (e.g., "₹45,000")
currencystringISO currency code (e.g., "INR", "USD")
price_before_discountfloat/nullOriginal price if discounted, else null
booking_urlstringDirect OTA booking URL (not a Google redirect)
free_cancellationboolWhether free cancellation is available
cancellation_deadlinestringDeadline for free cancellation, empty if none
room_typestringRoom type description
breakfast_includedboolWhether free breakfast is included
tax_includedbool/nullWhether tax is included, null if unknown
is_officialboolWhether this is the hotel's official direct site
logo_urlstringOTA brand logo URL

hotel_metadata Object

FieldTypeAlways PresentDescription
namestringYesHotel name as displayed on Google
hotel_classint/nullNoStar rating (1–5)
user_ratingfloat/nullNoGoogle user rating (1.0–5.0)
review_countint/nullNoTotal Google review count
addressstringNoFull address
phonestringNoPhone number with country code
websitestringNoOfficial hotel website URL
latitudefloatNoGPS latitude
longitudefloatNoGPS longitude
check_in_timestringNoCheck-in time (e.g., "14:00")
check_out_timestringNoCheck-out time (e.g., "12:00")
amenitiesarray[string]NoHotel amenities list
imagesarray[string]NoGoogle-hosted image URLs
neighborhoodstringNoNeighborhood name and description

Error Handling

HTTP-Level Errors

CodeMeaning
400Invalid input (missing fields, bad dates, no place_id or city)
401Missing or invalid API key
404Job ID not found or belongs to another client
429Rate limit or quota exceeded
500Unexpected server error

Job-Level Errors

Errors in completed jobs appear in the error_message field.

ErrorMeaningMode
Empty place dataGoogle Maps didn't return data for this Place IDPlace ID
Request timed outGoogle didn't respond within timeoutBoth
Hotel "X" not found in listing resultsHotel name didn't match any Google Hotels listingName search
Listing page is JS-renderedGoogle returned a JS-heavy page that couldn't be parsedName search

Code Examples

Python — Place ID Mode (Recommended)

python
import time
import requests

API_BASE = "https://gumo.co.in/api/v1/scraper"
API_KEY = "gsk_your_key_here"
HEADERS = {"X-API-Key": API_KEY}

# Submit job with Place ID (deterministic, fast)
response = requests.post(f"{API_BASE}/scrape/", json={
    "hotel_name": "Taj Mahal Palace",
    "place_id": "ChIJbSFzZEzO5zsRgHj0KiJfcoA",
    "check_in": "2026-08-01",
    "check_out": "2026-08-03",
}, headers=HEADERS)

job_id = response.json()["job_id"]

# Poll for results
while True:
    result = requests.get(f"{API_BASE}/scrape/{job_id}/", headers=HEADERS).json()
    if result["status"] in ("completed", "failed"):
        break
    time.sleep(2)

# Use results
if result["status"] == "completed":
    for ota in result["result"]["pricing"]:
        print(f"{ota['platform_name']}: {ota['price_display']}")

Python — Batch Example

python
# Submit batch — mix of Place ID and name-based lookups
response = requests.post(f"{API_BASE}/batch/", json={
    "check_in": "2026-08-01",
    "check_out": "2026-08-03",
    "hotels": [
        {"hotel_name": "Rambagh Palace", "place_id": "ChIJm14which9bDkRXF7ciSSR4eA"},
        {"hotel_name": "Taj Lake Palace", "city": "Udaipur"},
    ]
}, headers=HEADERS)

job_ids = [j["job_id"] for j in response.json()["jobs"]]

# Poll all at once after waiting
time.sleep(5)
results = requests.post(f"{API_BASE}/batch/results/", json={
    "job_ids": job_ids
}, headers=HEADERS).json()

for job in results["results"]:
    print(f"\n{job.get('hotel_name')} ({job['status']}):")
    if job["result"]:
        for ota in job["result"].get("pricing", [])[:3]:
            print(f"  {ota['platform_name']}: {ota['price_display']}")

cURL

bash
# Submit with Place ID
curl -X POST https://gumo.co.in/api/v1/scraper/scrape/ \
  -H "X-API-Key: gsk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"hotel_name":"Rambagh Palace","place_id":"ChIJm14which9bDkRXF7ciSSR4eA","check_in":"2026-08-01","check_out":"2026-08-03"}'

# Poll result
curl https://gumo.co.in/api/v1/scraper/scrape/JOB_ID_HERE/ \
  -H "X-API-Key: gsk_your_key"

How to Get a Google Place ID

Use the Google Places Text Search API with a minimal field mask (free tier). Place IDs are stable — cache them for repeated lookups of the same hotel.

bash
curl -X POST "https://places.googleapis.com/v1/places:searchText" \
  -H "Content-Type: application/json" \
  -H "X-Goog-Api-Key: YOUR_GOOGLE_API_KEY" \
  -H "X-Goog-FieldMask: places.id" \
  -d '{"textQuery": "Rambagh Palace Jaipur hotel", "maxResultCount": 1}'

# Response:
# {"places": [{"id": "ChIJm14which9bDkRXF7ciSSR4eA"}]}
Place IDs are stable identifiers — cache them once per hotel and reuse across all subsequent lookups. Google Places Text Search API docs

Performance

MetricPlace ID ModeName Search Mode
Job completion time3–5s8–12s
Bandwidth per job~25 KB~300 KB
Reliability100% (deterministic)~87% (name matching)
OTAs per hotel12–2512–25
Recommended polling strategy: Poll every 2 seconds. Timeout after 30 seconds (jobs rarely exceed 15s). Most jobs complete in 3–8 seconds.