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 key

A 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:

FieldWhat it holds
Place_NameBusiness name as it appears on Maps
EmailAddress published on the business website, where there is one
Phone, WebsiteContact details from the listing
Full_Address, City, Postal_Code, CountryLocation, split into parts
Latitude, Longitude, Place_IDFor mapping and de-duplication
Rating, Reviews_Count, PriceReputation signals
Category, CategoriesHow the business is classified
LinkedIn, Facebook, Instagram and five moreSocial profiles found on the site
Permanently_Closed, Temporarily_ClosedSo you can filter them out
Not every business publishes an email. In the job above, 118 of 173 records carried one. Records delivered without an email are billed at a lower rate than the rest.

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

ItemValue
Google Maps records$12 per 1,000
Records without an email addressBilled at a reduced rate
Optional real-time email verification$5 per 1,000, on top
Job size100 minimum, 50,000 maximum, in multiples of 100
Places per search termUp to 500, so a larger total needs more terms
Rate limits120 requests per minute, 20 job starts per minute
BillingPrepaid 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.

Related