Skip to content

Google Maps API ​

Two endpoints for local data from Google Maps. Search sends a query and an area and returns one page of places with their ids, address, rating, review count, category, phone, website, coordinates, open state, opening hours and photo. Place looks one place up by its place_id, data_id, cid or Maps URL and adds the description, the address split into parts, the Plus Code, the booking link, the photo count, the review count per star, review quotes and topics, the hours of its services, attributes, photos and the top reviews Google shows. Reviews returns the reviews of one place in the order you choose - most relevant, newest, highest or lowest rating first - optionally only those that mention a keyword, each with its text and translation, likes, photos, visit details, owner response and reviewer. Requests leave from a residential exit in the market country you pick, so names, categories and hours are localized like a local visitor sees them. No proxies, browsers, CAPTCHAs or parser maintenance on your side.

ProductTypeProduct codeWhat it does
Google Maps Search APIScraper API (synchronous)google_maps_searchOne page of twenty places for a query and area.
Google Maps Place APIScraper API (synchronous)google_maps_placeOne place with hours, attributes, photos and top reviews.
Google Maps Reviews APIScraper API (synchronous)google_maps_reviewsReviews of one place by order and keyword.

Every field is snake_case, the same convention as the Web Scraping API.

What people build with it ​

Use caseWhat you pull
Lead generationBusinesses of a category in a city, with phone, website and address.
Local SEO and rank checksWhich places Google Maps lists first for a query around a point.
Market and location researchDensity, ratings and opening hours of competitors in an area.
Reputation monitoringRating, review count and the latest top reviews of your own locations.
Directory and data enrichmentCoordinates, categories and contact details for places you already know.

Search places ​

GET https://api.scrapeit.io/api/v1/scrape/google/maps/search
x-api-key: YOUR_SCRAPEIT_API_KEY

Search parameters ​

ParameterTypeExampleDescription
qstringcoffee shopsRequired. What to search for, e.g. coffee shops, dentist, pizza (up to 2048 characters).
locationstringAustin, TXA city, region or address to search in: Austin, TX, Berlin, 10 Downing St, London. Added to the query, exactly as Google reads coffee shops Austin TX.
llstring@30.2672,-97.7431,14zMap centre and zoom as in a Google Maps URL: @lat,lng,zoomz, e.g. @40.7455,-74.0083,14z (zoom 1–21, defaults to 14). Places are ranked around it.
glstringusMarket country, two-letter ISO code (us, de, gb, fr…); Google's own uk works as gb. The request runs from an exit in this country; a country ScrapeIt has no exit in answers 422 PROXY_PROVIDER_NOT_FOUND and is not charged. Defaults to us.
hlstringenInterface language (en, de, fr, pt-BR…). Defaults to en.
pagenumber2Results page, 1–6. Google Maps serves twenty places per page and stops listing a query at about 120. Defaults to 1.

Send location, ll or both. Without either, Google picks the area itself - usually somewhere in the gl country - so results are not stable from one request to the next. An unknown parameter is rejected with VALIDATION_ERROR.

Coffee shops around downtown Austin:

bash
curl -G 'https://api.scrapeit.io/api/v1/scrape/google/maps/search' \
  -H 'x-api-key: YOUR_SCRAPEIT_API_KEY' \
  --data-urlencode 'q=coffee shops' \
  --data-urlencode 'll=@30.2672,-97.7431,14z' \
  --data-urlencode 'gl=us' \
  --data-urlencode 'hl=en'
js
const response = await fetch(
  'https://api.scrapeit.io/api/v1/scrape/google/maps/search?' +
    new URLSearchParams({ q: 'coffee shops', ll: '@30.2672,-97.7431,14z', gl: 'us', hl: 'en' }),
  { headers: { 'x-api-key': 'YOUR_SCRAPEIT_API_KEY' } },
);
const { data } = await response.json();
for (const place of data.local_results) {
  console.log(place.position, place.title, place.rating, place.phone);
}
python
import requests

response = requests.get(
    "https://api.scrapeit.io/api/v1/scrape/google/maps/search",
    headers={"x-api-key": "YOUR_SCRAPEIT_API_KEY"},
    params={"q": "coffee shops", "ll": "@30.2672,-97.7431,14z", "gl": "us", "hl": "en"},
    timeout=120,
)
data = response.json()["data"]
for place in data["local_results"]:
    print(place["position"], place["title"], place["rating"], place["phone"])

Search response ​

json
{
  "data": {
    "search_metadata": {
      "request_id": "8c1f4b2e-3d7a-4e59-9b61-2f0a7c9d1e34",
      "query": "coffee shops",
      "ll": "@30.2672,-97.7431,14z",
      "location": null,
      "country": "us",
      "language": "en",
      "page": 1,
      "proxy_tier": "residential",
      "duration_ms": 1840,
      "processed_at": "2026-10-22T15:01:10.637Z"
    },
    "local_results": [
      {
        "position": 1,
        "title": "Black Fox Coffee",
        "place_id": "ChIJKxa8FmW1RIYRnDlOJujvQjo",
        "data_id": "0x8644b56516bc162b:0x3a42efe8264e399c",
        "cid": "4198181583016835484",
        "address": "323 W 6th St, Austin, TX 78701",
        "rating": 4.6,
        "reviews_count": 82,
        "price_level": null,
        "type": "Coffee shop",
        "types": ["Coffee shop"],
        "phone": null,
        "website": "https://www.blackfoxcoffee.com/",
        "coordinates": { "latitude": 30.2686451, "longitude": -97.7460543 },
        "timezone": "America/Chicago",
        "open_state": "Open · Closes 5 PM",
        "hours": [
          { "day": "Thursday", "hours": ["7 AM–5 PM"] },
          { "day": "Friday", "hours": ["7 AM–5 PM"] }
        ],
        "thumbnail": "https://lh3.googleusercontent.com/grass-cs/AABkmLefeR2a…"
      }
    ],
    "pagination": { "current_page": 1, "next_page": 2 }
  }
}

A query Google answers with a single place (an exact name and address) returns that one place. A query with no match answers 200 with an empty local_results - Google's own "nothing found, here is what is nearby" list is not passed off as results.

Look up a place ​

GET https://api.scrapeit.io/api/v1/scrape/google/maps/place
x-api-key: YOUR_SCRAPEIT_API_KEY

Place parameters ​

Send exactly one of place_id, data_id, cid or url.

ParameterTypeExampleDescription
place_idstringChIJKxa8FmW1RIYRnDlOJujvQjoPlaces API id of a business or landmark, e.g. ChIJKxa8FmW1RIYRnDlOJujvQjo.
data_idstring0x8644b569562669d5:0x4b06cbdfc7196e9eThe data_id a search returned, e.g. 0x8644b56516bc162b:0x3a42efe8264e399c.
cidstring5406232564683337374The decimal customer id of the place - the ?cid= of a Maps link.
urlstringhttps://www.google.com/maps/place/Cipollina/@30.2805901,-97.7584946,17z/data=!3m1!4b1!4m6!3m5!1s0x8644b569562669d5:0x4b06cbdfc7196e9e!8m2!3d30.2805901!4d-97.7584946A Google Maps place URL (https://www.google.com/maps/place/…, …?cid=…, …?query_place_id=…). Only the place id is read from it; the URL itself is never fetched. Short maps.app.goo.gl links are not supported - open them once and send the long URL.
glstringusMarket country, two-letter ISO code. Defaults to us.
hlstringenLanguage of names, categories, hours and reviews. Defaults to en.

Example lookup ​

bash
curl -G 'https://api.scrapeit.io/api/v1/scrape/google/maps/place' \
  -H 'x-api-key: YOUR_SCRAPEIT_API_KEY' \
  --data-urlencode 'place_id=ChIJ1WkmVmm1RIYRnm4Zx9_LBks'
js
const response = await fetch(
  'https://api.scrapeit.io/api/v1/scrape/google/maps/place?' +
    new URLSearchParams({ place_id: 'ChIJ1WkmVmm1RIYRnm4Zx9_LBks' }),
  { headers: { 'x-api-key': 'YOUR_SCRAPEIT_API_KEY' } },
);
const { data } = await response.json();
console.log(data.place.title, data.place.rating, data.place.reviews.length);
python
import requests

response = requests.get(
    "https://api.scrapeit.io/api/v1/scrape/google/maps/place",
    headers={"x-api-key": "YOUR_SCRAPEIT_API_KEY"},
    params={"place_id": "ChIJ1WkmVmm1RIYRnm4Zx9_LBks"},
    timeout=120,
)
place = response.json()["data"]["place"]
print(place["title"], place["rating"], len(place["reviews"]))

Place response ​

json
{
  "data": {
    "search_metadata": {
      "request_id": "2b7e9c41-5a0d-4f3b-8e62-7d1c0a9f3b58",
      "data_id": "0x8644b569562669d5:0x4b06cbdfc7196e9e",
      "country": "us",
      "language": "en",
      "proxy_tier": "residential",
      "duration_ms": 1520,
      "processed_at": "2026-10-22T15:05:08.107Z"
    },
    "place": {
      "title": "Cipollina",
      "place_id": "ChIJ1WkmVmm1RIYRnm4Zx9_LBks",
      "data_id": "0x8644b569562669d5:0x4b06cbdfc7196e9e",
      "cid": "5406232564683337374",
      "address": "1213 W Lynn St, Austin, TX 78703",
      "rating": 4.4,
      "reviews_count": 641,
      "price_level": null,
      "type": "Italian restaurant",
      "types": ["Italian restaurant", "Bistro", "Takeout Restaurant", "Pizza restaurant"],
      "phone": "(512) 477-5211",
      "website": "http://www.cipollina-austin.com/",
      "coordinates": { "latitude": 30.2805901, "longitude": -97.7584946 },
      "timezone": "America/Chicago",
      "open_state": "Open · Closes 9 PM",
      "hours": [{ "day": "Thursday", "hours": ["11 AM–9 PM"] }],
      "thumbnail": "https://lh3.googleusercontent.com/grass-cs/AABkmLcs…",
      "editorial_summary": "Modern, often local & seasonal, fare, plus gourmet pizza & panini, in a spacious dining room.",
      "description": "A hidden gem in Austin since 1999. …",
      "address_components": {
        "neighborhood": "Old West Austin",
        "street": "1213 W Lynn St",
        "city": "Austin",
        "postal_code": "78703",
        "state": "Texas",
        "country_code": "US"
      },
      "plus_code": "862476JR+6J",
      "reservation_link": "https://www.opentable.com/restaurant/profile/60658?ref=1068",
      "photos_count": 303,
      "rating_distribution": [
        { "stars": 1, "count": 29 },
        { "stars": 2, "count": 13 },
        { "stars": 3, "count": 40 },
        { "stars": 4, "count": 145 },
        { "stars": 5, "count": 415 }
      ],
      "review_highlights": ["Great selection of small plates and excellent wood-fired pizza."],
      "review_topics": ["tagliatelle alfredo", "garlic knots", "wood fired pizza"],
      "secondary_hours": [
        { "type": "Happy hours", "hours": [{ "day": "Monday", "hours": ["3–6 PM"] }] }
      ],
      "attributes": [
        {
          "group": "Accessibility",
          "items": [{ "name": "Wheelchair accessible entrance", "available": true }]
        }
      ],
      "photos": ["https://lh3.googleusercontent.com/grass-cs/AABkmLeADEXf…"],
      "reviews": [
        {
          "author_name": "A. Reviewer",
          "rating": 5,
          "text": "Great pasta and friendly staff.",
          "date": "2 months ago",
          "published_at": "2026-08-03T07:14:49.078Z"
        }
      ]
    }
  }
}

Response fields ​

Every place (local_results[] and place) ​

FieldTypeDescription
positionnumberSearch only: 1-based position across pages (page 2 starts at 21).
titlestringThe place name.
place_idstring | nullPlaces API id (ChIJ…).
data_idstring | nullGoogle's feature id (0x…:0x…); send it to the place endpoint.
cidstring | nullDecimal customer id; https://maps.google.com/?cid=<cid> opens the place.
addressstring | nullThe address as Google prints it.
ratingnumber | nullAverage star rating, 1–5.
reviews_countnumber | nullNumber of reviews.
price_levelstring | nullThe price band (e.g. $$) when Google publishes one for the place; null for most places.
typestring | nullPrimary category, e.g. Coffee shop.
typesstring[]Every category Google lists, primary first.
phonestring | nullPhone number in the local format.
websitestring | nullThe website the place links.
coordinatesobject | nulllatitude and longitude.
timezonestring | nullIANA time zone of the place, e.g. America/Chicago - the zone hours and open_state are in.
open_statestring | nullThe status line as Google shows it at request time: Open · Closes 5 PM, Closed · Opens 7 AM.
hours[]object[]The week from today on: day and the hours ranges as printed (7 AM–5 PM, Closed, Open 24 hours).
thumbnailstring | nullThe main photo.

Place only ​

FieldTypeDescription
editorial_summarystring | nullGoogle's own short description of the place.
descriptionstring | nullThe description the business wrote ("From the business").
address_componentsobject | nullThe address in parts: neighborhood, street, city, postal_code, state and country_code (ISO 3166-1 alpha-2), each null when Google has none.
plus_codestring | nullGlobal Plus Code of the location, e.g. 862476JR+6J.
reservation_linkstring | nullThe table-booking page the place links (OpenTable, Resy…).
photos_countnumber | nullHow many photos the place has on Google Maps.
rating_distribution[]object[]Review counts per star, one to five: stars and count. Empty when Google publishes none.
review_highlights[]string[]Short quotes Google lifts from reviews for the place summary.
review_topics[]string[]The topics Google offers to filter the reviews by, e.g. garlic knots.
secondary_hours[]object[]Hours of the place's services that differ from the main hours: type (Happy hours, Kitchen, Delivery…) and hours[] like hours[] above.
attributes[]object[]The "About" groups: group (e.g. Accessibility) and items[] with name and available (false for "No …").
photos[]string[]Photo URLs of the place panel.
reviews[]object[]The top reviews Google shows on the panel (up to five): author_name, rating, text, date (as shown) and published_at (ISO 8601). Only the author's public display name is returned - no profile link or photo.

search_metadata reports what was asked and how it ran; proxy_tier is the tier of the exit that served the request (datacenter or residential). pagination.next_page is the next page to ask for, or null when the list has ended.

Reviews of a place ​

GET https://api.scrapeit.io/api/v1/scrape/google/maps/reviews
x-api-key: YOUR_SCRAPEIT_API_KEY

Google Maps shows a visitor who is not signed in up to five reviews per order and keyword, with no "more" page: the full list needs a Google sign-in. Each request returns that set for the order and keyword you choose; another sort or query returns another set, so combining them collects more reviews of the same place.

Reviews parameters ​

Send exactly one of place_id, data_id, cid or url, as in the place lookup.

ParameterTypeExampleDescription
place_idstringChIJCar0f49ZwokR6ozLV-dHNTEPlaces API id of the place.
data_idstring0x89c2598f7ff4aa09:0x313547e757cb8ceaThe data_id a search returned.
cidstring3545819340560108778The decimal customer id of the place - the ?cid= of a Maps link.
urlstringhttps://www.google.com/maps/place/Katz%27s+Delicatessen/data=!4m2!3m1!1s0x89c2598f7ff4aa09:0x313547e757cb8ceaA Google Maps place URL; only the place id is read from it.
sortstringnewestrelevant (default), newest, highest or lowest rating first. newest orders by the last edit of a review.
querystringpastramiOnly reviews that mention this keyword (up to 100 characters). No match returns an empty reviews list.
glstringusMarket country, two-letter ISO code. Defaults to us.
hlstringdeLanguage of dates and visit details, and of the translation of reviews written in another language. Defaults to en.

Example reviews request ​

bash
curl -G 'https://api.scrapeit.io/api/v1/scrape/google/maps/reviews' \
  -H 'x-api-key: YOUR_SCRAPEIT_API_KEY' \
  --data-urlencode 'place_id=ChIJCar0f49ZwokR6ozLV-dHNTE' \
  --data-urlencode 'sort=newest'
js
const response = await fetch(
  'https://api.scrapeit.io/api/v1/scrape/google/maps/reviews?' +
    new URLSearchParams({ place_id: 'ChIJCar0f49ZwokR6ozLV-dHNTE', sort: 'newest' }),
  { headers: { 'x-api-key': 'YOUR_SCRAPEIT_API_KEY' } },
);
const { data } = await response.json();
for (const review of data.reviews) console.log(review.rating, review.date, review.text);
python
import requests

response = requests.get(
    "https://api.scrapeit.io/api/v1/scrape/google/maps/reviews",
    headers={"x-api-key": "YOUR_SCRAPEIT_API_KEY"},
    params={"place_id": "ChIJCar0f49ZwokR6ozLV-dHNTE", "sort": "newest"},
    timeout=120,
)
for review in response.json()["data"]["reviews"]:
    print(review["rating"], review["date"], review["text"])

Reviews response ​

json
{
  "data": {
    "search_metadata": {
      "request_id": "8d0c6e2a-41f7-4b9e-9a55-1f3e0c7b2d64",
      "data_id": "0x89c2598f7ff4aa09:0x313547e757cb8cea",
      "sort": "newest",
      "query": null,
      "country": "us",
      "language": "en",
      "proxy_tier": "residential",
      "duration_ms": 1240,
      "processed_at": "2026-10-30T18:02:11.512Z"
    },
    "reviews": [
      {
        "review_id": "Ci9DQUlRQUNvZENodHljRjlvT2xVeE9WOVBSMmREWTBocFNqRmZWRzFqWldseVgyYxAB",
        "rating": 5,
        "text": "The pastrami is as good as everyone says. Worth the wait.",
        "original_language": "en",
        "translated_text": null,
        "date": "3 weeks ago",
        "published_at": "2026-10-09T14:21:52.626Z",
        "updated_at": "2026-10-09T14:21:52.626Z",
        "likes": 1,
        "photos": ["https://lh3.googleusercontent.com/geougc-cs/AB3k…=w1200-h900"],
        "attributes": [
          {
            "key": "GUIDED_DINING_MODE",
            "label": "Order type",
            "values": ["Dine in"],
            "rating": null
          },
          {
            "key": "GUIDED_DINING_PRICE_RANGE",
            "label": "Price per person",
            "values": ["$30–40"],
            "rating": null
          },
          { "key": "GUIDED_DINING_FOOD_ASPECT", "label": "Food", "values": [], "rating": 5 }
        ],
        "owner_response": null,
        "author": {
          "name": "Alex R.",
          "profile_url": "https://www.google.com/maps/contrib/100000000000000000001/reviews",
          "photo_url": "https://lh3.googleusercontent.com/a/reviewer=s120-c",
          "reviews_count": 101,
          "photos_count": 312,
          "is_local_guide": true
        },
        "link": "https://www.google.com/maps/reviews/data=!4m8!14m7!1m6!2m5!1sCi9DQUlRQUNv…"
      }
    ]
  }
}
FieldDescription
textThe review in the language it was written in.
original_languageLanguage of text, e.g. hu.
translated_textGoogle's translation into hl when the review was written in another language, otherwise null.
dateThe relative date Google prints, e.g. 3 weeks ago or Edited 3 hours ago.
published_atWhen the review was posted, ISO 8601; updated_at is its last edit.
likesHow many people marked the review helpful.
photosPhotos attached to the review.
attributesDetails of the visit the reviewer filled in (order type, meal, price per person, wait, parking…) and the aspects they rated 1-5 (food, service, atmosphere), in hl.
owner_responseThe business owner's reply with its text and date, or null.
authorThe reviewer's public profile: name, profile link, photo, reviews and photos count, Local Guide flag.

No-code Google Maps scrapers ​

Prefer a dashboard run and a file? Scrapers without code has two Google Maps scrapers. Each produces JSON, CSV and XML files and is also available over HTTP with an API key (x-api-key; scope scrapers:run to start, scrapers:read to poll):

POST https://api.scrapeit.io/api/v1/scrapers/{scraper}/jobs
GET  https://api.scrapeit.io/api/v1/scrapers/{scraper}/jobs/{jobId}
Scraper{scraper}ParametersOne record per
Google Maps Scrapergoogle-mapsq (required), location, ll, gl, hl, max_pages (1–20, default 5), include_detail, output_formatplace
Google Maps Reviews Scrapergoogle-maps-reviewsplaces (required: up to 20 place ids, data ids, cids or place URLs), gl, hl, output_formatreview, with its place
ParameterTypeExampleDescription
qstringcoffee shopsMaps Scraper: required, what to search for.
locationstringAustin, TXMaps Scraper: a city, region or address to search in.
llstring@30.2672,-97.7431,14zMaps Scraper: map centre and zoom, as in the Search API.
placesarray["ChIJKxa8FmW1RIYRnDlOJujvQjo"]Reviews Scraper: required, up to 20 place ids (ChIJ…), data ids (0x…:0x…), cids or Google Maps place URLs.
glstringusMarket country, two-letter ISO code; the proxy exit country. Defaults to us.
hlstringenInterface language (en, de, pt-BR…). Defaults to en.
max_pagesnumber10Maps Scraper: search pages to sweep, 1–20. Defaults to 5; Google Maps stops at about six.
include_detailbooleantrueMaps Scraper: also look each place up and nest it under detail (the place fields, with attributes, photos and top reviews), billed per place like the Place API. Defaults to false.
output_formatarray["json", "csv"]One or more of json, csv, xml. Defaults to ["json"]; an empty list is rejected.

The reviews scraper collects what Google Maps shows a signed-out visitor: up to five most relevant reviews per place, with the author's public name, rating, text and date - the full review list, sorting and review search need a Google sign-in. A place without reviews still gets one row with its place fields.

A run of five pages or places or fewer without include_detail finishes inline and the POST already answers with the result-file ids; a larger one, or any run with include_detail, answers queued, so poll the GET endpoint until status is finished (or failed). Each search page is billed like one Search API request and each place like one Place API request - the places of include_detail too; a place whose lookup fails keeps its search fields with detail: null and a detail_error code, and that lookup costs nothing. A listed place Google does not know, or blocks on every attempt, becomes a row with its place and an error code and costs nothing; the other places still run.

Errors ​

HTTPCodeWhen
400VALIDATION_ERRORA missing q; an ll in the wrong shape or off the globe; a page outside 1–6; no place id or more than one; an id in the wrong shape; a url that is not a Google Maps place URL with an id. Reviews: a place id Google itself rejects (the request reached Google and is charged).
404NOT_FOUNDPlace only (reviews of an unknown place come back as an empty list): Google answered with its own "no place under this id" response.
502TARGET_BLOCKEDEvery attempt was answered with Google's CAPTCHA, consent wall or another response that is not Maps data. error.details.block_reason says which: captcha, consent, unrecognized_response or no_response. Retry later.

A place response ScrapeIt cannot read - Maps data in a format it does not know, an error frame - is 502 TARGET_BLOCKED with block_reason: unrecognized_response, not 404: it says nothing about whether the place exists. The same goes for a first search page that carries neither places nor Google's "no match" answer: it is not passed off as an empty, charged result.

All other errors follow the platform's error codes.

Credits and billing ​

Each endpoint bills per request under its own product code (google_maps_search, google_maps_place, google_maps_reviews) - see billing & credits.

Price per request: 30 credits for search and place, 15 for reviews, flat. The proxy is included: a request costs the same whichever exit served it. This is an introductory price for a new product and may change; the dashboard Pricing page always shows the current one.

Limits and behavior ​

  • Every request is fetched live - never served from the shared cache - so hours, ratings and reviews are current.
  • One search request returns one page of up to twenty places; use page to walk further, up to page 6.
  • The place endpoint returns the reviews Google embeds in the place panel (the top few). The reviews endpoint chooses the order and a keyword, but Google shows a signed-out visitor at most five reviews per order and keyword and no next page. Popular times are not included: the place panel Google serves does not carry them.
  • Each request is a fresh session; nothing from one request (cookies, consent, location) carries into the next.
  • The consent dialog shown to visitors in the EU is accepted automatically, so gl values in the EU return data, not the consent page.
  • Places, names and categories are localized by the exit's country (gl) and the language (hl).
  • Google changes its data format from time to time; fields it stops sending come back null or empty rather than failing the request.

ScrapeIt Web Scraping API documentation. Managed web scraping services: www.scrapeit.io.