AnswerLine Start free

Google Search

Google Search local pack

Map-pack results with names, ratings and positions for local queries.

`localResults` returns the map-pack businesses in order, with name, rating, review count, category and address: the unit of local rank tracking.

Returned in result

Field
localResults

Request

curl -X POST "https://api.answerline.dev/v1/monitor/google" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query":"project management software","country":"US","include":{"aioverview":{"markdown":true}}}'

What the local pack is

The local pack is the map-backed block of businesses Google shows for queries with local intent, such as “plumber near me” or “best pizza in new york city”. It lists a few places with name, rating, review count, category, address and, for service businesses, buttons for the website and directions.

result.localResults returns the places in that pack, in order. It is the unit of local rank tracking: pack position across a grid of cities or neighborhoods, the share of keyword and location combinations where a business appears at all, the ratings and review counts of the businesses that outrank you, and the same keywords reported for every branch of a multi-location business.

Field reference

result.localResults[]

Field Type Meaning
position number, required 1-indexed position within the pack.
title string, required Business name as displayed.
placeId string Google entity ID for the place.
rating number Average star rating, 0 to 5.
reviews string Review count as displayed, such as 26K. Not normalized.
price string Price band as displayed, such as $10–20, in the locale’s currency.
type string Business category, such as Pizza or Plumber.
yearsInBusiness string Years-in-business badge, when shown; typical on service packs.
address string Street address or locality as displayed.
phone string Phone number, when shown, locale-formatted.
hours string Opening-hours text, such as Open · Closes 11 PM.
description string Trailing snippet: a review quote or service-options line.
links object Action links, usually on service-style packs; each key only when Google showed the button.
links.website string The business’s own website.
links.directions string Absolute Google Maps directions URL.
links.redirectLink string Google’s /goto redirect, present only when Google served a link as a redirect.
Field Type Meaning
localResultsMoreLink string Absolute URL of the pack’s “More places” or “More businesses” control, Google’s expanded Local Finder. Returned only alongside localResults when the control is shown.

Both fields are omitted when no local pack appears. The pack comes from the first results page of a desktop request.

Annotated excerpt

Values are illustrative; names and types follow the POST /v1/monitor/google result schema. The request used query: "plumber austin".

{
  "result": {
    // Omitted entirely when the page has no local pack.
    "localResults": [
      {
        "position": 1,
        "title": "Example Plumbing Co.",
        "placeId": "ChIJexample123",
        "rating": 4.8,
        "reviews": "1.2K",                    // display string, not a number
        "type": "Plumber",
        "yearsInBusiness": "10+ years in business",
        "address": "Austin, TX",
        "phone": "(512) 555-0142",
        "hours": "Open 24 hours",
        "description": "\"Arrived within the hour and fixed the leak\"",
        "links": {                              // service-style packs only
          "website": "https://www.exampleplumbing.example/",
          "directions": "https://www.google.com/maps/dir//..."
        }
      }
    ],
    "localResultsMoreLink": "https://www.google.com/search?..."
  }
}

Cost and targeting

No include flag is needed. The local pack comes with every Google Search request at the base price: $0.00103 for one page. Keep pages at 1; the pack comes from the first page.

Set country (or gl) for the result geography, and put the city in the query or send location (e.g. Austin,Texas,United States) or uule to search from that city.

A grid of 5 keywords across 20 cities is 100 tasks, $0.103 per run.

Example: presence rate and average position across a city grid

import os
import re
import time
from collections import defaultdict
from datetime import date

import requests

API = "https://api.answerline.dev"
HEADERS = {"Authorization": f"Bearer {os.environ['API_KEY']}"}
BUSINESS = "example plumbing"          # match on a normalized name fragment
KEYWORDS = ["plumber", "emergency plumber", "water heater repair"]
CITIES = ["austin", "round rock", "cedar park"]
DAY = date.today().isoformat()


def run_tasks(tasks):
    resp = requests.post(f"{API}/v1/async/task/batch", headers=HEADERS, json=tasks, timeout=60)
    resp.raise_for_status()
    pending = {item["task"]["id"]: tasks[item["index"]] for item in resp.json()["results"] if item["success"]}
    done = []
    while pending:
        time.sleep(10)
        for task_id in list(pending):
            body = requests.get(f"{API}/v1/async/task/{task_id}", headers=HEADERS, timeout=30).json()
            if body["task"]["status"] in ("COMPLETED", "FAILED"):
                task = pending.pop(task_id)
                if body["task"]["status"] == "COMPLETED":
                    done.append((task["payload"], body["response"]["result"]))
    return done


def review_count(text):
    match = re.search(r"([\d.,]+)\s*([KkMm]?)", text or "")
    if not match:
        return None
    value = float(match.group(1).replace(",", ""))
    return int(value * {"k": 1_000, "m": 1_000_000}.get(match.group(2).lower(), 1))


tasks = [
    {
        "taskType": "GOOGLE",
        "payload": {"query": f"{kw} {city}", "country": "US"},
        "idempotencyKey": f"lp-{k}-{c}-{DAY}",
    }
    for k, kw in enumerate(KEYWORDS)
    for c, city in enumerate(CITIES)
]

by_city = defaultdict(lambda: {"checks": 0, "packs": 0, "positions": []})
leaders = defaultdict(int)
for payload, result in run_tasks(tasks):
    stats = by_city[next(c for c in CITIES if payload["query"].endswith(c))]
    stats["checks"] += 1
    pack = result.get("localResults", [])
    stats["packs"] += bool(pack)
    for place in pack:
        if BUSINESS in place["title"].lower():
            stats["positions"].append(place["position"])
        if place["position"] == 1:
            leaders[(place["title"], place.get("rating"), review_count(place.get("reviews")))] += 1

for city, s in by_city.items():
    found = len(s["positions"])
    avg = sum(s["positions"]) / found if found else None
    avg_text = f"{avg:.1f}" if avg else "-"
    print(f"{city:34} pack shown {s['packs']}/{s['checks']}  present {found}/{s['checks']}  avg position {avg_text}")
print("Most frequent #1 places (title, rating, reviews):")
for key, count in sorted(leaders.items(), key=lambda kv: -kv[1])[:5]:
    print("  ", count, key)

Presence is counted against all checks, not only checks that showed a pack, so a keyword with no pack in a city counts as “not present”. Report both numbers: a low pack rate points to keyword intent, a low presence rate with packs shown points to the business.

Pitfalls

localResults comes from desktop requests, so it shows the desktop pack.

localResults and localResultsMoreLink are omitted when there is no pack. Record the absence per keyword and location instead of skipping the row.

Names in title can include suffixes or location labels. Match on placeId once you know it, and fall back to a normalized name fragment.

reviews such as 1.2K must be converted before comparing; keep the raw text too.

A city name in the query approximates searchers spread across the city, and “near me” results can differ within it. Keep the city list fixed across runs.

links, yearsInBusiness and phone are typical on service packs and absent on restaurant packs.

Questions

Does the Google local pack work on mobile requests?

localResults covers the desktop local pack, which is what Google Search requests return.

How do I check the local pack for a specific city?

Put the city in the query, such as plumber austin, and set country. Or send location, such as Austin,Texas,United States, or uule to search from that city.

Why is localResults missing from my result?

The field is omitted when no local pack appears on the results page, which is common for queries without local intent. Treat it as optional and record the absence.

Is the review count a number?

No. reviews is the count as Google displays it, such as 26K, so convert it yourself. rating is a number from 0 to 5.

Does local pack data cost extra?

No. localResults comes with every Google Search request at the base price: $0.00103 for one page.

More Google Search data

All Google Search fields · API reference