Skip to content
ScrapeField

Google Maps scraper API

Search for places, then read their details, reviews, photos and the owner’s own updates — with the field names Google’s own Places API uses. Blocks handled; nothing for you to unblock.

Endpoints
5
From
3 credits a call
Returns
place, review, photo, post
google.com/maps/place/

Blue Door Coffee

4.4(1,921)
Bakery · $$
DirectionsSaveNearbyShare
  • 124 Franklin St, Brooklyn, NY 11249, United States
  • Open · Closes 7 PM
  • bluedoorcoffee.example
  • (718) 555-0120

Extracted data

  1. 1name "Blue Door Coffee"
  2. 2rating 4.4user_ratings_total 1921
  3. 3category "Bakery"price_level 2
  4. 4formatted_address "124 Franklin St, Brooklyn, NY 11249, United…
  5. 5opening_hours.weekday_text[0] "Monday: 7:00 AM – 7:00 PM"
  6. 6website "https://bluedoorcoffee.example"
  7. 7formatted_phone_number "(718) 555-0120"
  8. place_id "ChIJN1t_tDeuEmsRUsoyG83frY4"
  9. business_status "OPERATIONAL"
  10. claimed false

Try it now

Every Google Maps endpoint, as an MCP tool, as a REST call, or as a question in plain English. Each one runs against the live API in demo mode — no key, no account. For an agent: the Google Maps MCP server.

POSThttps://scrapefield.com/mcp
5 tools
Transport
HTTP, JSON-RPC 2.0
Methods
initialize · tools/list · tools/call
Auth
Bearer key (or none for demo mode)
claude mcp add --transport http scrapefield https://scrapefield.com/mcp

What people build with it

Three worked examples, each with the calls it makes and what a run costs — multiplied out from the published price of every call.

01

Build a lead list for a city

Search a category neighbourhood by neighbourhood and every result already carries its phone, website, rating and opening hours — no second call per business. Duplicates across neighbourhoods collapse on the place_id.

The calls, and what each costs
GET google-maps/places× 515 cr
per run, up to 100 businesses15 cr

≈ $0.009 at the 250k pack

const API = 'https://api.scrapefield.com/v1';
const sf = (path, q) =>
  fetch(API + '/' + path + '?' + new URLSearchParams(q), {
    headers: { Authorization: 'Bearer ' + process.env.SCRAPEFIELD_KEY },
  }).then((r) => r.json());

const areas = ['Alfama', 'Baixa', 'Chiado', 'Estrela', 'Belém'];
const leads = new Map();

for (const area of areas) {
  const query = 'coffee shops in ' + area + ', Lisbon';
  const { data } = await sf('google-maps/places', { query, limit: 20 });
  for (const p of data) {
    leads.set(p.place_id, {
      name: p.name,
      phone: p.international_phone_number,
      website: p.website,
      rating: p.rating,
      reviews: p.user_ratings_total,
    });
  }
}

console.table([...leads.values()]);
02

Hear about a bad review the day it lands

Check the newest reviews at each of your locations once a day and raise anything at two stars or below — with whether the owner has already replied, so nobody answers twice.

The calls, and what each costs
GET google-maps/reviews× 1,5009,000 cr
a month, 50 locations checked daily9,000 cr

≈ $5.36 at the 250k pack

const API = 'https://api.scrapefield.com/v1';
const sf = (path, q) =>
  fetch(API + '/' + path + '?' + new URLSearchParams(q), {
    headers: { Authorization: 'Bearer ' + process.env.SCRAPEFIELD_KEY },
  }).then((r) => r.json());

const since = Date.now() - 24 * 3600 * 1000;

for (const place_id of myLocations) {
  const q = { place_id, sort: 'newest', limit: 20 };
  const { data } = await sf('google-maps/reviews', q);
  const bad = data.filter(
    (r) => r.publish_time !== null && Date.parse(r.publish_time) > since && r.rating !== null && r.rating <= 2,
  );

  for (const r of bad) {
    const replied = r.owner_response ? 'already answered' : 'no reply yet';
    notify(place_id, r.rating, r.text, replied);
  }
}
03

Map a market before you enter it

Lay a grid over a city and search around each point, so no part of it is missed by a 20-result ceiling. Group what comes back by category and you have ratings, review counts and price levels, street by street.

The calls, and what each costs
GET google-maps/places× 2575 cr
one city centre, a 5 × 5 grid75 cr

≈ $0.045 at the 250k pack

const API = 'https://api.scrapefield.com/v1';
const sf = (path, q) =>
  fetch(API + '/' + path + '?' + new URLSearchParams(q), {
    headers: { Authorization: 'Bearer ' + process.env.SCRAPEFIELD_KEY },
  }).then((r) => r.json());

const seen = new Map();

for (let i = 0; i < 5; i++) {
  for (let j = 0; j < 5; j++) {
    const lat = 38.70 + i * 0.009;
    const lng = -9.17 + j * 0.0115;
    const q = { query: 'restaurant', lat, lng, radius_m: 700 };
    const { data } = await sf('google-maps/places', q);
    for (const p of data) seen.set(p.place_id, p);
  }
}

const places = [...seen.values()];
const byCategory = Object.groupBy(places, (p) => p.category);

Everything that comes back

The complete response behind the Google Maps view at the top of this page, from GET /v1/google-maps/place — every field, including the ones that are null. Fields are named after Google's Places API, so if you have read those docs you already know them. Every field of google_maps_place, google_maps_review, google_maps_photo and google_maps_post is documented.

{
  "data": {
    "place_id": "ChIJN1t_tDeuEmsRUsoyG83frY4",
    "name": "Blue Door Coffee",
    "category": "Bakery",
    "categories": [
      "Bakery",
      "Bicycle shop"
    ],
    "formatted_address": "124 Franklin St, Brooklyn, NY 11249, United States",
    "address": {
      "street": "124 Franklin St",
      "city": "Brooklyn",
      "region": "New York",
      "postal_code": "11249",
      "country_code": "US"
    },
    "location": {
      "lat": 40.66704,
      "lng": -73.927703
    },
    "plus_code": "TNNG+EP",
    "rating": 4.4,
    "user_ratings_total": 1921,
    "rating_distribution": {
      "1": 56,
      "2": 75,
      "3": 157,
      "4": 458,
      "5": 1175
    },
    "price_level": 2,
    "formatted_phone_number": "(718) 555-0120",
    "international_phone_number": "+1 718-555-0120",
    "website": "https://bluedoorcoffee.example",
    "url": "https://www.google.com/maps/place/?q=place_id:ChIJN1t_tDeuEmsRUsoyG83frY4",
    "business_status": "OPERATIONAL",
    "opening_hours": {
      "weekday_text": [
        "Monday: 7:00 AM – 7:00 PM",
        "Tuesday: 7:00 AM – 7:00 PM",
        "Wednesday: 7:00 AM – 7:00 PM",
        "Thursday: 7:00 AM – 7:00 PM",
        "Friday: 7:00 AM – 7:00 PM",
        "Saturday: 9:00 AM – 7:00 PM",
        "Sunday: 9:00 AM – 7:00 PM"
      ],
      "periods": [
        {
          "open": {
            "day": 0,
            "time": "0900"
          },
          "close": {
            "day": 0,
            "time": "1900"
          }
        },
        {
          "open": {
            "day": 1,
            "time": "0700"
          },
          "close": {
            "day": 1,
            "time": "1900"
          }
        },
        {
          "open": {
            "day": 2,
            "time": "0700"
          },
          "close": {
            "day": 2,
            "time": "1900"
          }
        },
        {
          "open": {
            "day": 3,
            "time": "0700"
          },
          "close": {
            "day": 3,
            "time": "1900"
          }
        },
        {
          "open": {
            "day": 4,
            "time": "0700"
          },
          "close": {
            "day": 4,
            "time": "1900"
          }
        },
        {
          "open": {
            "day": 5,
            "time": "0700"
          },
          "close": {
            "day": 5,
            "time": "1900"
          }
        },
        {
          "open": {
            "day": 6,
            "time": "0900"
          },
          "close": {
            "day": 6,
            "time": "1900"
          }
        }
      ]
    },
    "popular_times": [
      {
        "day": 0,
        "busyness": [
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          23,
          55,
          94,
          100,
          90,
          83,
          75,
          62,
          33,
          13,
          7,
          1,
          0,
          0,
          0,
          0,
          0
        ]
      },
      {
        "day": 1,
        "busyness": [
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          18,
          45,
          71,
          83,
          72,
          66,
          61,
          46,
          29,
          14,
          4,
          3,
          0,
          0,
          0,
          0,
          0
        ]
      },
      {
        "day": 2,
        "busyness": [
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          17,
          47,
          74,
          78,
          71,
          63,
          65,
          52,
          28,
          11,
          8,
          3,
          0,
          0,
          0,
          0,
          0
        ]
      },
      {
        "day": 3,
        "busyness": [
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          21,
          42,
          74,
          84,
          73,
          65,
          63,
          52,
          26,
          14,
          10,
          2,
          0,
          0,
          0,
          0,
          0
        ]
      },
      {
        "day": 4,
        "busyness": [
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          18,
          48,
          75,
          84,
          74,
          63,
          66,
          47,
          26,
          13,
          4,
          3,
          0,
          0,
          0,
          0,
          0
        ]
      },
      {
        "day": 5,
        "busyness": [
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          23,
          56,
          94,
          100,
          86,
          83,
          77,
          64,
          37,
          17,
          5,
          3,
          0,
          0,
          0,
          0,
          0
        ]
      },
      {
        "day": 6,
        "busyness": [
          0,
          0,
          0,
          0,
          0,
          0,
          0,
          23,
          55,
          90,
          100,
          84,
          78,
          77,
          63,
          32,
          18,
          6,
          1,
          0,
          0,
          0,
          0,
          0
        ]
      }
    ],
    "about": {
      "service_options": [
        "Dine-in",
        "Takeout"
      ],
      "accessibility": [
        "Wheelchair accessible entrance"
      ],
      "payments": [
        "Credit cards",
        "Debit cards",
        "NFC mobile payments",
        "Cash"
      ]
    },
    "claimed": false,
    "photo": {
      "url": "https://cdn.example/maps/KccUhk3IwEeL5pn7.jpg",
      "width": 4032,
      "height": 3024,
      "author_name": null,
      "author_url": null
    }
  },
  "meta": {
    "request_id": "req_7f3ac1e94b2d40f8a1c6e5d2",
    "credits_charged": 3,
    "credits_remaining": 74218,
    "cached": false,
    "fetched_at": "2026-09-20T09:12:03Z",
    "next_cursor": null
  }
}

Endpoints and prices

One published credit cost per endpoint, charged per call and refunded automatically when a call fails. See what a credit costs.

Coming from Apify’s Google Maps Scraper

Google Maps Scraper costs $4.00 per 1,000 places on Apify’s free plan, $1.50 on its $999-a-month Business plan. Here, about 20 places come back a call, so 1,000 cost about $0.12 on our smallest pack and $0.07 on our largest, with no run to start or poll. Its fields, and ours. Apify’s price was read on 9 October 2026; the full comparison has where Apify wins.

Google Maps Scraper and ScrapeField, field by field
Google Maps ScraperScrapeField
titlename
categoryNamecategory
addressformatted_address
locationlocation
totalScorerating
reviewsCountuser_ratings_total
reviewsDistributionrating_distribution
placeIdplace_id
phoneformatted_phone_number
websitewebsite
openingHoursopening_hours
permanentlyClosed, temporarilyClosedbusiness_status

Google Maps, specifically

The questions people ask about this platform before they call it. And how this compares with the platform’s own API: ScrapeField vs Google Maps Platform.

How is this different from the Google Places API?
The Places API is Google’s own, official product, and the right choice inside a user-facing app where its licence matters. We return the full listing — including what the Places API leaves out, like the rating breakdown — under the field names the Places API uses, at one published credit cost per call.
How many results does a search return?
Up to 20 per call, and the next page is one call away with meta.next_cursor. To cover a whole city, search around points with lat, lng and radius_m (100 m to 50 km) — the market recipe above does exactly that.
Can I get every review of a place?
The first page has up to 8 reviews and each page after it up to 20, ordered by relevance, newest, highest or lowest, and you page through them with meta.next_cursor. Each has the rating, the text, the author, the date, any photos, and the owner’s reply where there is one.
Do you store the photos?
No. google-maps/photos returns the image URLs on the platform’s own CDN. We do not rehost images.
How fresh is the data?
Places are cached for 24 hours and reviews for 6. Pass fresh=true to fetch now instead; it is charged the same, and needs credits you have bought rather than the free ones. A failed call is refunded automatically.

The same key, four more platforms

One key, one balance and one invoice across all five — and each platform’s data in its own shape, because they are five different systems.

Your first Google Maps call, in a minute

Get a key