To get business leads with phone numbers from Google Maps, use Scavio's Google Maps API. POST /api/v2/google/maps/search with a category and a city returns 20 businesses a call with name, phone, website, address, rating, review count, category, opening hours and coordinates; page with start up to 100 for about 120 per query. On October 27, 2026, five Phoenix categories returned 515 unique businesses and 505 of them (98%) had a phone on the search row. Each call costs 1 credit, about $0.002 on the Growth plan billed yearly.
Google's own Places API returns phone numbers as well, but they are billed at its Enterprise tier, and its policies let you store place IDs indefinitely while ruling out caching or storing the rest beyond narrow exceptions, which is a problem for a list you keep. The steps below read the public listing instead.
Step 1: Search a category in a city
curl -s https://api.scavio.dev/api/v2/google/maps/search \
-H "Authorization: Bearer $SCAVIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "auto repair shops in Phoenix, AZ", "ll": "@33.4484,-112.0740,12z"}'ll is the map center as @latitude,longitude,zoom, and it decides where results come from. The response is flat: local_results sits at the top level. One row from the second page, as captured (thumbnail, provider_id, hours, extensions and four weekdays trimmed):
{
"position": 27,
"title": "Simon's Auto Repair",
"place_id": "ChIJ2UP9KiUTK4cRitieWP3HV9k",
"data_id": "0x872b13252afd43d9:0xd957c7fd589ed88a",
"data_cid": "15661206120131647626",
"gps_coordinates": { "latitude": 33.509717699999996, "longitude": -112.10713419999999 },
"rating": 4.7,
"reviews": 169,
"unclaimed_listing": true,
"type": "Auto repair shop",
"types": ["Auto repair shop"],
"address": "2220 W Camelback Rd, Phoenix, AZ 85015",
"open_state": "Closed · Opens 8 AM",
"operating_hours": {
"monday": "8 AM–5 PM",
"saturday": "9 AM–3 PM",
"sunday": "Closed"
},
"phone": "(602) 336-9807"
}There is no website key on this row because the listing has none; rows that have one carry it, along with book_online or order_online links where the business shows them. unclaimed_listing marks a Business Profile the owner never claimed, and it appeared on 37 of our 515 businesses.
Step 2: Page through the results and remove repeats
Search pages hold 20 businesses and start takes 0, 20, 40, 60, 80 and 100. A seventh page, start: 120, returns 400 with "Too big: expected number to be <=100". Pages overlap, so keep a dictionary keyed on place_id:
import csv
import requests
API_KEY = "sk_live_your_key"
leads = {}
for start in range(0, 120, 20):
r = requests.post(
"https://api.scavio.dev/api/v2/google/maps/search",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"query": "auto repair shops in Phoenix, AZ",
"ll": "@33.4484,-112.0740,12z", "start": start},
timeout=120,
)
for p in r.json().get("local_results", []):
leads[p["place_id"]] = p
fields = ["title", "phone", "website", "address", "rating", "reviews", "type", "place_id"]
with open("leads.csv", "w", newline="") as f:
w = csv.DictWriter(f, fieldnames=fields, extrasaction="ignore")
w.writeheader()
w.writerows(leads.values())
print(len(leads))For auto repair shops that was 120 rows and 105 unique businesses. Across our five categories, 85 of 600 rows were repeats. The slowest page took 52 seconds and the median 6.7, so keep the timeout generous.
Step 3: Count what the list actually contains
| Category, Phoenix | Unique businesses | Phone | Website | Phone and website | Phone, no website |
|---|---|---|---|---|---|
| Dentists | 99 | 99 | 98 | 98 | 1 |
| Roofers | 100 | 99 | 95 | 94 | 5 |
| Hair salons | 102 | 99 | 92 | 90 | 9 |
| Mexican restaurants | 109 | 104 | 98 | 94 | 10 |
| Auto repair shops | 105 | 104 | 74 | 73 | 31 |
| All five | 515 | 505 | 457 | 449 | 56 |
Phones are close to universal. Websites are not: 30% of the auto repair shops had none, which makes them the list for anyone selling websites, and the same filter returns 1 dentist. 509 of the 515 had a street address. The best Google Maps lead data APIs post charts these numbers and compares the other ways to get them.
Step 4: Cover more ground with more map centers
One query tops out at about 120 businesses. Move the center to reach the rest of a metro:
curl -s https://api.scavio.dev/api/v2/google/maps/search \
-H "Authorization: Bearer $SCAVIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "auto repair shops in Phoenix, AZ", "ll": "@33.6100,-112.0740,13z"}'From a center about 18 km north, the first page returned 20 shops and none of them were among the 105 from downtown. A center toward Tempe returned 9 new out of 20. Merge into the same place_id dictionary and the list grows without double-counting.
Step 5: Fill a single record by place_id
When you already have a business and need its full record, or you want its review breakdown before calling, use place detail:
curl -s https://api.scavio.dev/api/v2/google/maps/place \
-H "Authorization: Bearer $SCAVIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"place_id": "ChIJ2UP9KiUTK4cRitieWP3HV9k"}'place_results repeats the phone, address and coordinates and adds the plus code, the full week of hours, review snippets and the star breakdown:
{
"title": "Simon's Auto Repair",
"rating": 4.7,
"reviews": 169,
"unclaimed_listing": true,
"plus_code": "GV5V+V4 Phoenix, Arizona",
"phone": "(602) 336-9807",
"rating_summary": [
{ "stars": 1, "amount": 5 },
{ "stars": 2, "amount": 4 },
{ "stars": 3, "amount": 4 },
{ "stars": 4, "amount": 13 },
{ "stars": 5, "amount": 143 }
]
}It confirmed what the search row said: no website on the listing. For the reviews themselves, pass the data_id to /api/v2/google/maps/reviews.
All four endpoints
| Endpoint | What it returns | Credits |
|---|---|---|
/api/v2/google/maps/search | 20 businesses a page with phone, website, address, rating, category, hours and coordinates | 1 |
/api/v2/google/maps/place | One business in full by place_id or data_cid, with star breakdown and review snippets | 1 |
/api/v2/google/maps/reviews | A page of reviews with text, author and date, sortable | 1 |
/api/v2/google/maps/geo-grid | A business's map rank at every point of a 3x3, 5x5 or 7x7 grid | 1 per grid point |
Our five-category Phoenix run cost 30 credits for 505 phone leads, about $0.06 on the Growth plan billed yearly. If you would rather not write the loop, the free Google Maps lead scraper tool runs the same search and flags businesses with no website.
Getting started
- Sign up at dashboard.scavio.dev/sign-up: 50 free credits, no card required.
- Copy your API key from the dashboard.
- Send a POST to
/api/v2/google/maps/searchwith your key in theAuthorizationheader.
Try the Google Maps API free in the playground first, or call it from Claude and other agents through the MCP server.
Reference: Google Maps API overview · search · place · reviews · geo-grid
Frequently asked questions
How do I get a business phone number from Google Maps with an API?
Call Scavio's /api/v2/google/maps/search with a query such as "roofers in Phoenix, AZ". Each of the 20 results carries a phone field when the listing shows one; in our test 505 of 515 businesses had it. For a single business you already know, /api/v2/google/maps/place takes its place_id and returns the same phone with the full record.
How many businesses can I pull for one search?
About 120. Search pages hold 20 and start runs from 0 to 100, so six calls cover one query; start 120 is rejected. Repeats across pages are common, 85 of our 600 rows, so de-duplicate on place_id. To cover a larger area, run the same query from several map centers with the ll parameter.
Does Google Maps give business emails?
No. A Maps listing shows a phone and a website but no email address, so any tool that returns emails crawls the business website to find one. Use the website field from the search result as the input to that step.
How do I find businesses without a website?
Filter the search results for rows with a phone and no website. In Phoenix on October 27, 2026, 31 of 105 auto repair shops matched, against 1 of 99 dentists, so the category you pick decides how long that list is.
What does a Google Maps lead cost with Scavio?
A search call is 1 credit and returns up to 20 businesses. Our five Phoenix categories used 30 credits for 505 phone leads, about 59 credits per 1,000 leads: roughly $0.12 on the Growth plan billed yearly. New accounts get 50 free credits with no card.