Serper Google Places Scraper
Pricing
$10.00 / 1,000 serper places page requests
Serper Google Places Scraper
Run one or many Google Places searches through the Serper.dev API with automatic pagination and CID-based dedupe. Outputs a clean, flat, import-ready dataset - built for Clay, Google Sheets, and CRM lead-gen workflows. Pay only per page request.
Pricing
$10.00 / 1,000 serper places page requests
Rating
5.0
(1)
Developer
Umami Data
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
7 days ago
Last modified
Categories
Share
Run one or many Google Places searches through the Serper.dev Places API and get a clean, deduplicated, import-ready dataset — without writing any pagination code. Tuned for lead-gen workflows (Clay, Google Sheets, CRM imports).
You bring your own Serper API key; the actor handles pagination, deduplication, and flattening for you.
Features
- Familiar input — the standard
apiKey/q/gl/locationfields, so it slots straight into existing Serper Places workflows. - Multi-query runs — paste many search queries (one per line) in a single run.
- Automatic pagination — the actor walks every result page until Serper returns no more places. No manual page counting.
- Global deduplication — places are deduplicated by Google CID across all queries (first-seen wins), so the same business never appears twice.
- Spend cap —
maxResultscaps the number of unique places per query so you stay in control of your Serper credits. An internal 50-page safety brake also guards against runaway pagination — but a normal query stops on its own long before that (Google returns at most ~120 results per query), so you'll almost never reach it. - Clean, flat output — every row is the same fixed set of snake_case columns, null-filled when Serper omits a field. Ready to import straight into a spreadsheet or CRM.
- Secret-safe — your Serper key is stored encrypted, never logged, and never written to a dataset row.
Data / Output
Every dataset row has exactly these columns, in this order. Fields that Serper does not return for a given place are filled with null.
| Column | Description |
|---|---|
title | Business / place name |
address | Formatted street address |
latitude | Latitude of the place |
longitude | Longitude of the place |
rating | Average Google rating (e.g. 4.6) |
rating_count | Number of ratings |
price_level | Google price level (e.g. $$), or null |
category | Primary place category (e.g. Coffee shop) |
phone_number | Phone number, when the business has one listed; otherwise null |
website | Website, when the business has one listed; otherwise null |
cid | Google Customer ID — the stable place identifier used for deduplication |
maps_url | Google Maps link, derived as https://maps.google.com/?cid=<cid> |
query | The search query that produced this row |
location | The location used for the search |
gl | The country code used for the search |
hl | The language code used (if supplied) |
page | The Serper result page this row came from |
position | The place's position within its page |
Sample output row
{"title": "Blue Bottle Coffee","address": "1 Ferry Building, San Francisco, CA 94111","latitude": 37.7956,"longitude": -122.3933,"rating": 4.5,"rating_count": 1280,"price_level": "$$","category": "Coffee shop","phone_number": "+1 510-653-3394","website": "https://bluebottlecoffee.com","cid": "1234567890123456789","maps_url": "https://maps.google.com/?cid=1234567890123456789","query": "coffee shops","location": "San Francisco, United States","gl": "us","hl": "en","page": 1,"position": 1}
(The cid above is synthetic — a placeholder for documentation only.)
Usage / Tutorial
- Get a Serper API key. Sign up at serper.dev and copy your API key from the dashboard. Serper offers a free tier so you can try the actor before paying for credits.
- Paste your key into the Serper API key field. It is a secret field — stored encrypted, never logged, never written to output.
- Enter a search. Set a single query in
q(e.g.coffee shops), or paste many queries (one per line) into Search queries. - Set the location. Provide a 2-letter country code in
gl(e.g.us) and a namedlocation(e.g.New York, United States). Optionally sethlfor the language andmaxResultsto cap results per query. - Run the actor. It paginates through every page automatically and pushes clean, deduplicated rows to the dataset. Export to JSON, CSV, or Excel, or pull it into Clay / Sheets / your CRM.
Run it from code, n8n, or the API
You don't have to use the Console — the actor runs the same way programmatically. There are two separate credentials, don't mix them up:
- Apify API token — authenticates you to Apify so you can start a run (from your Apify account → Settings → API & Integrations).
- Serper API key — passed as the
apiKeyinput field, exactly like in the Console. It is a secret field (encrypted, never logged), but you still include it in the input payload — that's expected and safe.
n8n
Add your Apify API token as Apify credentials once, then use the Apify node's "Run Actor and get dataset items" operation, select this actor, and provide the input JSON (keep your Serper key in an n8n credential/variable and reference it via an expression rather than hardcoding):
{ "apiKey": "YOUR_SERPER_API_KEY", "queries": ["coffee shops in soho"], "gl": "gb", "location": "London, United Kingdom", "maxResults": 50 }
The dataset rows flow straight into the next node. (No dedicated node? An HTTP Request node hitting the REST endpoint below works identically.)
REST API (one call, returns the rows)
curl -X POST "https://api.apify.com/v2/acts/USERNAME~serper-google-places-scraper/run-sync-get-dataset-items?token=APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{ "apiKey": "YOUR_SERPER_API_KEY", "queries": ["coffee shops in soho"], "gl": "gb", "location": "London, United Kingdom", "maxResults": 50 }'
JavaScript / Python (Apify client)
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('USERNAME/serper-google-places-scraper').call({apiKey: process.env.SERPER_KEY,queries: ['coffee shops in soho'],gl: 'gb',location: 'London, United Kingdom',maxResults: 50,});const { items } = await client.dataset(run.defaultDatasetId).listItems();
from apify_client import ApifyClientclient = ApifyClient(APIFY_TOKEN)run = client.actor("USERNAME/serper-google-places-scraper").call(run_input={"apiKey": SERPER_KEY,"queries": ["coffee shops in soho"],"gl": "gb","location": "London, United Kingdom","maxResults": 50,})items = client.dataset(run["defaultDatasetId"]).list_items().items
Bound your spend programmatically: set a per-run charge ceiling (
maxTotalChargeUsdin the run options / API). The actor stops cleanly the moment the limit is reached, so an automated loop can never run away. ReplaceUSERNAMEwith your Apify username (the actor lives atapify.com/USERNAME/serper-google-places-scraper).
Pricing
This actor uses pay-per-event charging, plus your own Serper credits.
- Actor fee: $0.01 per Serper Places page request (~10 places per page). That works out to $10 per 1,000 page requests. One charged event = one Serper page fetched, so a single multi-page query costs multiple events (e.g. a query that spans 3 pages = 3 charged events). Charging is per page request, not per result — your cost scales with pages fetched, not with how many places land on each page.
- Bring your own Serper credits: you supply your own Serper API key and pay Serper directly for the API calls the actor makes. The actor never resells Serper credits.
- Serper free tier: Serper provides a free tier of credits, so you can evaluate the actor at no Serper cost before topping up.
Input / Output Examples
Input
A minimal, runnable input. Replace the placeholder with your real key.
{"apiKey": "YOUR_SERPER_API_KEY","q": "coffee shops","gl": "us","location": "New York, United States","maxResults": 100}
To run several searches at once, supply queries (one per line) instead of, or in addition to, q:
{"apiKey": "YOUR_SERPER_API_KEY","queries": ["coffee shops", "bakeries", "bookstores"],"gl": "us","location": "New York, United States","hl": "en","maxResults": 50}
Output
Each run produces dataset rows shaped exactly like the sample output row above, with the columns documented in Data / Output.
FAQ
Why is pricing per page request and not per result? Serper bills per page request, and a page can return a variable number of places (up to ~10). Charging per page keeps your cost predictable and tied to the actual API calls made, instead of mischarging based on how many places happen to appear on a page.
What happens when I hit the Serper charge limit? The actor respects the run's max-charge limit. It stops issuing new page requests before exceeding the limit, so you never get charged beyond what you set — partial results collected up to that point are still saved.
How many results can a single query return?
maxResults caps the number of unique places per query (counted after deduplication — duplicates never consume the cap). Omit it for unlimited results. An internal 50-page safety brake also applies as a runaway-pagination guard; whichever limit is reached first ends the query. In practice a single query exhausts on its own well before 50 pages — Google returns at most ~120 results per query, so the natural last-page stop almost always fires first. The brake exists only to bound spend if the upstream API ever fails to terminate.
Do duplicate places across multiple queries get returned twice? No. Places are deduplicated globally by Google CID across all queries in a run (first-seen wins), so the same business never appears in more than one row.