Google Maps scraper API
Send a search term and a place, get back the businesses with their address, phone, website, rating and the email address published on their site. JSON by default, CSV if you prefer. No browser, no proxies, no headless setup to maintain.
Get an API keyA confirmed account starts with $2.00 in credit, enough for about 160 records.
One call to start a job
Everything is a job: you start it, poll it, then read the records.
curl -X POST https://app.evascrape.com/api/v1/jobs \
-H "Authorization: Bearer $EVASCRAPE_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "google_maps",
"list_name": "austin-dentists",
"total_records": 200,
"search_terms": "dentist",
"location": "Austin, Texas"
}'
Then poll until it is finished. This is a real response from the status endpoint:
GET /api/v1/jobs/90
{
"job": {
"id": 90,
"status": "succeeded",
"source": "google_maps",
"list_name": "austin-dentists",
"requested_records": 200,
"delivered_records": 173,
"records_with_email": 118,
"email_verification": false,
"verification_status": "none",
"credits_charged": "2.40",
"credits_refunded": "0.32",
"error": null,
"created_at": "2026-09-07T02:33:06.208Z",
"results": {
"available": true,
"variants": ["all"],
"url": "/api/v1/jobs/90/results"
}
}
}
Read that response carefully, because it shows how billing works. The job asked for 200 records and found 173. You were charged $2.40 up front and $0.32 came back automatically. Asking for more than exists costs nothing extra.
What each record contains
Thirty-one fields per place. The ones people use most:
| Field | What it holds |
|---|---|
Place_Name | Business name as it appears on Maps |
Email | Address published on the business website, where there is one |
Phone, Website | Contact details from the listing |
Full_Address, City, Postal_Code, Country | Location, split into parts |
Latitude, Longitude, Place_ID | For mapping and de-duplication |
Rating, Reviews_Count, Price | Reputation signals |
Category, Categories | How the business is classified |
LinkedIn, Facebook, Instagram and five more | Social profiles found on the site |
Permanently_Closed, Temporarily_Closed | So you can filter them out |
Reading the results
JSON is the default, because that is what code wants:
GET /api/v1/jobs/90/results?limit=1000&offset=0
{
"job_id": 90,
"variant": "all",
"total": 173,
"offset": 0,
"limit": 1000,
"has_more": false,
"fields": ["Place_Name", "Email", "Phone", "..."],
"records": [ { "Place_Name": "...", "Email": "...", "Phone": "..." } ]
}
Add ?format=csv for the raw file. Very large result sets must be read as CSV.
Price it before you spend
The quote endpoint costs nothing and changes nothing. Use it when an agent or a script is spending on someone's behalf. Real response:
POST /api/v1/quote {"source": "google_maps", "total_records": 200}
{
"source": "google_maps",
"total_records": 200,
"email_verification": false,
"cost": { "base": "2.40", "verification": "0.00", "total": "2.40" },
"currency": "USD",
"note": "You are charged up front and refunded for any records we cannot deliver."
}
Pricing and limits
| Item | Value |
|---|---|
| Google Maps records | $12 per 1,000 |
| Records without an email address | Billed at a reduced rate |
| Optional real-time email verification | $5 per 1,000, on top |
| Job size | 100 minimum, 50,000 maximum, in multiples of 100 |
| Places per search term | Up to 500, so a larger total needs more terms |
| Rate limits | 120 requests per minute, 20 job starts per minute |
| Billing | Prepaid balance in USD, no subscription, credits do not expire |
Errors are boring on purpose
Every failure is JSON with a stable code. These are real responses:
401 {"error":{"code":"invalid_api_key","message":"This API key is not valid, or it was revoked."}}
400 {"error":{"code":"invalid_request","message":"source must be one of: google_maps, apollo, linkedin."}}
400 {"error":{"code":"invalid_request","message":"Search terms and location are required!"}}
402 {"error":{"code":"insufficient_credits","message":"Your credit is insufficient!"}}
Skip the polling
Pass callback_url when you start a job and the finished job object is
posted to your endpoint, signed with HMAC-SHA256 in X-Evascrape-Signature.
The URL has to be https and publicly resolvable.
How this compares to building it yourself
You can drive a headless browser against Maps yourself. What you take on is proxy rotation, layout changes, retry logic, and the separate job of visiting each business website to find a published email address. That last part is usually the reason people stop maintaining their own scraper: the map data is the easy half.
General purpose scraping platforms such as Apify, Outscraper and SerpApi also cover Google Maps. Their pricing models and quotas change, so check their current pages rather than trusting a comparison table. What differs structurally is the shape: those platforms give you a scraping runtime and you assemble the workflow, while this API gives you one endpoint that returns business records with emails already resolved, priced per record with automatic refunds for what could not be delivered.
If you want the comparison in one line: use a scraping platform when you need arbitrary sites, use this when you specifically need business contact data.