# n8n Google Maps Leads Workflow: Step by Step

URL: https://leadraft.co/blog/n8n-google-maps-leads-workflow
Summary: Build a Google Maps leads workflow in n8n: your data source options, the 60 and 120 result caps, a node-by-node REST API and webhook build, then Sheets or Instantly.

[ All articles](https://leadraft.co/blog)

# How to build a Google Maps leads workflow in n8n (with verified emails)

Build a Google Maps leads workflow in n8n: your data source options, the 60 and 120 result caps, a node-by-node REST API and webhook build, then Sheets or Instantly.

The Leadraft teamLeadraft

Published

November 3, 2026

Read time

11 min

Category

Playbook

To build a Google Maps leads workflow in n8n, you need a data source first: n8n has no official Google Maps node, so workflows either call the Google Places API through the HTTP Request node, run a scraper through a community node, or call a lead tool's API. The core build is four nodes: start a search, wait and poll until it finishes, page through the leads, and write them to Google Sheets or a sending tool. If you want n8n to receive leads instead of fetching them, a Webhook node can catch them as they're exported. Below are the options, the result cap that breaks most templates, and a node-by-node build with exact endpoints.

## What are my options for getting Google Maps data into n8n?[#](#what-are-my-options-for-getting-google-maps-data-into-n8n)

There are three ways to get businesses from Google Maps into n8n, and they differ in how many businesses you get per search and whether emails come with them. We checked n8n's integrations directory in November 2026 and found no official Google Maps or Places node; the Google nodes listed are Sheets, Gmail, Drive, Calendar and Gemini.

Scroll horizontally if needed →

| Route | How it works in n8n | Results per query | Emails | Runs on n8n Cloud |
| --- | --- | --- | --- | --- |
| Google Places API | HTTP Request node to Text Search (New), with your API key | Up to 60 (20 per page, 3 pages) | No: Google doesn't provide them | Yes |
| Community node or scraper actor | A community node (for example one wrapping an Apify actor) or an HTTP call to the scraper's API | Depends on the actor and its settings | Some actors crawl websites for emails; checks vary | Verified community nodes only |
| Lead tool REST API | HTTP Request nodes to the tool's API, or its webhook into an n8n Webhook node | Whole area, deduped | Depends on the tool | Yes |

Two n8n details matter here. First, unverified community nodes "aren't available on n8n cloud" and need a self-hosted instance; only verified ones install from the in-app nodes panel. Many Google Maps community nodes are small, early packages, so check their version history before you depend on one. Second, n8n counts an execution as "a single run of your entire workflow", regardless of how many steps it has. As of November 2026, n8n Cloud's Starter plan was listed at €20 a month (billed annually) for 2,500 executions, and the self-hosted Community edition is on GitHub.

On terms: Google's Maps terms restrict scraping Maps content, and the Places API has its own rules about storing data. Read [is scraping Google Maps legal](https://leadraft.co/blog/is-scraping-google-maps-legal) before you build a large pipeline, and get legal advice if you resell or store the data long term.

## Why do n8n Google Maps templates stop at 60 or 120 results?[#](#why-do-n8n-google-maps-templates-stop-at-60-or-120-results)

Because one Google search is capped, and most templates run one search per city. Google's Text Search (New) reference says it "returns a maximum of 60 results across all pages", and the Maps interface itself stops at about 120 places per search. A template that runs "dentist in Phoenix" through either route gets the top of Google's ranking and silently misses everyone else.

One search stops after a few hundred results, mostly near the middle. Searching the area tile by tile reaches the edges. Measured once: Portland coffee shops, 230 from one search vs 457 tiled (measured on one city and one keyword.)

The fix is the same whatever tool you use: split the area into small tiles, search each tile, split any tile that still returns the full cap, try several names for the trade ("dentist", "dental clinic", "orthodontist"), and dedupe by Google place ID. Building that inside n8n is possible, but it means a grid generator, a recursive split, and a lot of API calls billed per request, not per business. Our [120 results limit guide](https://leadraft.co/blog/google-maps-120-results-limit) walks through the method, and [Places API vs scraping](https://leadraft.co/blog/google-places-api-vs-scraping) works through what the API calls cost.

The rest of this guide uses a lead tool's API as the source, so n8n only has to orchestrate. The example is Leadraft's REST API, because its endpoints are documented publicly; the same shape works with any tool that has a "start search, poll, read results" API.

## How do I build the workflow node by node?[#](#how-do-i-build-the-workflow-node-by-node)

The pull version of the workflow has six nodes and runs as one execution. Here it is end to end:

```
Schedule Trigger (or Manual Trigger)
  → HTTP Request: POST /searches          (start the search, keep "group")
  → Wait: 30 seconds
  → HTTP Request: GET /searches/{group}   (check status)
  → If: status is "completed"?
       false → back to Wait
       true  → HTTP Request: GET /leads   (paginated)
             → Google Sheets: Append or Update Row (match on place ID)
```

### Step 1: Create a credential for the API key[#](#step-1-create-a-credential-for-the-api-key)

In Leadraft, create an API key under Settings → API keys. Keys look like `lg_...`. In n8n, create a **Header Auth** credential (one of the HTTP Request node's generic authentication methods) with the name `Authorization` and the value `Bearer lg_your_key`. Every HTTP Request node below uses it. The API allows 120 requests a minute per key, which a polling workflow never gets near.

### Step 2: Start the search[#](#step-2-start-the-search)

Add an **HTTP Request** node:

Scroll horizontally if needed →

| Setting | Value |
| --- | --- |
| Method | POST |
| URL | `https://app.leadraft.co/api/v1/searches` |
| Authentication | Generic credential type → Header Auth |
| Send Headers | `Idempotency-Key`: a unique value, for example the execution ID |
| Body | JSON (below) |

```json
{
  "queries": ["dentist in Phoenix, AZ", "orthodontist in Phoenix, AZ"],
  "email_required": true,
  "scope": "in"
}
```

Each line is its own search, up to 500 lines and 25 locations per request. `scope: "in"` counts only businesses inside the city boundary; `"near"` adds a ring set by `scope_km`. The response returns `201` with a `group` (keep it) and a `failed` array listing any line that couldn't run and why. The `Idempotency-Key` header means a retried node returns the first answer instead of starting the searches twice. A `402` means the account is out of business credits.

Tip: you can paste the curl example from the [API docs](https://leadraft.co/docs/api) into the node with **Import cURL**. Imported values come in as strings, so switch the body to **Using JSON** if you need real booleans.

### Step 3: Wait, then poll the status[#](#step-3-wait-then-poll-the-status)

Add a **Wait** node set to **After Time Interval**, 30 seconds. Then an **HTTP Request** node:

-   Method: GET
-   URL: `https://app.leadraft.co/api/v1/searches/{{ $('Start search').item.json.group }}` (use your node's name)

The response has `status`, which is `running`, `finishing` (searching is done, emails are still being found and checked), `paused` or `completed`, plus `businesses`, `with_email`, `searches_done` and `searches_total`. The docs suggest polling every 10–30 seconds; businesses usually start arriving within minutes.

Add an **If** node: `{{ $json.status }}` equals `completed`. Connect the false branch back to the Wait node. n8n offloads waits of 65 seconds or more to its database, so if you'd rather poll every two minutes on a long search, that's fine too.

Don't treat `finishing` as done: at that stage the businesses are in, but emails are still being checked, and reading early gives you rows without them.

### Step 4: Read the leads, page by page[#](#step-4-read-the-leads-page-by-page)

On the true branch, add an **HTTP Request** node:

Scroll horizontally if needed →

| Setting | Value |
| --- | --- |
| Method | GET |
| URL | `https://app.leadraft.co/api/v1/leads` |
| Query parameters | `search_group` = the group, `grade` = `valid`, `limit` = `500` |
| Pagination | Update a Parameter in Each Request: query `cursor` = `{{ $response.body.next }}` |

`/leads` is keyset-paged: each page returns `items` and a `next` value, which you send back as `cursor`. Set the node to stop when `next` comes back null, which marks the last page. `grade=valid` returns only Verified emails; add a second `grade` parameter with `catch_all` if you want accept-all addresses too (keep them in a separate sheet or campaign). Invalid addresses are never returned.

Then add a **Split Out** node on `items`, so each lead becomes its own n8n item.

One billing detail: reading a Verified address you haven't been charged for uses one checked-email credit, once. If credits run out, the email comes back null with `email_withheld: true`, and it fills in on a later read.

### Step 5: Write to Google Sheets without duplicates[#](#step-5-write-to-google-sheets-without-duplicates)

Add a **Google Sheets** node with the **Append or Update Row** operation, which updates a matching row or adds a new one at the end. Match on the place ID column so re-running the workflow updates businesses instead of duplicating them. Map the columns you'll use: name, email, email grade, phone, website, city, rating, review count.

If you only need a sheet, you can skip n8n entirely: Leadraft's [live feeds](https://leadraft.co/docs/feeds) give you a private CSV link that Google Sheets reads with `=IMPORTDATA(...)` and refreshes about once an hour.

## How do I make n8n receive leads instead of polling?[#](#how-do-i-make-n8n-receive-leads-instead-of-polling)

Use a Webhook node and let the lead tool push. This is the better pattern for monitors, which find new businesses on a schedule and send only the new ones.

1.  Add an n8n **Webhook** node, method POST. Turn on the **Raw Body** option, because the signature is computed over the exact bytes sent. Set **Respond** to **Immediately**.
2.  Activate the workflow and copy the **production** URL. The test URL only works while the editor is listening.
3.  In Leadraft, choose **Webhook** as the destination when you export a segment, or as a monitor's destination, and paste the URL. Optionally generate a signing secret under Settings → Integrations → Webhook.
4.  Verify the signature. Each request carries `X-LeadGrid-Signature: sha256=<hex>`, an HMAC-SHA256 of the raw body keyed with your secret. n8n's **Crypto** node has an Hmac action with SHA256 and HEX encoding; compute it over the raw body, prefix `sha256=`, and drop the request in an **If** node if it doesn't match.
5.  **Split Out** the `leads` array, then write each lead to Sheets, a database or a CRM.

What arrives:

```json
{
  "source": "leadgrid",
  "export_id": 3141,
  "count": 200,
  "leads": [
    {
      "email": "hello@brightsmile.example",
      "email_grade": "valid",
      "business": "Bright Smile Dental",
      "category": "Dentist",
      "phone": "+15125550142",
      "website": "https://brightsmile.example/",
      "city": "Austin",
      "state": "Texas",
      "country": "US",
      "in_area": true,
      "place_id": 48213,
      "google_place_id": "ChIJ…"
    }
  ]
}
```

Rules worth building around:

-   Leads come in **batches of 200**, so one export of 1,000 leads is five requests and five n8n executions.
-   Answer with a `2xx` within 30 seconds. Network errors and `5xx` answers are retried (3 attempts in total); a `4xx` stops the push. "Respond Immediately" keeps you inside the window.
-   A batch can arrive more than once, so **upsert on `place_id`**, never blind-append.
-   Webhooks carry lead batches, not events. There's no "search finished" event yet; to react when a search completes, use the polling loop above.
-   The URL must be public and final: redirects aren't followed and private networks are refused. Self-hosted n8n behind a firewall needs a public tunnel or reverse proxy.

The full payload and field list are in the [webhooks docs](https://leadraft.co/docs/webhooks).

## How do I send the leads from n8n to Instantly or a CRM?[#](#how-do-i-send-the-leads-from-n8n-to-instantly-or-a-crm)

Add one more HTTP Request node per lead. For Instantly, the API v2 call is `POST https://api.instantly.ai/api/v2/leads` with a bearer token, a `campaign` (the campaign's ID), the `email`, and extra fields in `custom_variables`:

```json
{
  "campaign": "your-campaign-id",
  "email": "{{ $json.email }}",
  "company_name": "{{ $json.business }}",
  "website": "{{ $json.website }}",
  "custom_variables": { "city": "{{ $json.city }}", "category": "{{ $json.category }}" },
  "skip_if_in_workspace": true
}
```

Instantly's reference also lists skip flags (`skip_if_in_workspace`, `skip_if_in_campaign`) and a `verify_leads_on_import` flag. Leave verification off for addresses that are already Verified, and keep the skip flag on so the same business isn't emailed from two campaigns. Use the HTTP Request node's batching options (items per batch, batch interval) to stay under Instantly's rate limit.

That said, n8n in the middle only earns its place if you're doing something to the leads on the way: scoring them, writing a first line with an AI node, routing by city. If you just want leads in a campaign, a direct push is fewer moving parts. Our guide to [importing Google Maps leads into Instantly](https://leadraft.co/blog/google-maps-leads-to-instantly) covers the column mapping either way.

## Which pattern should I use?[#](#which-pattern-should-i-use)

Pick by what starts the work.

Scroll horizontally if needed →

| You want | Pattern | n8n nodes |
| --- | --- | --- |
| Run a search on a schedule and collect the results | Pull: start, poll, read | Schedule Trigger, HTTP Request ×3, Wait, If, Google Sheets |
| Get new businesses in a market as they appear | Push from a [monitor](https://leadraft.co/product/monitors) | Webhook, Crypto, If, Split Out, destination |
| Send an existing segment to a custom destination | Push from an export | Webhook, Split Out, destination |
| Just a sheet that stays current | No n8n: live feed | None (`IMPORTDATA` in Sheets) |

## FAQ[#](#faq)

### Does n8n have a Google Maps scraper node?[#](#does-n8n-have-a-google-maps-scraper-node)

Not an official one, as far as we could find in n8n's integrations directory in November 2026. Most n8n Google Maps workflows call the Google Places API with the HTTP Request node, run a third-party scraper (such as an Apify actor) through a community node or HTTP call, or call a lead tool's REST API.

### Why does my n8n Google Maps workflow stop at 60 or 120 results?[#](#why-does-my-n8n-google-maps-workflow-stop-at-60-or-120-results)

Because one Google search is capped. Google's Places API Text Search returns at most 60 results across all pages, and the Maps interface stops at about 120. To get every business in a city you have to split the area into smaller tiles, search each, and dedupe by place ID, or use a source that does that for you.

### Can n8n receive leads from Leadraft automatically?[#](#can-n8n-receive-leads-from-leadraft-automatically)

Yes, through a webhook. Add an n8n Webhook node, copy its production URL, and choose Webhook as the destination when you export a segment or set up a monitor in Leadraft. Leadraft posts the leads as JSON in batches of 200, signed with HMAC-SHA256 if you set a signing secret. There is no native Leadraft node.

### How many n8n executions does a Google Maps leads workflow use?[#](#how-many-n8n-executions-does-a-google-maps-leads-workflow-use)

n8n counts one execution per run of a whole workflow, however many nodes it has. A workflow that starts a search, waits, polls and writes rows is one execution per run. A webhook workflow is one execution per batch it receives.

### Can I send the leads from n8n to Instantly?[#](#can-i-send-the-leads-from-n8n-to-instantly)

Yes. Call Instantly's API (`POST /api/v2/leads` with a campaign ID and the email) from an HTTP Request node, one lead per item. If you don't need n8n in the middle, Leadraft can also push to Instantly directly.

## Sources[#](#sources)

1.  n8n Docs, [HTTP Request node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/) (generic Header Auth, pagination modes, `$response`, batching, Import cURL), seen November 3, 2026.
2.  n8n Docs, [Webhook node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook/) (test vs production URL, Raw Body, Respond options, 16 MB payload), seen November 3, 2026.
3.  n8n Docs, [Wait node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.wait/) (resume options; waits of 65 seconds or more offloaded), seen November 3, 2026.
4.  n8n Docs, [Crypto node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.crypto/) (Hmac with SHA256, HEX encoding).
5.  n8n Docs, [Google Sheets: sheet operations](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googlesheets/sheet-operations/) (Append or Update Row).
6.  n8n Docs, [Install community nodes](https://docs.n8n.io/integrations/community-nodes/installation/) (unverified nodes not available on n8n Cloud).
7.  n8n, [Pricing](https://n8n.io/pricing/) (plans, executions, definition of an execution), seen November 3, 2026.
8.  Google for Developers, [Text Search (New)](https://developers.google.com/maps/documentation/places/web-service/text-search) ("returns a maximum of 60 results across all pages").
9.  Instantly, [API v2: Lead](https://developer.instantly.ai/api-reference/lead) (create lead, campaign, custom\_variables, skip and verify flags).
10.  Leadraft docs: [REST API](https://leadraft.co/docs/api), [webhooks](https://leadraft.co/docs/webhooks), [live feeds](https://leadraft.co/docs/feeds).

## Lead lists for the trades in this article

-   [Dentists email listLeadraft builds a list of dental practices from Google Maps for the area you choose: a city, a county, a ZIP code or a shape you draw.](https://leadraft.co/leads/dentists)
-   [Orthodontists email listLeadraft builds a list of orthodontic practices from Google Maps for the area you choose: braces and clear aligner specialists, pediatric orthodontics, and general dentists who offer Invisalign.](https://leadraft.co/leads/orthodontists)
-   [Lead lists for every industry](https://leadraft.co/leads)

## Keep reading

-   [
    
    November 3, 2026Playbook
    
    ### How to get Google Maps leads into HubSpot: field mapping, dedupe, segments and the rules
    
    Get Google Maps leads into HubSpot: a CSV import with exact property mapping, dedupe by email and domain, segments, a direct push, and HubSpot's email rules.
    
    Read article
    
    ](https://leadraft.co/blog/hubspot-google-maps-leads)
-   [
    
    November 3, 2026Guide
    
    ### Clay and Google Maps: what Clay's Maps source does, where it stops, and how to import a full local list
    
    What Clay's Google Maps source returns, its 1,000-result default and no-website gaps, why teams source outside Clay, and how to import a CSV or webhook feed.
    
    Read article
    
    ](https://leadraft.co/blog/clay-google-maps-leads)
-   [
    
    November 3, 2026Playbook
    
    ### Commercial insurance leads: how agents build their own prospect lists by trade
    
    How commercial P&C agents build their own lead lists of contractors, restaurants and truckers by county, time outreach to renewals, and follow licensing rules.
    
    Read article
    
    ](https://leadraft.co/blog/commercial-insurance-leads)

Last built: 2026-11-09
