From search to your workflow.
Practical setup steps, real API fields and clear limits. Start small, inspect your list, then connect your tools.
What works today
Reviewed 13 October 2026 against the current code and live beta. Real Philippine province/country jobs and Excel, CSV and JSON downloads have been tested on Azure. Examples below are request instructions or schema descriptions, not invented business results.
Third-party setup recipes were checked against official documentation. They have not been run inside your n8n, Make, Zapier, HubSpot or Sheets accounts. Your account permissions, mapping and any platform fees still apply. LeadMaps adds no connector surcharge; collection credits still apply.
| Connection | Current availability | Verification |
|---|---|---|
| Cloud collections / exports | Available | Real Azure collections and private exports verified. |
| REST API | Available with a scoped key | Saved results, auth and export workflow verified against the service. |
| Codex MCP | Local stdio bridge; source installation required | Protocol/tools tested. No hosted /mcp endpoint or public package. |
| GoHighLevel | Implemented, disabled in live beta | Mapping tested locally; real GHL account sync not verified. |
| n8n / Make / Zapier | Generic HTTP recipes | No native LeadMaps node/app; destination-account execution not verified. |
| HubSpot / Sheets | File import | Real export files generated; destination mapping/import required. |
| Webhooks | Beta implementation | Use polling; retry scheduling limitation described below. |
| ChatGPT | Planned | Hosted OAuth integration and directory publication unavailable. |
Your first collection
Start with 5–10 leads and inspect their source links, location and contacts before expanding. Maximum leads is a cap, not a promise of that many matches. No exhaustive coverage, speed or email hit-rate guarantee is made.
- Sign in with Google. A new account receives 50 one-time collection credits; existing accounts keep their balance. Paid checkout is closed during beta.
- Open New collection. Choose one to eight categories, use the examples or specify your own. Categories are search terms; result classification is not a strict industry taxonomy guarantee.
- Choose country and scope: whole country, province/state or city. Only the chosen scope needs those location fields. US city/region searches also need a valid state.
- For each detail choose Don’t collect, Include when available, or Require on every lead. Required phone excludes records without phone; the same rule applies to website, email, socials and rating.
- Set Maximum leads within your available credits. Review scope, categories, required contacts and maximum charge before confirming.
- Follow actual counts in Collections. Closing the browser does not stop the job. Cancellation is processed when the worker next checks; completed records remain saved.
- Open All businesses, choose a list, search/filter/sort, optionally select rows, then preview/export. Edit notes, tags and workflow status beside your leads.
Search fields and coverage
Country searches combine a bounded set of location queries. They are not exhaustive, statistically random or geographically balanced. Source-address/country/region matching excludes uncertain results. Review a small sample for ambiguous names and non-Latin locations.
Contact extraction visits the listed public website and up to two relevant contact/about pages within a budget. Access restrictions stop extraction. Social links come from available source/website content; no logged-in social scraping. Contacts remain found/unverified: no deliverability check or consent guarantee.
Website can be a social page. Phone normalization preserves international prefixes when possible; some source numbers remain unchanged. Source category and business status can be incomplete. Review closed businesses yourself before use.
| Request field | Accepted values / behavior |
|---|---|
| categories / category | categories: 1–8 strings, each 2–100 characters; duplicates removed. Or category: a single string. |
| scope / country | scope: country, region, city. country: uppercase two-letter code, e.g. PH, US, GB, AU, DE, JP. |
| city / region | city required for city scope; region required for region scope. US non-country searches require a valid state name/code. Omit both for country scope. |
| limit | Integer 1–10,000; must fit available credits. A processing/delivery maximum. |
| fields | At least one of phone, website, email, socials, rating. Unselected optional details are removed from delivered records. |
| requiredFields | Subset of fields; all must be present for delivery. Empty array allows missing optional details. |
| preset | all, no-website, has-phone, has-email, rating. Required website conflicts with no-website. rating alone does not define a threshold. |
| minRating / maxReviewCount | Optional numeric thresholds: 0–5 rating / nonnegative integer review count. Missing corresponding values fail the filter. |
| confirmed / excludeChains | confirmed must be true after review. Automatic chain exclusion unavailable: omit excludeChains or set false. |
Record field dictionary
| Field | Type / meaning |
|---|---|
| id / placeId | Stable record string id; placeId string or null. Use id for downstream deduplication. |
| name / category / address / city / country | Strings; category/address/city may be empty. Country is a two-letter code. |
| state / postalCode | String or null. Postal codes remain text, including leading zeros. |
| latitude / longitude | Number or null from source; not a live location tracker. |
| phone / website | String or null; unselected values removed. |
| emails / socials | String arrays; [] when unavailable or not selected. |
| contactSources | Array of {value,url,verification:'unverified'}; email provenance, not verification. |
| rating / reviewCount | Number or null. Zero/unrated source rating becomes null; present rating is 1–5. |
| sourceUrl / collectedAt / businessStatus | Listing link or null, ISO timestamp string, source status or unknown. |
| completeness | Number: phone 30 + website 30 + any email 30 + address 10, based on delivered fields. Not buyer intent. |
| locationStatus | matched / uncertain. Uncertain matches excluded from delivery. |
| status / tags / notes / list | Editable workflow fields. Status: New, Reviewing, Contacted, Qualified, Archived; tags: string array; notes/list: strings. |
Credits and job states
One credit buys one unique business delivered within the confirmed job. Missing optional email still counts; missing required details excludes the record. Reserve the maximum before starting and release unused credits when the job ends. Duplicates/retries within that job do not charge again.
One queued/running job per workspace. No automatic overage. Viewing saved results and re-exporting do not consume collection credits; an explicit fresh collection is a new operation.
Proposed paid-plan rules: expiring monthly credits consumed before non-expiring prepaid credits; monthly credits reset without rollover. Purchases are not enabled yet.
Counts: discovered, accepted, duplicates, excluded and incomplete (completeness below 100). Strict requirements can deliver zero leads within the search budget.
| State | Next step |
|---|---|
| queued / running | Keep job id; poll at a reasonable interval, e.g. 10–15 seconds. Do not submit another collection to check progress. |
| completed | Requested cap delivered; read/export results. |
| partial | Some results saved; inspect error/counts and released credits. |
| cancelled | Cancellation processed; completed results remain. |
| failed | Read error and credits. Correct the cause before a new search with a new request key. |
Exports and templates
Excel has frozen headers, filters, alternating rows and a Read me sheet. A Contact sources sheet is included except for Calling List and CRM Import. Phones/postal codes remain text; dates use date cells.
CSV is UTF-8 with a BOM and protects formula-like values with a leading apostrophe, including + phone prefixes. Prefer XLSX/JSON for exact phone text. JSON contains schemaVersion, generatedAt, count and records, with arrays and nulls preserved.
Exports follow filters/sort and selected records. Hiding workspace columns does not customize template columns. Generated files expire after seven days; authenticated links expire after five minutes. Regenerate from saved results when needed. Inactive free-account datasets may be removed after 30 days; see Privacy.
| Template | Actual contents |
|---|---|
| Clean Lead List | Business/category/location/contact columns, rating/reviews/completeness, status/list/tags/notes, source and collection time. |
| Calling List | Business name, Phone, City, Status, Notes. |
| Agency Prospecting | Website/email/phone, rating/reviews/completeness, business status/category/location, tags/status/notes/source. |
| CRM Import | Company Name, Phone, first Email, Website, Address, City, State, Postal Code, Country, comma-separated Tags. |
| Complete Data | Choose JSON for full records. JSON always returns full schema regardless of template. CSV/XLSX with this template use standard flat columns. |
API: authenticate and create a job
Base URL: https://leadmaps.live/api/v1. All authenticated clients share a 180-request/60-second workspace limit. Never put your key in browser code, query strings or public repositories. Use your automation platform’s private credential storage.
For whole-country searches use scope: country and omit city/region. City scope requires city (e.g. Tuguegarao City), with region to disambiguate (e.g. Cagayan); US city scope must include a valid state.
- Workspace → Integrations → API keys & Codex. Name the key and choose minimum scopes. read, collect, export are selected by default; write/integrations are opt-in. Copy once and keep it private. Revoke unused keys from this screen.
- First test GET https://leadmaps.live/api/v1/me with Authorization: Bearer KEY. It returns identity, available/monthly/reserved credits, verified, googleConnected, liveEnabled, paidEnabled and ghlEnabled. No collection charge.
- Review the JSON search below. POST /jobs with Content-Type: application/json, Authorization, and Idempotency-Key. This example reserves up to 10 credits. Keep the returned job id.
- Retry the exact same submission with the same request key; use a new key for a different search. Changed parameters under an existing key return 409. Poll GET /jobs/{id} until terminal.
# Bash: set LEADMAPS_API_KEY privately first.
curl 'https://leadmaps.live/api/v1/me' \
-H "Authorization: Bearer $LEADMAPS_API_KEY"
# Windows PowerShell: use a privately configured environment variable.
$headers = @{ Authorization = "Bearer $env:LEADMAPS_API_KEY" }
Invoke-RestMethod 'https://leadmaps.live/api/v1/me' -Headers $headers
# Job request (review before sending)
POST https://leadmaps.live/api/v1/jobs
Authorization: Bearer YOUR_PRIVATE_KEY
Content-Type: application/json
Idempotency-Key: your-reviewed-isabela-request-001
{
"categories": ["Restaurants", "Coffee shops"],
"scope": "region", "country": "PH", "region": "Isabela",
"limit": 10, "fields": ["phone", "website", "email", "rating"],
"requiredFields": ["phone"], "preset": "all", "confirmed": true
}API endpoint reference
All paths follow /api/v1. Replace {id} with your resource id. Job/webhook ids are UUIDs; lead ids are record identifiers. Mutation bodies are JSON. Keys are managed only from the signed-in browser, not another API key.
| Method / path | Scope | Body / response |
|---|---|---|
| GET /me | read | Identity, credits and feature flags. |
| POST /preview | read | {prompt:string}; returns parsed suggestions, no reservation. Not full scope validation. |
| POST /jobs | collect | Confirmed search + Idempotency-Key; returns job object including id/status (201). |
| GET /jobs | read | Latest 100 workspace jobs, newest first (array). |
| GET /jobs/{id} | read | Owned job object, stage/counts/error/dates/spec. |
| POST /jobs/{id}/cancel | collect | {} → {ok:true}; requests cancellation. Poll final state. |
| GET /leads | read | Query below → {total,records,page,pageSize:100}. |
| PATCH /leads/{id} | write | Optional status,notes,tags,list → {ok:true}; collected contact/business fields are not editable here. |
| GET /lists; GET /views | read | Arrays of list names/counts or saved views. |
| POST /views | write | {name,config:{search,filter,sort,list?,columns?}} → {ok:true}; same name updates. |
| POST /exports/preview | export | Selection below → {count,rows}; up to five rows, no file. |
| POST /exports | export | Selection below → {count,url,filename}; relative authenticated URL, five-minute validity. |
| GET /connections | read | Provider/settings; stored token never returned. |
| POST /connections/ghl | integrations | {token,locationId}; operator-enabled GHL required, currently disabled. |
| DELETE /connections/ghl | integrations | Removes stored connection, not previously sent CRM records. |
| POST /sync/ghl | integrations | {ids:[leadId],confirmed:false} previews; confirmed:true sends up to 100 when enabled. |
| GET /sync/ghl | read | Latest 100 outcomes: lead_id,remote_id,state,updated_at. |
| GET /webhooks | read | Endpoint id/url/created_at, no secret. |
| POST /webhooks | integrations | {url:publicHttpsUrl} → secret shown once (201). GET endpoints for its id. |
| DELETE /webhooks/{id} | integrations | Removes owned endpoint → {ok:true}. |
Pagination, export selection and downloads
GET /leads accepts jobId, page (zero-based integer), search (name/city/category/tags), filter (has-email, has-phone, no-website, incomplete), list, sort (completeness, name, rating). Default completeness/rating sorts descend, then name, then id. No arbitrary-column or status filter exists here. GET does not accept an ids array.
Keep the same query/sort and increment page until (page + 1) × pageSize ≥ total. Prefer a terminal job so records do not change between pages. Export bodies accept jobId, ids (up to 10,000), search, filter, list, sort, format (xlsx,csv,json) and template.
Resolve the returned export url against https://leadmaps.live. Request it with the same export-scoped bearer key, with redirects disabled. Azure returns a short-lived Location URL; fetch that storage URL separately WITHOUT forwarding your bearer key to storage. Do not publish the signed URL.
GET /api/v1/jobs/YOUR_JOB_UUID
GET /api/v1/leads?jobId=YOUR_JOB_UUID&page=0&sort=name
POST /api/v1/exports/preview
POST /api/v1/exports
{
"jobId": "YOUR_JOB_UUID", "format": "xlsx",
"template": "Calling List", "sort": "name"
}API errors and scopes
read reads jobs/results/settings and preview. collect creates/cancels jobs. export previews/generates files and authorizes download. write updates annotations/views. integrations manages webhook/GHL connections and sync. Keys cannot create/revoke other keys. Sessions belong to the website; automate using bearer keys.
| HTTP | Meaning / next step |
|---|---|
| 400 | Invalid JSON/fields; read {error:message} and correct before retrying. |
| 401 | Missing/invalid/revoked key or session. |
| 403 | Missing scope, blocked workspace, invalid origin or expired download; inspect error. |
| 402 | Insufficient available credits; lower maximum. |
| 404 | Missing resource or not owned by workspace. |
| 409 | Active collection or different search under an existing request key. |
| 413 | Request exceeds 64 KiB; reduce payload size. |
| 429 | Shared rate limit; back off, do not loop tightly. |
| 503 | Feature disabled; repeated retries do not enable it. |
| 500 | Unexpected server issue; preserve references. Job submission retries retain original key. |
Choose your connection path
Use file exports for a finished list, REST polling for repeatable automation, or the local MCP bridge for an assistant. Each external tool needs its own account access. Google sign-in authenticates LeadMaps only; it does not grant Drive or Sheets access.
Give each workflow a separate scoped key. Store request key/job id durably, separate polling from collection creation, deduplicate destination writes by LeadMaps id, and verify actual destination rows. Do not invent personal names from company listings.
GoHighLevel: awaiting live enablement
The native connector is disabled in the current live beta. Mapping is tested locally, but no real GHL destination sync has passed. These steps describe an enabled pilot; contact us to arrange one before relying on it.
GHL upsert matching depends on the location’s duplicate settings. LeadMaps claims a lead submission before sending: synced indicates a successful API response; already-submitted prevents repeat sending; rejected indicates a non-success response; unknown is an ambiguous network outcome. Rejected/unknown records are not automatically resubmitted. Reconcile the actual CRM before asking support to retry. Disconnect does not reset submission history or delete CRM data.
- Use an eligible GHL sub-account/location. Create a Private Integration token with locations.readonly and contacts.write; contacts.readonly is useful for inspecting pilot contacts. Do not use a legacy agency API key.
- When enabled, enter token and exact location ID in LeadMaps Integrations. The server checks location access before encrypting/saving credentials.
- Select 1–100 leads and preview Sync to GHL. Check destination workflows before confirmation; contact upsert can update records and trigger automations.
- Test one record first. Verify it inside GHL and inspect sync outcomes before expanding. Disconnect in LeadMaps and revoke the GHL token when no longer needed.
| LeadMaps | GHL mapping |
|---|---|
| name | companyName; no invented first/last names |
| phone / first email | phone / email; leads with neither are skipped |
| website / address | website / address1 |
| city / state / postalCode / country | Corresponding GHL fields; country code preserved |
| connection | locationId; source: LeadMaps |
| tags / notes / list | Not sent by this connector; use exports or separate mapping |
n8n / Make / Zapier: shared recipe
These are generic HTTP recipes based on official platform documentation, not native integrations or account-tested automations. Your plan must permit the HTTP actions. Polling is recommended instead of relying exclusively on beta completion webhooks.
- Test GET /me with a read key first, without spending collection credits.
- POST one reviewed /jobs request with collect scope, JSON body and persistent Idempotency-Key. Store returned id; never generate a new key for a transport retry.
- Use a bounded status-check workflow: wait 10–15 seconds between GET /jobs/{id}; branch on terminal states. A single delay is not proof of completion.
- For completed/partial/cancelled jobs, fetch /leads?jobId=…&page=0, iterate records and increment page until total is covered.
- Map name to company name, phone, emails[0] only when present, website/address/city/country. Deduplicate with id. Verify small test outputs in the actual destination before scaling.
n8n setup
- Add HTTP Request. GET https://leadmaps.live/api/v1/me. Use Generic Credential → Header Auth: Authorization with value Bearer followed by your private key.
- For job submission set POST /api/v1/jobs, JSON body from the API section, and an Idempotency-Key header. Keep auth in the credential store.
- Use Wait and IF nodes for bounded polling. Preserve the job id between nodes. Read actual output before writing expressions.
- Results are under records, not the top-level response. Split that array into items before the destination node; increment page and stop based on total/pageSize. Keep certificate validation enabled.
Make setup
- Add HTTP → Make a request with GET https://leadmaps.live/api/v1/me. Configure secure header/API-key credentials for Authorization: Bearer KEY.
- For /jobs use POST, Content-Type: application/json, Idempotency-Key, JSON body. Enable parsed response and store id durably.
- Use a separate scheduled status-check scenario or bounded polling route. An Iterator processes records; advance page until total is covered. Map destination fields explicitly.
Zapier setup
Do not treat a Catch Hook payload as trusted completion unless your receiver verifies the exact raw body/timestamp/signature. Use the polling recipe if those are unavailable.
- Use Webhooks by Zapier → Custom Request, method GET for /me and header Authorization: Bearer KEY. Keep credentials and task history access private.
- For /jobs choose POST, Data as JSON body, Content-Type: application/json and Idempotency-Key headers. Store returned job id in your durable storage/table.
- Use a separate scheduled checker to poll terminal jobs, then loop over records and subsequent pages. Do not assume one Delay means collection finished.
HubSpot company imports
- Export CRM Import CSV/XLSX and inspect it. In HubSpot start a file import for Companies.
- Map Company Name → Name, Website → Website URL, Phone → Phone number, Address → Street address, and City/State/Postal Code/Country to the matching company properties.
- Map Email/Tags only to appropriate existing/custom properties. Do not silently import business listings as named people; first/last names are not supplied.
- For repeat imports use HubSpot Record ID or a suitable unique company property. Website is a full URL, not a dedicated Company domain name column. If using domain matching, add/review that column yourself and watch for franchises sharing domains.
- Review mapping errors and duplicates inside HubSpot. This is manual import, not continuous sync.
Google Sheets imports
No native Sheets OAuth connector is available. IMPORTDATA cannot fetch a private authenticated export link, and that link expires. Google sign-in is not permission to write spreadsheets.
- Download XLSX for structured sheets or CSV for a flat table. In Sheets use File → Import → Upload, choose the file and destination. Or upload XLSX to Drive and open with Sheets.
- For CSV disable automatic conversion to numbers/dates/formulas when offered; inspect Phone/Postal Code columns. CSV protection may leave a literal apostrophe before + phones; prefer XLSX for exact formatting.
- Check Unicode, leading zeros and phone prefixes. Apply frozen headers/filters if import did not preserve them.
Codex: local MCP bridge
This is a local stdio server in the LeadMaps project, not a hosted URL. You need Node.js, the supplied project/bridge source, installed dependencies, a compatible MCP client and a private key. No public npm package/self-service bridge download exists yet; request source/setup through Contact us if needed.
LEAD_STUDIO_URL and LEAD_STUDIO_API_KEY are the bridge’s exact current environment names. LEADMAPS_* will not work here. Configuration uses forward slashes in Windows paths. The sample calls the already-installed tsx CLI directly, avoiding npx prompts/downloads.
A protocol test is not proof your particular Codex installation is connected. No hosted ChatGPT OAuth integration or directory app is available.
- Install dependencies with npm ci in the provided project folder. Check node runs from your terminal.
- Create a read/collect/export key (or read only for inspecting results). Add config below to your user MCP configuration, preserving existing entries. Replace both absolute paths and the private key.
- Refresh/restart the client’s MCP connections and check the six tools appear. Try read_results or collection_status for a job you own first; no collection credits consumed.
- Before create_collection, confirm categories, scope, country/city/region, required contacts, limit and maximum charge. Reuse idempotencyKey for retries.
| Tool | Inputs / output |
|---|---|
| preview_search | prompt; suggestions, not complete scope validation; no charge. |
| create_collection | category or categories, scope, country, city/region as needed, limit, fields, optional requiredFields/preset/minRating/maxReviewCount, confirmed:true, idempotencyKey. |
| collection_status / cancel_collection | jobId UUID; actual job object / cancellation request. |
| read_results | Optional jobId and page (default 0); total/records/page/pageSize. |
| export_results | jobId, format (xlsx/csv/json), template; count/relative url/filename. Download requires export scope. |
[mcp_servers.leadmaps] command = "node" args = ["C:/LeadMaps/node_modules/tsx/dist/cli.mjs", "C:/LeadMaps/src/server/mcp.ts"] [mcp_servers.leadmaps.env] LEAD_STUDIO_URL = "https://leadmaps.live" LEAD_STUDIO_API_KEY = "REPLACE_WITH_YOUR_PRIVATE_SCOPED_KEY"
Completion webhooks: beta limits
Polling is recommended for dependable beta automation. Endpoint registration and signed delivery are implemented, but the Azure event worker wakes for collection jobs. Pending retries do not independently wake it; a later worker run may process them. Nominal retry intervals are not a timing guarantee. A dedicated retry trigger is needed before webhooks can be relied on alone.
POST /api/v1/webhooks with {url:yourPublicHttpsUrl}, using integrations scope. Save secret immediately, shown once; this is the signing secret, not your API key. GET /webhooks gives endpoint id; DELETE /webhooks/{id} removes it.
Payload: {id:deliveryUUID,type:'job.finished',jobId:jobUUID,status:terminalStatus,accepted:integer,occurredAt:ISOtimestamp}. Header names remain X-Lead-Studio-Timestamp (Unix seconds) and X-Lead-Studio-Signature (lowercase hex) for compatibility.
Verify HMAC-SHA256 of timestamp + period + exact raw UTF-8 request body, before JSON parsing. Reject missing/malformed headers and timestamps more than five minutes away, including future timestamps. Compare fixed-size buffers in constant time. Reserializing parsed JSON changes the signed bytes.
Persist the verified event and deduplicate by id before responding 2xx. Duplicate verified events should also get 2xx. Up to five total attempts (initial + four retries), nominal backoff 30/60/120/240 seconds while a worker is available. Private-network hosts, URL credentials, nonstandard ports and webhook redirects are rejected. No retry timing SLA, replay button or delivery dashboard is available.
// Node.js receiver helper, before parsing the exact raw body.
import { createHmac, timingSafeEqual } from 'node:crypto';
function verify(rawBody, timestamp, signature, signingSecret) {
if (!/^\d+$/.test(timestamp || '') || !/^[a-f0-9]{64}$/.test(signature || '')) return false;
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const expected = createHmac('sha256', signingSecret)
.update(timestamp + '.' + rawBody).digest();
return timingSafeEqual(expected, Buffer.from(signature, 'hex'));
}Troubleshooting
For help provide job id, approximate time, scope, error text and failing platform step through Contact us. Never send API keys, OAuth secrets or integration tokens. Data removal requests need the source listing link.
| Problem | Check / action |
|---|---|
| Fewer leads / missing email | Inspect required fields/exclusions/source. Limit is a maximum; strict filters can yield zero. Missing data remains empty. |
| Queued / interrupted job | Keep job id, inspect Collections. Worker startup/capacity can delay it. Do not submit repeated jobs. |
| Partial / failed / cancelled | Read error/counts, export completed results, inspect available/reserved credits. Fresh search gets new key; transport retry retains old key. |
| GHL disabled / 503 | Await operator enablement and real pilot. Credential rotation cannot change a feature flag. |
| GHL unknown / already-submitted | Check actual CRM state before reconciliation; repeated submissions intentionally do not resend. |
| MCP tools missing | Check Node/absolute paths/dependencies/exact environment names/key. HTTPS required remotely; localhost supported for development. |
| Download expired / 403 | Generate again; export scope needed. Fetch storage redirect separately without the key. |
| Automation duplicates | Persist request/job ids and downstream lead ids. Separate status polling from collection creation. |
| Webhook missing | Poll status; inspect raw-body signature and receiver 2xx handling. Beta wake-up limitation applies. |
| CSV prefix / changed phone | CSV protects formula-like values. Prefer XLSX/JSON and text columns; inspect destination conversion. |
Official platform references
Checked on 13 October 2026. Platform screens and plan entitlements can change; follow their current requirements.
