1. Why Single-Query City Searches Miss 85% of Local Businesses
Any single Google Maps search viewport returns at most 100–120 businesses ranked by prominence. If you search 'dentists in Los Angeles', you only see top-ranked clinics near downtown.
| Extraction Strategy | Max Places per City | Endpoint | Effective Cost / 1K Places |
|---|---|---|---|
| Single City Text Query | Up to 100 places | GET /v1/places/search?q=dentists+in+Austin | $0.20 – $0.50 / 1K |
| ZIP Code Loop | 1,500 – 4,000 places | GET /v1/places/search?q=dentists+78701 | $0.20 – $0.50 / 1K |
| Coordinate Grid Viewport Scan | 10,000+ places (100% recall) | GET /v1/places/nearby?q=dentist&lat=...&lng=...&zoom=15 | $0.20 – $0.50 / 1K (0 on empty cells) |
2. Querying /v1/places/search & Deduplicating by place_id
Every business returned by PlacesData API includes its canonical place_id, E.164 phone number, normalized website domain, and exact WGS84 coordinates.
Fetch Local Business Leads with Phone, Website & Coordinates
Run a synchronous search for local businesses and inspect normalized contact fields:
curl "https://api.placesdataapi.com/v1/places/search?q=specialty+coffee+in+SoHo+New+York&limit=20" \
-H "x-api-key: pd_live_your_api_key"import requests
API_KEY = "pd_live_your_api_key"
seen_places = {}
for zip_code in ["10012", "10013", "10014"]:
res = requests.get(
"https://api.placesdataapi.com/v1/places/search",
headers={"x-api-key": API_KEY},
params={"q": f"coffee shops in New York, NY {zip_code}", "limit": 50},
timeout=30,
).json()
for place in res.get("data", []):
seen_places[place["place_id"]] = place
print(f"Unique businesses collected: {len(seen_places)}")const seenPlaces = new Map();
for (const zip of ["10012", "10013", "10014"]) {
const url = new URL("https://api.placesdataapi.com/v1/places/search");
url.searchParams.set("q", `coffee shops in New York, NY ${zip}`);
url.searchParams.set("limit", "50");
const res = await fetch(url, {
headers: { "x-api-key": "pd_live_your_api_key" },
});
const { data } = await res.json();
for (const place of data) {
seenPlaces.set(place.place_id, place);
}
}
console.log("Unique businesses:", seenPlaces.size);{
"code": 0,
"provider": "https://placesdataapi.com",
"status": "ok",
"msg": "success",
"data": [
{
"place_id": "ChIJSy28upiAhYARkoxpzFnW7b4",
"cid": "13757888117856636050",
"google_id": "0x80858098babc2d4b:0xbeedd659cc698c92",
"name": "Blue Bottle Coffee",
"category": "Coffee shop",
"phone": "+15106613510",
"website": "https://bluebottlecoffee.com/us/eng/northern-california-cafes",
"domain": "bluebottlecoffee.com",
"rating": 4.6,
"reviews_count": 908,
"address": "Blue Bottle Coffee, 315 Linden St, San Francisco, CA 94102",
"latitude": 37.7763342,
"longitude": -122.4232375
}
],
"meta": {
"request_id": "799c3853-e73d-494a-b669-4b69b4cf7f3f",
"endpoint": "/v1/places/search",
"count": 1,
"credits_charged": 5,
"took_ms": 34
}
}Interactive Engineering Workbench · GET /v1/places/search
Verify real-time latency, credit math & JSON schema
Frequently Asked Questions
- How many concurrent requests can I run when scanning a large metro grid?
- Starter accounts support 300 RPM (5 RPS), Growth supports 600 RPM (10 RPS), Pro supports 1,200 RPM (20 RPS), and Business supports 3,000 RPM (50 RPS).
- Do I pay for grid coordinates that land on water or empty neighborhoods?
- No. Whenever GET /v1/places/nearby or GET /v1/places/search returns 0 results, 0 Credits are deducted.