DEV Community

Cover image for Google Local AI: Get Local Pack Data as JSON for Agents, Lead Gen, and Rank Tracking
Truffle Pig Data
Truffle Pig Data

Posted on

Google Local AI: Get Local Pack Data as JSON for Agents, Lead Gen, and Rank Tracking

The local pack, that map-plus-three-businesses block at the top of Google Search, decides who gets the phone call for "plumber near me" in every city on earth. For local SEO work and lead generation you need that block as data, and Google doesn't hand it over. The Google Local API on Apify fixes that: send a query and a city, get back the local results as JSON with ratings, phones, hours, and coordinates.

Disclosure: the Apify links in this post are affiliate links. If you run the Actor, I may earn a referral commission at no extra cost to you.

Does Google have a local pack API?

Google has the official Places API, and it's genuinely good at what it does: look up businesses, get details, autocomplete addresses. What it will not tell you is what the local pack actually shows for a search in a specific city, in what order, on which device. Pack composition and ranking are SERP features, not Places data, and there's no official endpoint for them. Rank trackers and lead-gen tools need the page as served, which is why a scraper you call like an API fills the gap: it queries Google Local the way a user in that location would and returns the businesses it saw.

What the Google Local API returns

The Google Local API returns each local result as structured JSON: business name, rating, review count, address, phone, hours, GPS coordinates, place_id, and links.

Field Example Notes
Business name Smith & Sons Plumbing As shown in the pack
rating 4.8 Star rating
Reviews 312 Review count behind the rating
phone (813) 555-0182 The lead-gen field
Hours Open until 6 PM Current status as rendered
place_id ChIJd8BlQ2Bx... Stable ID for joins with other Google data

GPS coordinates ride along for mapping, and you can target by google_domain, country (gl), language (hl), and device. Desktop pages carry about 20 businesses, mobile about 10, which matters because billing is per page.

Who this is for

Local SEO agencies tracking pack positions for clients. Lead-gen operators building contact lists of roofers, med spas, or HVAC contractors city by city. And builders wiring local business lookup into AI agents, where "find me the top-rated dentists in Chicago" should return data, not vibes.

The manual way, and where it breaks

Scraping the local pack yourself means faking a location. Google decides what you see from where it thinks you are, so you're forging uule strings, juggling consent pages, and rendering JavaScript before you parse a single card. Then the anti-bot layer notices your datacenter IP. Then the markup changes. I keep a mental list of scrapers I've written twice, and Google SERP parsers sit at the top of it. The location spoofing alone is why I'd rather call something hosted.

The faster way: run the Google Local API

Apify Console

  1. Open the Google Local API and click Try for free.
  2. Set q to a search like "plumbers" and location to a city.
  3. Run it and export JSON or CSV.

REST

curl -X POST "https://api.apify.com/v2/acts/johnvc~google-local-api/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "q": "plumbers", "location": "Tampa, Florida, United States", "max_pages": 1 }'
Enter fullscreen mode Exit fullscreen mode

The run lifecycle is standard Apify; details in the Apify API docs.

Pull local businesses in Python

from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor("johnvc/google-local-api").call(
    run_input={
        "q": "dentists",
        "location": "Chicago, Illinois, United States",
        "device": "desktop",
        "max_pages": 1,
    }
)

for biz in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(biz.get("rating"), biz.get("phone"), biz.get("place_id"))
Enter fullscreen mode Exit fullscreen mode

Loop the same call over a city list and you've got a scraper-backed prospecting pipeline in thirty lines.

Build lead lists for home services

The biggest family of published tasks does exactly this, one trade per task: roofer contacts in Dallas, HVAC contractors in Phoenix, and plumbers in Tampa. Each is a preconfigured run you can clone for your own metro.

Cover professional and medical niches

The same pattern extends to higher-ticket verticals: med spas in Scottsdale with ratings, dental implant leads in Phoenix, and immigration lawyers in New York.

Track local pack rankings for SEO

Rank tracking is the other half of the story. Google local pack rank tracker for SEO agencies is the agency template, track "plumber near me" local pack rankings covers the near-me query class, and monitor local SERP visibility for dentist SEO shows ongoing monitoring for one niche.

No code, just a spreadsheet

Export Google Local results to CSV is the Console-only path from search to sheet.

Google Local AI: give your agent the pack

Where this gets interesting in 2026 is agents. Over the Model Context Protocol, the Actor becomes a tool Claude, Claude Code, or Cursor can call, so a prompt like "who ranks in the local pack for roofers in Denver, and what are their ratings?" triggers a live run and comes back grounded in the actual SERP. Wire it up through Apify's MCP server, and read more about Claude at claude.ai.

FAQ about the Google Local scraper

What does the local pack scraper cost per run?

Two cents per page of results, plus a small setup fee per run. A desktop page holds around 20 businesses, so a city-level lead pull works out to about a tenth of a cent per business. max_pages caps spend, and new Apify accounts include free credit.

Can this scraper power a local rank tracker on a schedule?

Yes, that's the core SEO use. Save one task per query-city pair, attach an Apify schedule, and diff positions run over run. Start from the Google Local API and the agency rank-tracker task above.

Does the scraper support "near me" and precise locations?

It does. Use location for city-level targeting or a uule string for finer control, plus gl, hl, and google_domain for country and language. The device setting switches between desktop and mobile results, which often differ.

Can Claude call this scraper as an MCP tool?

Yes. Registered through Apify's MCP server, it shows up as a callable tool in Claude, Claude Code, and Cursor, and returns the same structured rows an API call would.

What won't a local pack scraper give you?

Email addresses, for one: Google Local shows phone, hours, and links, so email prospecting needs an enrichment step. And the pack is inherently local and personalized, so your run reflects the location and device you requested, not the exact page every user sees. Treat positions as a consistent measurement, not a universal truth.

More from Truffle Pig Data

Adjacent Actors for local data work: the Google Maps Places API for place detail lookups, the Google Local Services API for the sponsored pros block, and the Google Maps Directions API for travel times between the businesses you find.

Wrapping up

The local pack is where local revenue starts, and now it's queryable. Point the Google Local API at your niche and city, and you'll have the block as JSON before your coffee cools.

Top comments (0)