Med Spa Lead Scraper — Aesthetics Business Contacts
Pricing
from $50.00 / 1,000 base med spa leads
Med Spa Lead Scraper — Aesthetics Business Contacts
Find med spas, Botox clinics and aesthetics businesses by city. Exclude previous Maps URLs, review public contact and email evidence, and export CSV/JSON/Excel. See the saved demo, redacted sample and prepared n8n/HubSpot starter.
Pricing
from $50.00 / 1,000 base med spa leads
Rating
0.0
(0)
Developer
Sam Kleespies
Maintained by CommunityActor stats
0
Bookmarked
36
Total users
3
Monthly active users
5 days ago
Last modified
Categories
Share
Med Spa & Aesthetics Lead Scraper
Find medical spa and aesthetics businesses by city, collect public business contact details, and export JSON, CSV or Excel. Use excludeMapsUrls from your previous dataset to request businesses outside that list. A bounded repeat search may return fewer new records than requested.
Explore the saved demo and download the sample. One Sacramento search excluded 20 prior listings and returned five records with zero overlap against that saved list. Four records contained email candidates; none was SMTP-verified. The sample hides email values. These are results from one owner-run example, not a promise of future coverage.
The demo includes the search input, a company mapping preview and an inactive n8n/HubSpot starter. It is prepared for your setup and manual testing; no connected HubSpot import has been verified. Read the setup walkthrough.
Start with a small search: open the 3-lead sample configuration, review current pricing, and inspect business fit, email sources and verification evidence before scaling. A business record may have no email, and extracted candidates are not guaranteed deliverable mailboxes. Apify Actor fees and platform usage apply.
Quick start
Choose a business type and location, start with 3–10 results (default: 3), and inspect Full output before scaling. Email extraction is on by default; optional email verification and social enrichment are off. Enable verification when you need DNS/SMTP evidence. For larger runs, set a maximum cost and timeout in Apify. Use HubSpot or Salesforce output as convenient column layouts; your CRM may require field mapping.
Pricing
The current configured events are $50 per 1,000 base med spa leads ($0.05 per result), $20 per 1,000 SMTP-confirmed email leads ($0.02 extra per qualifying result), and $0.01 per Actor-start event. Apify says the number of start events depends on Actor memory (one per GB, minimum one). At 4 GB, that means four start events, or $0.04. Platform usage is charged separately. The live Pricing tab is authoritative and may reflect plan discounts.
| Example | Result event fees | Start fees at 4 GB | Platform usage |
|---|---|---|---|
| 10 base leads, no confirmed email | $0.50 | $0.04 | Extra |
| 100 base leads, 20 confirmed emails | $5.40 | $0.04 | Extra |
| 100 base leads, 60 confirmed emails | $6.20 | $0.04 | Extra |
These are examples, not a prediction of email coverage. Base records are chargeable even when no email is found. A run may incur platform usage even if it produces no results.
Email verification
DNS MX records establish that a domain has mail routing; they do not confirm a particular address. SMTP-confirmed means the server accepted the recipient and rejected a random-recipient probe at check time. It does not guarantee message delivery. Catch-all servers, blocked SMTP connections, temporary DNS problems, and inconclusive replies stay unconfirmed; they never set emailVerified to true or trigger the premium email event. Inspect emailVerificationStatus and emailDomainHasMx in Full output for the distinction. No emails are sent by the check, and no bounce-rate percentage is promised.
Only results with an smtp_verified address qualify for the $0.02 premium event. The premium event is based on the stricter SMTP-confirmed rule.
Inputs and output
Select a business type such as Med Spa, a city or region, and a total maxResults limit. Custom queries use searchQuery. Set enrichEmails, verifyEmails, and enrichSocials as needed; verification applies only to extracted emails. Choose full, hubspot, or salesforce output. An optional proxyUrl replaces the default Apify proxy.
Results include the business name, address, phone, website, rating, review count, Maps URL, extracted emails and verification evidence, and available social links. Public sites may hide contact details or provide only a form. Google Maps coverage varies by search. Use a small test before a bulk job.
The actor publishes completed batches as it enriches them. If it fails or times out, inspect the run log and partial dataset. Review the output before using it for outreach, and follow the rules applicable to your use.
For support, open an issue with a fresh run link, search settings, expected behavior, and observed result. Keep tokens, proxy credentials, and private customer data out of public issues.
Copyable input for your next run
This is a configuration example, not a guaranteed result count. Start small and set a run-cost limit. Change the business type and location to match your segment.
{"businessType": "Botox Clinic","location": "Miami, FL","maxResults": 10,"enrichEmails": true,"verifyEmails": false,"enrichSocials": false,"outputFormat": "full"}
Related business segments
Use the dedicated Lawyer, Dentist, or Med Spa Actor for the segment you serve. Each has a small sample on its Examples tab.
Walkthrough: Med spa business leads to HubSpot companies
This starter workflow connects this Actor to HubSpot company records using n8n. It starts with ten results and uses your own service credentials. The Actor extracts public business information; email availability varies and the template does not send outreach.
1. Check a small sample
Open the prepared sample, review its settings and current Pricing tab, and inspect the resulting names, source URLs and contact fields. A sample run has normal Apify charges; it is not a promise of free data or a fixed number of matches.
2. Import and connect
Copy the workflow JSON below into a local .json file, then use n8n's Import from File. Alternatively paste the copied JSON onto a blank n8n canvas. The template uses built-in nodes and remains inactive.
Create/select an n8n Header Auth credential for your Apify account: header name Authorization, value Bearer YOUR_APIFY_TOKEN. Assign it to Start Actor, Get run, and Get dataset. Keep secrets in credentials, never in workflow JSON or public issues.
In HubSpot, create a Company property with internal name samstorm_maps_url, field type Single-line text, and Require unique values enabled. This property identifies each location by its Google Maps URL, so two locations sharing a website remain separate companies. If your HubSpot account cannot create a unique property, use the manual export option below.
Create/select a separate n8n Header Auth credential for your HubSpot private app: Authorization: Bearer YOUR_HUBSPOT_TOKEN, with the company read/write scopes required by HubSpot. Assign it ONLY to Upsert HubSpot companies, never to an Apify node. The template uses the company batch-upsert API. It writes name and the unique source key, plus nonempty phone, website and address fields. Matching companies may have those values refreshed; review this behavior on a test company first. It does not create contacts, deals, enrollments or messages.
3. Run once and inspect
In Configure, change businessType and location for your market. Keep outputFormat full, which includes verification evidence. Email enrichment is on; SMTP verification and social enrichment are off initially. Enable them only when needed and review the current price.
Click Execute workflow. The Actor starts once, waits for completion, validates the dataset, and exports. Failed/aborted/timed-out runs and empty datasets stop before the destination write. Duplicate Maps URLs within a batch are removed. HubSpot upserts by the unique Maps URL property. It merges repeated identical URLs, not every possible URL variant for the same real business.
Check your first exported rows against the Apify dataset. Do not interpret MX records, catch-all results or an unconfirmed SMTP check as a verified mailbox. The template marks emailVerified true only when the Actor also reports smtp_verified. No mailbox check guarantees delivery.
4. Repeat without avoidable costs
If export fails after scraping succeeded, copy the 17-character run ID from the Apify run page into existingRunId and execute again. This retries export without launching another paid scrape. Leave it blank when you want a fresh search. The template retrieves up to 101 records and fails above 100; use pagination before scaling beyond 100. Do not point it at a larger historical dataset expecting complete export.
For new prospects, rotate the city or business segment. Repeated searches can return the same listings. Destination deduplication does not make repeated scraping free.
Only after a successful manual test, optionally replace Manual start with an n8n Schedule Trigger. Choose your timezone and cadence, publish the workflow, prevent overlapping executions, and set a monthly budget. Keep existingRunId blank for fresh scheduled searches. Configure an n8n Error Workflow/notification for failed executions. This starter does not create a schedule or send alerts automatically.
Costs and compatibility
Each fresh execution can incur Actor result fees, applicable enrichment fees and separately billed Apify platform usage, plus any n8n/destination subscription costs. The default $2 maxTotalChargeUsd limits Actor event charges, not separately billed platform usage. The Actor timeout is 600 seconds; n8n execution timeout is 900 seconds. Consult the current Pricing tab before scaling.
The template uses HTTP Request 4.2, Code 2, IF 2.2, Wait 1.1. Local tests cover mapping and failure handling; a complete run against your own n8n and HubSpot credentials is required before production use.
Manual export alternative
Run the Actor with full output, open the dataset, and export CSV or Excel. For HubSpot’s manual company import wizard, choose the Actor’s hubspot output format and review the mapping. Business emails are not automatically HubSpot person/contact records. Preserve Maps URLs as source evidence.
Troubleshooting
- 401/403: check which service's credential is selected and its permissions.
- No leads / source failure: inspect the Apify run log and OUTPUT_SUMMARY; try a narrower, known location.
- Destination error: fix the destination and retry using existingRunId.
- Unexpected duplicates: compare Maps URLs, and avoid concurrent writes. Confirm the HubSpot property requires unique values.
- Need help: open an Actor issue with the run link, business type, location and expected/actual behavior. Do not include tokens or private customer data.
References: n8n workflow import, Apify API, HubSpot upsert.
Importable n8n workflow JSON
{"name":"Med spa business leads to HubSpot companies | samstorm","nodes":[{"name":"Manual start","id":"manual-start","type":"n8n-nodes-base.manualTrigger","typeVersion":1,"position":[0,300],"parameters":{}},{"name":"Configure","id":"configure","type":"n8n-nodes-base.code","typeVersion":2,"position":[220,300],"parameters":{"jsCode":"// Edit these values. Existing run ID reuses results without starting a new paid run.\nconst config={\n \"actorId\": \"DZ2im6CoOrIqye8aJ\",\n \"existingRunId\": \"\",\n \"sheetDocumentId\": \"\",\n \"sheetName\": \"Leads\",\n \"actorInput\": {\n \"businessType\": \"Med Spa\",\n \"location\": \"Miami, FL\",\n \"maxResults\": 10,\n \"enrichEmails\": true,\n \"verifyEmails\": false,\n \"enrichSocials\": false,\n \"outputFormat\": \"full\"\n },\n \"maxActorEventChargeUsd\": 2,\n \"timeoutSeconds\": 600\n};\nif(!Number.isInteger(config.actorInput.maxResults) || config.actorInput.maxResults<1 || config.actorInput.maxResults>100) throw new Error('Set maxResults between 1 and 100.');\nif(config.actorInput.outputFormat!=='full') throw new Error('Keep outputFormat full for this mapping.');\nif(config.existingRunId && !/^[a-zA-Z0-9]{17}$/.test(config.existingRunId)) throw new Error('Enter the 17-character Apify run ID, not a URL.');\nreturn [{json:config}];"}},{"name":"Reuse existing run","id":"reuse-existing-run","type":"n8n-nodes-base.if","typeVersion":2.2,"position":[440,300],"parameters":{"conditions":{"options":{"caseSensitive":true,"leftValue":"","typeValidation":"strict","version":2},"conditions":[{"id":"Reuse existing run","leftValue":"={{ !!$json.existingRunId }}","rightValue":"","operator":{"type":"boolean","operation":"true"}}],"combinator":"and"},"options":{}}},{"name":"Start Actor","id":"start-actor","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[660,440],"parameters":{"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","options":{"timeout":75000,"response":{"response":{"responseFormat":"json"}}},"method":"POST","url":"=https://api.apify.com/v2/actors/{{ $json.actorId }}/runs","sendQuery":true,"queryParameters":{"parameters":[{"name":"build","value":"latest"},{"name":"waitForFinish","value":"60"},{"name":"timeout","value":"={{ $json.timeoutSeconds }}"},{"name":"memory","value":"4096"},{"name":"maxTotalChargeUsd","value":"={{ $json.maxActorEventChargeUsd }}"}]},"sendBody":true,"specifyBody":"json","jsonBody":"={{ $json.actorInput }}"},"retryOnFail":false,"maxTries":3,"waitBetweenTries":2000,"notes":"Choose your own Header Auth credential. Authorization: Bearer YOUR_TOKEN. Never embed tokens in this template.","notesInFlow":false},{"name":"Get run","id":"get-run","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[660,140],"parameters":{"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","options":{"timeout":75000,"response":{"response":{"responseFormat":"json"}}},"url":"=https://api.apify.com/v2/actor-runs/{{ $json.runId || $('Configure').first().json.existingRunId }}","sendQuery":true,"queryParameters":{"parameters":[{"name":"waitForFinish","value":"60"}]}},"retryOnFail":true,"maxTries":3,"waitBetweenTries":2000,"notes":"Choose your own Header Auth credential. Authorization: Bearer YOUR_TOKEN. Never embed tokens in this template.","notesInFlow":false},{"name":"Validate run","id":"validate-run","type":"n8n-nodes-base.code","typeVersion":2,"position":[880,300],"parameters":{"jsCode":"const r=$input.first().json.data;\nconst config=$('Configure').first().json;\nif(!r || !/^[a-zA-Z0-9]{17}$/.test(r.id || '') || r.actId!==config.actorId) throw new Error('Unexpected Apify run response or wrong Actor. No records exported.');\nif(!['READY','RUNNING','SUCCEEDED'].includes(r.status)) throw new Error('Apify run '+r.id+' ended '+r.status+'. Inspect its log and partial dataset; no CRM write performed.');\nif(r.status==='SUCCEEDED' && !/^[a-zA-Z0-9]{17}$/.test(r.defaultDatasetId || '')) throw new Error('Succeeded run has no valid dataset ID.');\nreturn [{json:{runId:r.id,datasetId:r.defaultDatasetId || '',complete:r.status==='SUCCEEDED'}}];"}},{"name":"Run succeeded","id":"run-succeeded","type":"n8n-nodes-base.if","typeVersion":2.2,"position":[1100,300],"parameters":{"conditions":{"options":{"caseSensitive":true,"leftValue":"","typeValidation":"strict","version":2},"conditions":[{"id":"Run succeeded","leftValue":"={{ $json.complete }}","rightValue":"","operator":{"type":"boolean","operation":"true"}}],"combinator":"and"},"options":{}}},{"name":"Wait before next check","id":"wait-before-next-check","type":"n8n-nodes-base.wait","typeVersion":1.1,"position":[1100,100],"parameters":{"amount":15,"unit":"seconds"}},{"name":"Get dataset","id":"get-dataset","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[1320,300],"parameters":{"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","options":{"timeout":60000,"response":{"response":{"responseFormat":"json","fullResponse":true}}},"url":"=https://api.apify.com/v2/datasets/{{ $json.datasetId }}/items","sendQuery":true,"queryParameters":{"parameters":[{"name":"format","value":"json"},{"name":"clean","value":"true"},{"name":"limit","value":"101"}]}},"retryOnFail":true,"maxTries":3,"waitBetweenTries":2000,"notes":"Choose your own Header Auth credential. Authorization: Bearer YOUR_TOKEN. Never embed tokens in this template.","notesInFlow":false},{"name":"Validate and map leads","id":"validate-and-map-leads","type":"n8n-nodes-base.code","typeVersion":2,"position":[1540,300],"parameters":{"jsCode":"const payload=$input.first().json;\nconst rows=payload.body;\nif(!Array.isArray(rows)) throw new Error('Expected a JSON dataset array. Check the Get dataset node response settings.');\nif(!rows.length) throw new Error('No leads returned. Review the Apify log and OUTPUT_SUMMARY before changing the search.');\nif(rows.length>100) throw new Error('This starter workflow supports at most 100 records; use dataset pagination for larger runs.');\nconst seen=new Set();\nconst result=[];\nconst runId=$('Validate run').last().json.runId;\nconst text=v=>typeof v==='string'?v.trim():'';\nfor(const row of rows){\n const name=text(row.name), mapsUrl=text(row.mapsUrl).split('#')[0];\n if(!name || !/^https:\\/\\/(?:[a-z0-9-]+\\.)?google\\.[a-z.]+\\/maps(?:\\/|\\?)/i.test(mapsUrl)) throw new Error('A record lacks a business name or valid Google Maps source. Nothing in this batch was exported.');\n if(seen.has(mapsUrl)) continue;\n seen.add(mapsUrl);\n const status=text(row.emailVerificationStatus);\n const email=text(row.email);\n result.push({json:{mapsUrl,name,category:text(row.category),address:text(row.address),phone:text(row.phone),website:text(row.website),email,\n emailVerified:!!email && row.emailVerified===true && status==='smtp_verified',\n emailVerificationStatus:status || (email?'not_checked':'no_email'),emailVerificationNote:text(row.emailVerificationNote),\n emailDomainHasMx:typeof row.emailDomainHasMx==='boolean'?row.emailDomainHasMx:'',\n rating:typeof row.rating==='number'?row.rating:'',reviewCount:typeof row.reviewCount==='number'?row.reviewCount:'',sourceRunId:runId,capturedAt:new Date().toISOString()}});\n}\nreturn result;"}},{"name":"Build company batch","id":"build-company-batch","type":"n8n-nodes-base.code","typeVersion":2,"position":[1760,300],"parameters":{"jsCode":"const inputs=$input.all().map(({json:r})=>{\n const properties={samstorm_maps_url:r.mapsUrl,name:r.name};\n for(const key of ['phone','website','address']) if(r[key]) properties[key]=r[key];\n return {id:r.mapsUrl,idProperty:'samstorm_maps_url',properties};\n});\nif(!inputs.length || inputs.length>100) throw new Error('Expected 1–100 company records.');\nreturn [{json:{inputs}}];"}},{"name":"Upsert HubSpot companies","id":"upsert-hubspot-companies","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[1980,300],"parameters":{"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","options":{"timeout":75000,"response":{"response":{"responseFormat":"json"}}},"method":"POST","url":"https://api.hubapi.com/crm/v3/objects/companies/batch/upsert","sendBody":true,"specifyBody":"json","jsonBody":"={{ $json }}"},"retryOnFail":false,"maxTries":3,"waitBetweenTries":2000,"notes":"Choose your own Header Auth credential. Authorization: Bearer YOUR_TOKEN. Never embed tokens in this template.","notesInFlow":false},{"name":"Check HubSpot result","id":"check-hubspot-result","type":"n8n-nodes-base.code","typeVersion":2,"position":[2200,300],"parameters":{"jsCode":"const r=$input.first().json;\nconst expected=$('Build company batch').first().json.inputs.length;\nif(r.status!=='COMPLETE' || (r.numErrors || 0)>0 || (r.errors || []).length || !Array.isArray(r.results) || r.results.length!==expected) throw new Error('HubSpot returned an incomplete batch. Inspect this response before retrying with the existing Apify run ID.');\nreturn [{json:{status:'exported',companies:r.results.length,runId:$('Validate run').last().json.runId}}];"}},{"name":"Setup and limits","id":"setup-and-limits","type":"n8n-nodes-base.stickyNote","typeVersion":1,"position":[0,-300],"parameters":{"content":"## Med spa business leads to HubSpot companies\n1. Read the setup walkthrough on the Actor README.\n2. Assign YOUR Apify Header Auth to the three Apify HTTP nodes.\n3. Create a unique company property samstorm_maps_url in HubSpot. Assign YOUR separate HubSpot Header Auth to Upsert HubSpot companies.\n4. Review Configure, then test manually.\n\nDefaults: 10 results, verification off, 600-second Actor timeout. $2 is an Actor-event charge limit; separately billed platform usage still applies. Failed/empty runs stop export.\n\nTo retry export after a destination error, set existingRunId. Do not restart the Actor unnecessarily.\n\nNo automatic schedule. Prevent concurrent executions against the same destination.\nValidation: local control-flow/mapping tests; customer credential setup and live destination test required.","width":560,"height":520}}],"connections":{"Manual start":{"main":[[{"node":"Configure","type":"main","index":0}]]},"Configure":{"main":[[{"node":"Reuse existing run","type":"main","index":0}]]},"Reuse existing run":{"main":[[{"node":"Get run","type":"main","index":0}],[{"node":"Start Actor","type":"main","index":0}]]},"Start Actor":{"main":[[{"node":"Validate run","type":"main","index":0}]]},"Get run":{"main":[[{"node":"Validate run","type":"main","index":0}]]},"Validate run":{"main":[[{"node":"Run succeeded","type":"main","index":0}]]},"Run succeeded":{"main":[[{"node":"Get dataset","type":"main","index":0}],[{"node":"Wait before next check","type":"main","index":0}]]},"Wait before next check":{"main":[[{"node":"Get run","type":"main","index":0}]]},"Get dataset":{"main":[[{"node":"Validate and map leads","type":"main","index":0}]]},"Validate and map leads":{"main":[[{"node":"Build company batch","type":"main","index":0}]]},"Build company batch":{"main":[[{"node":"Upsert HubSpot companies","type":"main","index":0}]]},"Upsert HubSpot companies":{"main":[[{"node":"Check HubSpot result","type":"main","index":0}]]}},"active":false,"settings":{"executionOrder":"v1","executionTimeout":900,"saveDataErrorExecution":"all","saveDataSuccessExecution":"none"},"pinData":{},"tags":[]}
Email source and association checks — October 2026
Full output now includes emailSource, emailDomainRelationship and emailNeedsReview; each item in allEmails keeps its source URL and extraction method. The crawler reads published text and email links, removes hidden templates and placeholder addresses, and follows at most two additional contact/about links. It retains the actual website path supplied by Maps. Static pages that block requests or require JavaScript can still hide contacts.
same_domain means the email domain matches the website host or a subdomain. public_mailbox_provider preserves addresses such as Gmail and Yahoo; other_domain can be a parent company, vendor or unrelated contact. Both require source review. These labels do not verify business ownership, permission or deliverability. SMTP status remains a separate check. Full output is recommended for evidence review before CRM import.
emailPurpose flags obvious press, recruitment and privacy mailbox names. These specialized addresses remain in the evidence but are ranked below ordinary contacts and require review. This is a name-based heuristic, not a guarantee of recipient role.
Search completeness
The scanner waits for business fields, keeps Maps feed layout intact and scans at most twice the requested result count plus the number of entries in both exclusion lists, capped at 500 candidates. If the Actor event budget allows fewer results, that smaller affordable count replaces the requested count in this formula. It returns up to maxResults complete records, with at least two of address, phone and website. A US City, ST request checks the detailed address locality; broader regions keep Google's search scope. Inspect MAPS_SCAN_SUMMARY in run storage for exclusions, detail failures and partial results. A small result set may reflect source coverage or a time limit.
Choosing a branch email
The primary email now favors explicit locality evidence from the published mailbox or a single-mailbox contact block. For businesses with several same-domain branch mailboxes and no matching evidence, the Actor leaves the primary email empty instead of choosing alphabetically. All discovered emails and their source evidence remain available in full output.
Full output includes emailSelectionStatus, emailLocationEvidence, and emailNeedsReview. A locality match is a heuristic based on the public page, not proof of branch ownership or deliverability. General company mailboxes may still require branch review. Simple CRM exports use the same conservative primary selection. Existing inputs and pricing are unchanged.
October reliability update
Exact-business searches that open a Google Maps place page can now return that business without requiring a search-results feed. Location matching and exclusions still apply where configured. The scanner stops opening more detail pages after three consecutive navigation failures, preserving completed records. A source failure is not reported as a confirmed empty search. These controls limit repeated failed work; they do not guarantee lower costs or complete coverage.
Address evidence when selecting emails
A bounded contact block containing a matching street number, street-name prefix and ZIP code can now take precedence over a city-only hint (address_evidence_match). A city appearing only in the business name is not enough. Company-wide contacts and candidates without location evidence are flagged for review. These are association hints, not mailbox verification or a guarantee of branch ownership.
Repeat runs: request businesses you have not collected
Set excludeMapsUrls to the mapsUrl values from a previous full-format dataset, then rerun the same search with your desired maxResults. Supported Maps URL variants are matched using stable place identifiers. Known listings are skipped before detail retrieval when possible and are checked again before website enrichment, dataset output and the optional verified-email event. Excluded records do not create new result events, but scanning still uses platform/proxy resources.
For records with no usable Maps URL, excludeBusinessKeys accepts business:normalized name|normalized address: lowercase the name and address, trim their ends and collapse whitespace. For example, business:example med spa|12 main st, miami, fl 33101. Address-based exclusion may require loading a detail page first.
A repeat search scans beyond known listings within the existing time budget and a 500-candidate ceiling. It may return fewer new records than requested; it is not proof that the territory is exhausted. Check MAPS_SCAN_SUMMARY and OUTPUT_SUMMARY in the run's key-value store for exclusions, incomplete scans and the result count.
