NativePort
← Google Maps API

Build a business list from Google Maps results

Search for a type of business in an area and collect the available listing details as JSON. The example combines several map searches into a CSV.

Try a request

curl
curl https://api.nativeport.ai/serper/maps \
  -H "Authorization: Bearer $NATIVEPORT_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{"q": "coffee roasters", "ll": "@37.7749,-122.4194,13z"}'
example response
{
  "places": [
    {
      "title": "Ritual Coffee Roasters",
      "address": "1026 Valencia St, San Francisco, CA 94110",
      "latitude": 37.7561,
      "longitude": -122.4213,
      "phoneNumber": "+1 415-641-1011",
      "website": "https://ritualroasters.com/",
      "rating": 4.4,
      "ratingCount": 1893,
      "category": "Coffee shop"
    }
  ]
}

Search an area and save the results

Send a search term, such as a business category, with a map center. Each result contains the listing details available to the provider, which may include an address, phone number, website, and rating.

The Python example queries several nearby map centers and removes duplicates using the business name and address. It writes the remaining records to a CSV that you can review or import into your own tools.

A maps search does not guarantee every matching business in a region. If your project needs broader collection, compare a bulk tool such as an Apify Maps actor and check its limits. Keep coverage separate from the number of rows returned.

Listings can be incomplete. Treat phone numbers, websites, and ratings as optional, and check the returned matches before using them in a customer-facing directory. If you need email addresses, visiting the business websites is a separate step.

Export business results from several map areas

Searches several map centers, removes duplicate names and addresses, and writes a CSV.

python
import csv, json, os, urllib.request

QUERY = "coffee roasters"
# A maps query answers around one viewport, so cover a city with a few centres.
CENTRES = ["@37.7749,-122.4194,13z", "@37.7899,-122.4014,13z",
           "@37.7599,-122.4348,13z"]

def maps(q, ll):
    req = urllib.request.Request(
        "https://api.nativeport.ai/serper/maps",
        data=json.dumps({"q": q, "ll": ll}).encode(),
        headers={
            "Authorization": f"Bearer {os.environ['NATIVEPORT_API_KEY']}",
            "Content-Type": "application/json",
        },
    )
    with urllib.request.urlopen(req) as r:
        return json.load(r).get("places") or []

seen, rows = set(), []
for ll in CENTRES:
    for p in maps(QUERY, ll):
        key = (p.get("title"), p.get("address"))
        if key in seen:
            continue
        seen.add(key)
        rows.append(p)

with open("leads.csv", "w", newline="") as fh:
    w = csv.writer(fh)
    w.writerow(["name", "address", "phone", "website", "rating", "reviews"])
    for p in rows:
        w.writerow([p.get("title"), p.get("address"), p.get("phoneNumber"),
                    p.get("website"), p.get("rating"), p.get("ratingCount")])
print(f"{len(rows)} unique places from {len(CENTRES)} queries → leads.csv")
example output
$ python leads.py
47 unique places from 3 queries → leads.csv

Consider another approach

For searches around a map location

Serper's maps endpoint returns a page of matching businesses as JSON. Use several queries when you need to cover more than one area.

For bulk collection

Apify's Google Maps actors collect results as background jobs. Compare the actor's coverage, limits, and per-result cost for your project.

Use it with NativePort

Use your NativePort key for Maps searches and any website scraping you add afterwards. Both draw from the same balance.

Before you start

Does one request return every business in the area?

No. It returns a page of search results around the map location. Several queries can broaden coverage, and you should remove duplicates. Bulk collection tools can help, but check their limits before assuming a complete list.

How do I set the search area?

The ll parameter sets a map center and zoom, using @latitude,longitude,zoom. The example uses 13z. Adjust the center and zoom for the area you want to research.

What if a listing has no phone number or website?

Allow those fields to be empty. The example uses .get() so a missing value does not stop the export.

Can I collect the review text too?

The maps response includes ratings and review counts where available. Use a separate reviews request for the text, with the place identifier required by that endpoint.