API Reference

Google Maps data, one request away

A ready-to-use REST API for Google Maps. Search a point for its local businesses, resolve any place by its place_id into its full record, pull the complete review set, or rank a business across a local search grid, all matched by stable place id, billed only for successful calls.

https://api.hexscraper.comAuth · API keyJSON
Overview

Introduction

The Hexscraper API is a synchronous request/response service: you call an endpoint, you get the data back in the same HTTP response, no queue or webhook to manage. Every business is addressed by its Google place_id (a CID-backed ChIJ… id), so results are never confused between same-name look-alikes.

All responses are JSON. The base URL is https://api.hexscraper.com.

Security

Authentication

Authenticate every request with an API key in the Authorization header as a Bearer token. Keys are issued per account, so keep them server-side and never ship one to a browser.

Authorization header
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx

A missing or invalid key returns 401.

Pricing

Billing & credits

Usage is metered in credits. Billing is reserve-then-refund: a call reserves its credits up front and refunds anything unused, so you only pay for successful results. A 4xx, a 503, or an upstream failure is never charged.

EndpointCost
GET /v1/search1 credit per non-empty search (~20 businesses); empty is free
GET /v1/places/{id}1 credit per lookup
GET /v1/places/{id}/reviews1 credit per 10 reviews returned (min 1)
GET /v1/visibilitygrid_size² credits (e.g. a 5×5 grid = 25)

A cache hit still bills (it saves you the latency, not the credit). Running out of credits returns 402.

Limits

Rate limits

Limits are per account, over a fixed one-minute window: 120/min for place lookups and the visibility grid, 60/min for reviews (each reviews call can page a lot of data). Exceeding a limit returns 429 with a Retry-After header, and is never billed.

Reliability

Idempotency

Send an Idempotency-Key header on any request. A retry carrying the same key replays the stored response without re-charging or re-scraping; a concurrent duplicate gets 409 while the first is still running.

Idempotent retry
Idempotency-Key: 9f1c2b7a-restaurant-batch-042
Reference

Errors

Errors use standard HTTP status codes and a JSON body { "detail": "…" }. A 503means the data was temporarily unavailable (not that the place doesn't exist). Retry after the Retry-After delay; it is never billed.

StatusMeaning
400Malformed place_id (not a CID-backed ChIJ… id) or invalid parameters.
401Missing or invalid API key.
402Out of credits. Top up to continue.
409A request with the same Idempotency-Key is already in progress.
429Rate limit exceeded. Honour the Retry-After header. Not billed.
503Temporarily unavailable (upstream/farm). Retry after Retry-After. Not billed.

Query parameters

FieldTypeDescription
keywordrequiredstringThe search term, e.g. "tapas" or "dentist". URL-encode spaces and accents (a space becomes %20).
latrequirednumberLatitude of the search centre (−90 to 90).
lonrequirednumberLongitude of the search centre (−180 to 180).
hlstringGoogle Maps host language for the response, e.g. "es" or "pt-BR". Categories, attributes and price formatting come back in that language, and they are Google's own strings, not a translation. Defaults to English.

Request

curl "https://api.hexscraper.com/v1/search?keyword=tapas&lat=36.3707&lon=-6.1809" \
  -H "Authorization: Bearer $HEXSCRAPER_API_KEY"

Response

200 OK · application/json
{
  "keyword": "tapas",
  "latitude": 36.3707,
  "longitude": -6.1809,
  "count": 20,
  "results": [
    {
      "place_id": "ChIJx3-pvNszDA0R837NptBLjM4",
      "name": "Café bar la Almadraba",
      "rating": 4.6,
      "reviews_count": 1071,
      "price_level": "€10-20",
      "phone": null,
      "website": null,
      "address": "Avenida la Barrosa, 11130 Chiclana, Cádiz",
      "city": "Chiclana",
      "latitude": 36.3707792,
      "longitude": -6.180956,
      "categories": ["Restaurante", "Bar", "Pub"],
      "primary_category": "Restaurante",
      "business_status": "Open"
    }
  ]
}

An empty result (no businesses at that point) returns count: 0 and is not billed. For richer fields on a single business (amenities, popular times, the full review set), feed a result's place_id into the endpoints below.


Place details

1 credit
GET/v1/places/{place_id}
Resolve a single place_id to its full public record: name, rating and review count, contact, address components, categories, popular times, the review keyword cloud, related places, and a sample of the most relevant reviews.

Path parameters

FieldTypeDescription
place_idrequiredstringA CID-backed Google place_id (ChIJ…).

Query parameters

FieldTypeDescription
hlstringGoogle Maps host language for the response, e.g. "es" or "pt-BR". Defaults to English.

Request

curl "https://api.hexscraper.com/v1/places/ChIJx3-pvNszDA0R837NptBLjM4" \
  -H "Authorization: Bearer $HEXSCRAPER_API_KEY"

Response

200 OK · application/json
{
  "place_id": "ChIJx3-pvNszDA0R837NptBLjM4",
  "name": "Café bar la Almadraba",
  "rating": 4.6,
  "reviews_count": 1071,
  "price_level": "€10-20",
  "website": null,
  "phone": null,
  "address": "Avenida la Barrosa, 11130 Chiclana, Cádiz",
  "city": "Chiclana",
  "country_code": "ES",
  "latitude": 36.3707792,
  "longitude": -6.180956,
  "categories": ["Restaurante", "Bar", "Pub"],
  "primary_category": "Restaurante",
  "business_status": "Open",
  "is_claimed": true,
  "owner_name": "Café bar la Almadraba",
  "time_spent": "People typically spend 45 min to 1.5 hr here",
  "reviews_tags": [
    { "keyword": "tapas", "count": 83 },
    { "keyword": "fried fish", "count": 12 }
  ],
  "popular_times": { "Friday": [[12, 0], [13, 54], [20, 88], [21, 71]] },
  "people_also_search": [
    { "name": "EL ARBOL TAPAS", "cid": "0x0:0x9f69...", "rating": 4.7, "reviews": 6988 }
  ],
  "rating_summary": [
    { "stars": 5, "amount": 784 },
    { "stars": 4, "amount": 199 }
  ],
  "reviews": [
    {
      "review_id": "ChZ...",
      "author_name": "A VG",
      "review_rating": 2,
      "review_text": "Overpriced for what it is.",
      "review_datetime_utc": "2025-06-29T20:58:02+00:00"
    }
  ],
  "business_description": "Pollos asados y pescado frito en casa, también para llevar.",
  "popular_dishes": [{ "name": "Medio Pollo Con Patatas", "photo": "https://lh3..." }],
  "menu": [
    {
      "section": "Pizzas y pasta",
      "items": [
        { "name": "Pizza Margarita", "description": "Base fina…", "price": "€10.50", "photo": "https://lh3..." }
      ]
    }
  ],
  "photo_categories": ["Del propietario", "Carta", "Comida y bebida", "Ambiente"],
  "posts": [
    { "text": "QUESO GORGONZOLA: origen y sabor…", "date": "Aug 4, 2026", "timestamp": 1785848535, "image": "https://lh3…", "cta_label": "Book", "cta_url": "https://…" }
  ],
  "action_links": [
    { "url": "https://www.google.com/maps/reserve/v/dine/c/…", "label": "google.com" }
  ]
}

Reviews

1 credit / 10 reviews
GET/v1/places/{place_id}/reviews
Fetch the full review set for a place, well past the handful embedded in a place lookup. Reviews are paginated for you and returned in one response, each in a stable, Outscraper-shaped schema. A place with no reviews returns an empty list (billed 1 credit).

Path parameters

FieldTypeDescription
place_idrequiredstringA CID-backed Google place_id (ChIJ…).

Query parameters

FieldTypeDescription
limitintegerMax reviews to return. Default 10, no hard cap; bounded by the place's actual review count and your credit balance.
hlstringGoogle Maps host language for the response, e.g. "es" or "pt-BR". Categories, attributes and price formatting come back in that language, and they are Google's own strings, not a translation. Defaults to English.

Request

curl "https://api.hexscraper.com/v1/places/ChIJTzciJkUxDA0RtK7jOAlZTKo/reviews?limit=50" \
  -H "Authorization: Bearer $HEXSCRAPER_API_KEY"

Response

200 OK · application/json
{
  "place_id": "ChIJTzciJkUxDA0RtK7jOAlZTKo",
  "count": 50,
  "reviews": [
    {
      "review_id": "ChdD...",
      "author_id": "1094...",
      "author_name": "Pilar Pavón",
      "author_link": "https://www.google.com/maps/contrib/1094...",
      "review_rating": 5,
      "review_text": "Absolutely phenomenal food. The garlic prawns...",
      "review_timestamp": 1751803869,
      "review_datetime_utc": "2025-07-06T12:11:09+00:00",
      "relative_date": "2 months ago"
    }
  ]
}

Visibility grid

grid_size² credits
GET/v1/visibility
Rank a business for a keyword across an N×N grid of local searches centred on it: a local-visibility report. Every cell is matched by place_id, so a same-name look-alike can never inflate or corrupt the target's rank or the competitor table.

Query parameters

FieldTypeDescription
place_idrequiredstringThe business to rank (a CID-backed ChIJ… id).
keywordrequiredstringThe search term to rank for, e.g. "tapas" (URL-encode special characters).
grid_sizeintegerOdd number 3–9. Default 5 (a 5×5 grid = 25 searches).
radius_mintegerGrid half-width in metres, 1–50000. Default 1000. The response echoes it as radius_km.
hlstringGoogle Maps host language for the response, e.g. "es" or "pt-BR". Defaults to English.

Request

curl "https://api.hexscraper.com/v1/visibility?place_id=ChIJx3-pvNszDA0R837NptBLjM4&keyword=tapas&grid_size=5&radius_m=1000" \
  -H "Authorization: Bearer $HEXSCRAPER_API_KEY"

Response

200 OK · application/json
{
  "keyword": "tapas",
  "target_place_id": "ChIJx3-pvNszDA0R837NptBLjM4",
  "target_name": "Café bar la Almadraba",
  "center_lat": 36.3707792,
  "center_lon": -6.180956,
  "grid_size": 5,
  "radius_km": 1.0,
  "total_points": 25,
  "found_in": 18,
  "average_rank": 3.4,
  "grid": [
    { "row": 0, "col": 0, "lat": 36.3752, "lon": -6.1849,
      "rank": 2, "top_result": "Café bar la Almadraba", "total_results": 20 }
  ],
  "competitors": [
    { "place_id": "0x0:0x9f69...", "name": "EL ARBOL TAPAS",
      "appearances": 22, "avg_rank": 1.8, "best_rank": 1, "top3_count": 20,
      "total_reviews": 6988, "avg_rating": 4.7, "is_target": false }
  ],
  "top_rankings": [ { "name": "Café bar la Almadraba", "count": 18 } ],
  "degraded": false
}

If the results look degraded (Google blanked review counts on a burned session), the response sets degraded: true. The data may be incomplete and is not cached.


Ready to build?

Get an API key and your first credits to start pulling Google Maps data.

Get your API key