How to Scrape Google Maps with n8n (and Send Results to Google Sheets)

A working n8n workflow that pulls Google Maps business data into a Google Sheet on demand or on a schedule. No code, no browser automation, no proxy configuration. The template is free, the actor bills about a dollar per thousand places, and the whole thing sets up in under ten minutes.

Google Sheet populated with Google Maps results: title, category, address, phone, website, rating, review count and other fields across many rows
What you end up with: 30+ fields per business, straight into your Google Sheet.
Difficulty: Beginner
Time: 10 minutes
Cost: ~$1 per 1,000 places (free Apify tier covers ~5,000/month)
Tools: n8n, Apify, Google Sheets
Download the n8n template ↓ Open the actor on Apify

In this tutorial

  1. What you will build
  2. Prerequisites
  3. Step 1: Get your Apify API token
  4. Step 2: Import the n8n template
  5. Step 3: Paste your token and search query
  6. Step 4: Connect Google Sheets
  7. Step 5: Run it
  8. Schedule daily runs
  9. Add reviews, popular times, or contact emails
  10. Skip places you have already scraped
  11. Handling large runs
  12. What it costs
  13. FAQ

What you will build

A four-node n8n workflow. Click Run, and about ten seconds later a fresh batch of businesses lands in your Google Sheet with 30-plus fields per row: business name, category, full address with parsed city and postal code, phone, website, GPS coordinates, rating, review count, opening hours, price range, photos, and more.

The workflow calls the NanoScrape Google Maps Scraper under the hood. That actor is a lightweight Go binary running on Apify, roughly 80 MB in size, uses datacenter proxies, and returns results in seconds. All the field extraction, geocoding, and pagination is handled for you.

Prerequisites

STEP 1

Get your Apify API token

  1. Open the Google Maps Scraper and click Try for free.
  2. Sign up with Google or email. It takes about a minute.
  3. Once signed in, click your avatar (top right), open Settings, then Integrations.
  4. Copy the Personal API token. Keep the tab open, you will paste it in a moment.
Apify Console Settings page showing the Integrations tab with the Personal API token field
Apify Console › Settings › Integrations. Copy the Personal API token.
Tip: the free tier is more than enough to complete this tutorial. You only pay if you exceed $5 in usage in a given month.
STEP 2

Import the n8n template

  1. Download the workflow: scrape-google-maps-to-google-sheets.json
  2. In n8n, open the workflows list. Click the three-dot menu at the top right and choose Import from File.
  3. Select the JSON you just downloaded.
n8n workflows list with the top-right three-dot menu open, highlighting the Import from File option
Top-right menu in the n8n workflows list. Choose "Import from File".

You will see three nodes wired left to right:

  1. Manual Trigger starts the run when you click a button.
  2. Run an Actor and get dataset calls the Google Maps Scraper via the verified Apify n8n node. It handles the run, waits for completion, and returns the dataset items.
  3. Append to Google Sheet writes one row per business.
n8n canvas after import showing three nodes wired left to right: Manual Trigger, Run an Actor and get dataset, Append to Google Sheet
The imported workflow: three nodes, no code, no HTTP wiring.
Self-hosted or n8n Desktop? If the Apify node is missing after import, install it once from Settings › Community Nodes › Install with the package name @apify/n8n-nodes-apify. On n8n Cloud it is pre-installed.
STEP 3

Add your Apify credential and review the input

Open the Run an Actor and get dataset node. At the top, click the Credential to connect with dropdown and choose Create new credential. Paste the Personal API token you copied in step 1, name it something like "Apify account", and save.

n8n Apify node with the Credential to connect with dropdown expanded, showing Create new credential
Step 3a: open the credential dropdown, choose Create new.
n8n credential creation panel for Apify with the API token field ready to paste
Step 3b: paste the Apify Personal API token, save.

Below the credential, the template pre-fills the Input JSON with a working configuration. This is the same JSON you would paste into the actor's Input tab on Apify Console:

{
  "searchStrings": [
    "pizza restaurant new york",
    "coffee shop new york"
  ],
  "maxResultsPerQuery": 50,
  "language": "en",
  "includeReviews": true,
  "maxReviewsPerPlace": 10,
  "outputLanguage": "en",
  "proxyConfiguration": { "useApifyProxy": true },
  "maxConcurrency": 10,
  "requestDelay": 300
}

Adjust the fields you care about and leave the rest at their defaults:

Why include the location in the query string? Google Maps ranks results by relevance to the whole search string. plumber Berlin returns better results than plumber with a separate location filter.
STEP 4

Create a Google Sheet and connect it

  1. Go to Google Sheets and create a new blank spreadsheet. Leave the first row empty. The n8n node handles headers automatically.
  2. Copy the spreadsheet ID from the URL. It is the long string between /d/ and /edit.
Google Sheets URL in a browser address bar with the spreadsheet ID portion highlighted
The spreadsheet ID is the long string between /d/ and /edit.
  1. In n8n, open the Append to Google Sheet node.
  2. Paste the spreadsheet ID into the Document ID field.
  3. Leave the sheet name as Sheet1 if that is what your tab is called, otherwise update it.
  4. Click the Credential to connect with dropdown at the top of the node. Pick an existing Google Sheets credential or click Create New to walk through the Google OAuth flow.
n8n Google Sheets credential creation panel with Sign in with Google button
Step 4a: create a new Google Sheets credential.
Google OAuth consent screen granting n8n access to Google Sheets
Step 4b: sign in and grant access. One-time setup.

Back in the node, confirm the Document ID and Sheet Name are set, and save.

Configured Append to Google Sheet node with Document ID and sheet name filled
Final configuration of the Append to Google Sheet node.
Tip for self-hosted n8n: if you have not set up Google credentials before, follow n8n's OAuth setup guide. It takes about five minutes.
STEP 5

Run it

Click Test Workflow at the bottom left. Each node lights up green as it runs. Depending on maxResultsPerQuery and how many search strings you added, the run finishes in roughly ten to sixty seconds. Open your Google Sheet: one row per business, with columns for name, address, phone, website, rating, review count, opening hours, GPS coordinates, and around 25 other fields.

n8n canvas after a successful run showing all nodes with green checkmarks, next to the populated Google Sheet
Successful run. Green checkmarks on every node, rows in the sheet.

If something goes wrong, click the node with the red icon and read the error panel on the right:

Schedule daily runs

Replace the Manual Trigger with a Schedule Trigger node. Set the interval to once a day, once a week, or a cron expression of your choice. Every morning your sheet will grow with fresh data for the search terms you configured.

To keep the sheet clean, either clear it at the start of each run (add a Google Sheets "Clear" node before the Append), or skip already-scraped places (see the next section).

Add reviews, popular times, or contact emails

The Google Maps Scraper has several optional enrichments that stack on top of the basic scrape. Enable them by editing the Input JSON field of the Run an Actor and get dataset node.

Input JSON field of the Apify node with includeReviews, maxReviewsPerPlace, includePopularTimes and other enrichment options set
All enrichments are just fields in the Input JSON. Toggle them per run.

Featured reviews

Set "includeReviews": true (it is already enabled in the default template) and each place gets a user_reviews array with author name, star rating, publication date, and review text. Adds about 300 ms per place.

{
  "searchStrings": ["restaurants in Paris"],
  "maxResultsPerQuery": 20,
  "includeReviews": true,
  "maxReviewsPerPlace": 10,
  "reviewsSort": "newest"
}

Sort options: most_relevant (default), newest, highest_rating, lowest_rating. To only pull reviews from the last month, add "reviewsNewerThan": "2026-06-14".

Popular times histogram

Add "includePopularTimes": true and each place gets a popular_times object with visitor-traffic scores by weekday and hour (0 to 100). Great for finding low-traffic time slots. Adds about 1.5 seconds per place.

Contact email extraction

Add "enableContactExtraction": true and "geminiApiKey": "your-gemini-key". After the Maps scrape completes, an AI-powered add-on visits every business website found in the results and extracts team member names, emails, phone numbers, and departments. Great for turning a lead list into a contact list in one step. Get a free Gemini API key at Google AI Studio.

How the add-ons are billed: the base Google Maps scrape stays at $1 per 1,000 places regardless of which enrichments you enable. Contact extraction is billed separately by the Website Contact Extractor. Reviews and popular times are free.

Skip places you have already scraped

Every place on Google Maps has a stable identifier called a CID. It does not change even if the business renames or moves. To avoid re-collecting places on scheduled runs, pass an array of CIDs in the excludeCids parameter.

{
  "searchStrings": ["cafes in Zurich"],
  "maxResultsPerQuery": 100,
  "excludeCids": ["12345678901234567", "98765432109876543"]
}

A common pattern in n8n: read the CID column from your existing sheet with a Google Sheets "Read" node, feed it into a Set node that builds the array, then reference that array in the Apify node's Input JSON via an expression.

Handling large runs

The Apify n8n node manages the run lifecycle for you: it starts the actor, waits for completion, and returns the dataset items. For big jobs, just bump the Timeout field in the node's options (defaults to 3000 seconds, plenty for tens of thousands of places).

If you want to run a very long job in the background and check on it later, switch the operation to Run Actor (without and get dataset) to start the run without waiting, then add a second node with Get dataset items that runs on a schedule.

What it costs

A daily workflow that pulls 100 new places every morning runs at about $3 per month. A weekly workflow that pulls 1,000 places every Monday runs at $4 per month.

FAQ

Do I need a paid Apify plan to run this?

No. The free tier includes $5 of usage credit every month, enough for around 5,000 places from this actor. You only pay if you go over.

Does the template work with n8n Cloud, self-hosted, and Desktop?

Yes, all three. It uses n8n's core Manual Trigger and Google Sheets nodes plus the verified Apify node. On n8n Cloud the Apify node is available immediately. On self-hosted or Desktop, install it once from Settings › Community Nodes › Install with the package name @apify/n8n-nodes-apify.

Can I send results to Airtable, PostgreSQL, or Notion instead?

Yes. Replace the Google Sheets node at the end of the workflow with whatever destination you prefer. All incoming fields are auto-mapped, so you just need to point the new node at your target and pick which fields to keep.

How do I search multiple queries in one run?

Two options. Simple approach: add more strings to the searchStrings array in the Apify node's Input JSON (the template already ships with two example queries). Advanced approach: use the structured queries parameter, which lets you attach your own company_id per query and separate the search term from the location and country code. The actor README has examples.

Can I collect email addresses too?

Yes. Set enableContactExtraction to true and provide a Gemini API key. The scraper visits every business website found in the results and extracts team member emails, names, positions, and phone numbers using AI.

What if I want to scrape more than 500 places in one query?

Google Maps returns at most about 120 results per single query. For broader coverage, split the search by neighborhood, category, or sub-region and run each as a separate search string. For example, instead of "restaurants in London", try "restaurants in Shoreditch", "restaurants in Camden", "restaurants in Notting Hill".

How fresh is the data?

Every scrape hits Google Maps live. There is no cached data. Whatever Google shows at the moment of the run is what you get in your sheet.

Is scraping Google Maps legal?

Scraping publicly available data is generally permitted in most jurisdictions, but the specifics depend on where you and your users are located and what you do with the data. The hiQ Labs v. LinkedIn ruling in the US established that scraping public data is not a violation of the Computer Fraud and Abuse Act. GDPR still applies to any personal data you collect. Consult a lawyer if you have specific compliance questions.

Related resources

Download the template ↓ Open the actor on Apify