A spreadsheet is a convenient handoff between business research and human review. The difficult part is keeping repeated searches and failed writes from turning that handoff into duplicate rows.
This guide connects the G Maps Crawl Search API to Google Sheets through Make's generic HTTP module. It starts with one category, one location, and one page. A persistent Place ID index controls whether a returned listing creates a row or updates an existing one.
This is a configuration walkthrough, not a downloadable or account-tested Make blueprint. The example payload is fictional. Build the mapping in a separate test scenario and spreadsheet before allowing real records into a working research list.
Set a small request budget
Use an API workspace and a key with scrapes:write. Online and Extension allowances are separate from API usage. If your workspace offers test credentials, use them first and label their simulated output. Test keys use zero request units; a successful live page uses one, including an empty result.
The REST operation is synchronous: POST /api/v1/search returns data.businesses in the same response. There is no G Maps Crawl job to poll or webhook to configure for this workflow. A page contains at most 20 businesses, and supported page numbers run from 1 to 10.
Start with page one only. Keep scheduling off while you build. Make usage and Google Sheets limits are separate from your API request allowance; one page can produce multiple downstream module operations.
Prepare the destination and a persistent index
Create a dedicated worksheet named Businesses. Use these headers, keeping source identifiers and provenance beside the fields your team will review:
Place ID | Business ID | Name | Category | Address | Phone | Website
Rating | Review Count | Maps URL | Observed At | Source Query | Source Page
Connect the Google Sheets account that can write this worksheet. Keep a separate test worksheet for fixture records. In the mapping below, place refers to the object inside each business returned by G Maps Crawl.
Create a Make data store named business_sheet_index. Give its records a Place ID key and these fields: status as text, row_number as number, and spreadsheet_id and sheet_name as text. Use pending and ready for status.
Make's data-store modules can check whether a key exists, retrieve its record, and add or replace records. This index must persist between runs; a temporary scenario variable does not prevent duplicates next week.
Use a dedicated, initially empty worksheet. Existing rows need an index backfill before this workflow can safely manage them. Do not sort, insert, or delete physical rows in the managed worksheet; use a separate presentation tab for alternate ordering. Saved row numbers can otherwise point at a different business.
Configure HTTP: Make a request
Add HTTP > Make a request, using the current HTTP app rather than the legacy version. Configure its API-key credentials with a name such as G Maps Crawl API, Key set to Bearer YOUR_API_KEY, placement in the header, and parameter name Authorization. Use Make's protected credential field; do not put the secret in a query string or ordinary scenario variable. See Make's API-key authentication instructions.
Use these request settings:
| Setting | Value |
|---|---|
| URL | https://gmapscrawl.com/api/v1/search |
| Method | POST |
| Body content type | application/JSON |
| Body input method | Data structure |
| Parse response | Yes |
| Pagination type | Leave empty for this one-page workflow |
| Timeout | 180 seconds |
| Return error if HTTP request fails | Yes |
| Allow redirects | No |
Add a non-secret Idempotency-Key header with one 16–128-character identifier for this intended page, such as make-ballard-20261218-page01-batch01. Keep it unchanged when retrying that body. Create a new identifier when intentionally starting a new search or changing its arguments.
Build the JSON data structure with these typed values:
{
"q": "restaurants in Ballard Seattle",
"page": 1,
"hl": "en",
"extra": false
}
Use a number for page and a boolean for extra. Make's HTTP documentation explains structured JSON input and parsed responses. Keeping the first request fixed makes its body and retry identity easy to inspect.
Learn the response mapping with a fixture
Before connecting a live request to Sheets, add JSON > Parse JSON in a temporary test path. Paste this reduced, fictional response and generate its data structure:
{
"data": {
"total": 1,
"params": {
"q": "restaurants in Ballard Seattle",
"page": 1,
"hl": "en",
"extra": false
},
"simulated": true,
"businesses": [{
"businessId": "11111111-1111-4111-8111-111111111111",
"place": {
"placeId": "fixture-place-001",
"name": "Example Ballard Restaurant",
"category": "Restaurant",
"address": {"formatted": "100 Example Street, Seattle"},
"phone": "+1 206-555-0100",
"website": null,
"rating": 4.2,
"reviewCount": 17,
"mapsUrl": null,
"observedAt": "2026-10-23T00:00:00Z",
"fieldStates": {"website": "not_found"}
}
}]
},
"request_id": "req_fixture_only"
}
This fixture teaches field paths; it is not the complete API schema. Run only that test path while its writes target the test worksheet. For production, use the parsed HTTP response and block data.simulated = true before any working-sheet write. Simulated records should never silently enter a real prospect queue.
Add Flow Control > Iterator and map its Array to the parsed response's data.businesses. Make may display an outer response-body collection around this JSON; follow its actual output tree rather than assuming a module number. The Iterator emits one bundle per array item. An empty array produces no business writes.
Map one business into one row
After the Iterator, filter out records without a Place ID into a separate manual-review path. Preserve their raw response and businessId; do not invent a matching key from a name or phone number.
Use these mappings in both Google Sheets write branches:
| Sheet column | Iterator field or request context |
|---|---|
| Place ID / Business ID | place.placeId / businessId |
| Name / Category | place.name / place.category |
| Address | place.address.formatted |
| Phone / Website | place.phone / place.website |
| Rating / Review Count | place.rating / place.reviewCount |
| Maps URL / Observed At | place.mapsUrl / place.observedAt |
| Source Query / Source Page | The request's q / page |
Select Raw as the value input option. This preserves phone and identifier strings and prevents source text beginning with = from being evaluated as a formula. Leave unknown fields blank, preserve a numerical zero, and keep raw JSON for place.fieldStates and other nested details. Make documents both Add a Row and Update a Row.
Route new and existing Place IDs separately
Add Data store > Check the Existence of a Record, using the incoming Place ID as key, then a Router:
- Exists is false: write an index record with
status = pending, the destination spreadsheet and sheet, and no row number. Then use Google Sheets > Add a Row. On confirmed success, store its returned row number and set the index record toready. - Exists is true: retrieve the index record. If its destination matches, status is
ready, and its saved row still contains this Place ID, use Update a Row with the saved row number. Verify that identity cell using Get a Cell before updating. Otherwise stop this record for reconciliation.
Use mutually exclusive existence filters. A Router branches by filters; ordering two unconditional routes would not turn them into an if/else. A pending record must never fall through into another append.
This design keeps one current row per indexed Place ID. It does not promise a distributed transaction across Make and Google Sheets. A crash between creating the pending marker and adding a row leaves a recoverable pending item rather than silently assuming completion.
Resolve uncertain writes before replaying
If Add a Row times out, the row might already exist. Leave its index entry pending and pause recovery of that write. Search the worksheet for the exact Place ID using Search Rows: one matching row lets you repair the index; multiple matches require deduplication; no match requires confirming the previous write finished before intentionally appending again. Do not use Search Rows (advanced) for a row-number repair because it does not return row numbers.
In scenario settings, enable Commit after each module so the pending marker persists before Sheets writes, plus Process data in order and Store incomplete executions. Keep this scenario as the sole writer. These settings do not reverse completed Sheets writes.
Attach a Commit error handler to Add a Row, with automatic completion disabled, to retain prior state and stop for reconciliation. Do not resume directly at that append until its outcome is resolved. Review Make's automatic retries; an uncertain append must not replay automatically. For a search timeout, preserve its body and key; for HTTP 429, honor Retry-After. Stop on authentication, validation, quota, and capability errors.
Review the sample before turning on a schedule
Test the fixture twice: the second pass should update its indexed row. Also test a missing Place ID and a deliberately pending index record. Neither should append automatically. Inspect both the worksheet and execution bundles before connecting live data. These are acceptance checks to perform in your account, not claims that this scenario has already passed them.
A later scheduled version needs durable request records containing each batch's body, page, idempotency key, and completion state before HTTP runs. Replaying a batch reuses that record; a genuinely new batch gets a new key. Do not generate a replacement key inside a retry path. Add pagination only with an explicit page budget, distinct keys per page, and a stop after an empty response.
Finally, preserve observation time. Query responses may be reused for 24 hours, empty results for one hour; complete Maps details can be up to 730 days old, and contacts have a separate seven-day window. extra: false requests no additional email/social enrichment. A blank website is unknown, not proof of a website opportunity. Read the business-field guide before qualifying rows.
Once the one-page flow is understood, your team has a research sheet with stable identities and explicit recovery rules. Prepare your API access and keep the initial run small enough to review row by row.



