HTTP API

HTTP API reference

Programmatic access to the same scrape-and-enrich pipeline as the Online Lead Extractor. Authenticate with a personal Bearer key (gmf_…). One keyword per job. Agent-capable Online (cloud) plans only—see Pricing.

Base URL: https://gmapsleadfinder.com

Prefer Remote MCP?

If you use Claude, Cursor, or another MCP client, install Remote MCP instead of calling HTTP by hand. The Agent & MCP docs cover setup, tools, and install snippets.

Open Agent & MCP docs

Authentication

Every /api/v1 request requires an Authorization header with your personal API key. Keys start with gmf_ and are issued in Account after you sign in on an agent-capable plan.

http
Authorization: Bearer gmf_<your_key>
  1. Sign in at gmapsleadfinder.com on a plan that includes agent API.
  2. Open Account → API key, or visit /account#api-key.
  3. Copy the key (or regenerate). Pass it only from your client or secret store—never embed it in public frontends.

GET/POST /api/me/api-key require a browser session cookie and are for the Account UI—not for agent Bearer calls. Open Account API key

GET/api/v1/me

Get plan & credits

Returns the authenticated user’s plan and credit snapshot. Useful before creating jobs.

Parameters

Name In Type Required Description
AuthorizationheaderstringYesBearer gmf_… API key

Response fields

Field Type Description
planstringPlan id / name for the account
creditsLimitnumberCredit limit for the current period (or lifetime free pool)
creditsUsednumberCredits already consumed
creditsRemainingnumbercreditsLimit − creditsUsed

Error codes

  • 401 — Missing or invalid API key
  • 403 — Key valid but plan cannot use the agent API

curl

bash
curl -sS https://gmapsleadfinder.com/api/v1/me \
  -H "Authorization: Bearer $GMF_API_KEY"

JavaScript

js
const res = await fetch("https://gmapsleadfinder.com/api/v1/me", {
  headers: { Authorization: `Bearer ${process.env.GMF_API_KEY}` },
});
const me = await res.json();
console.log(me.creditsRemaining);

Example response

json
{
  "plan": "growth",
  "creditsLimit": 5000,
  "creditsUsed": 120,
  "creditsRemaining": 4880
}
POST/api/v1/jobs

Create a job

Queues a single-keyword Maps scrape + enrich job. Exactly one keyword is required. Shares the one-running-job lock with the web extractor (HTTP 409 if busy).

Parameters

Name In Type Required Description
AuthorizationheaderstringYesBearer gmf_… API key
keywordbodystringYesOne search query (city + category works best). Multi-keyword strings are rejected.

Response fields

Field Type Description
jobIdstring (uuid)Job id for polling and results
keywordCountnumberAlways 1 for API jobs
creditsRemainingnumberCredits left after queue (consumption occurs as rows are collected)

Error codes

  • 400 — Missing keyword or more than one keyword
  • 401 — Missing or invalid API key
  • 402 — No credits remaining
  • 403 — Plan cannot use the agent API
  • 409 — Another search job is already running for this user

curl

bash
curl -sS -X POST https://gmapsleadfinder.com/api/v1/jobs \
  -H "Authorization: Bearer $GMF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"keyword":"dentists in Austin TX"}'

JavaScript

js
const res = await fetch("https://gmapsleadfinder.com/api/v1/jobs", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.GMF_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ keyword: "dentists in Austin TX" }),
});
const { jobId } = await res.json();

Example response

json
{
  "jobId": "3f2c8a1e-9b4d-4c2a-8e1f-0a1b2c3d4e5f",
  "keywordCount": 1,
  "creditsRemaining": 4880
}
GET/api/v1/jobs/{id}

Get job status

Poll job metadata until status is completed, partial, or failed. Includes per-keyword file progress when available.

Parameters

Name In Type Required Description
AuthorizationheaderstringYesBearer gmf_… API key
idpathstring (uuid)YesJob id returned by POST /api/v1/jobs

Response fields

Field Type Description
idstringJob id
statusstringqueued | running | completed | partial | failed (and related pipeline states)
keywordsstring[]Keyword list for the job
keywordCountnumberNumber of keywords
currentKeywordIndexnumberProgress index while running
rowCountnumberRows collected so far / total for the job
errorstring | nullError message when failed
createdAtstring (ISO)Created timestamp
finishedAtstring | nullFinished timestamp
filesobject[]Per-keyword file records: id, keyword, position, status, pageCount, rowCount, enrichStatus, error
creditsRemainingnumberCurrent credits remaining

Error codes

  • 401 — Missing or invalid API key
  • 403 — Plan cannot use the agent API
  • 404 — Job not found for this key’s user

curl

bash
curl -sS https://gmapsleadfinder.com/api/v1/jobs/$JOB_ID \
  -H "Authorization: Bearer $GMF_API_KEY"

JavaScript

js
const res = await fetch(`https://gmapsleadfinder.com/api/v1/jobs/${jobId}`, {
  headers: { Authorization: `Bearer ${process.env.GMF_API_KEY}` },
});
const job = await res.json();
// poll while job.status is queued or running

Example response

json
{
  "id": "3f2c8a1e-9b4d-4c2a-8e1f-0a1b2c3d4e5f",
  "status": "completed",
  "keywords": ["dentists in Austin TX"],
  "keywordCount": 1,
  "currentKeywordIndex": 0,
  "rowCount": 42,
  "error": null,
  "createdAt": "2026-09-13T01:00:00.000Z",
  "finishedAt": "2026-09-13T01:02:10.000Z",
  "files": [
    {
      "id": "…",
      "keyword": "dentists in Austin TX",
      "position": 0,
      "status": "completed",
      "pageCount": 3,
      "rowCount": 42,
      "enrichStatus": "completed",
      "error": null
    }
  ],
  "creditsRemaining": 4838
}
GET/api/v1/jobs/{id}/results

Get job results

Returns paginated place rows as JSON objects keyed by export column headers. Follow nextCursor until null. Column set matches Account export-column preferences.

Parameters

Name In Type Required Description
AuthorizationheaderstringYesBearer gmf_… API key
idpathstring (uuid)YesJob id
limitqueryintegerNoPage size 1–500 (default 100)
cursorquerystringNoOffset cursor from a previous nextCursor (default 0)

Response fields

Field Type Description
jobIdstringJob id
statusstringCurrent job status
columnsstring[]Ordered export column headers
rowsobject[]Each row is { [column]: string }
countnumberRows in this page
totalnumberTotal rows available for the job
cursornumberOffset used for this page
nextCursorstring | nullPass as cursor for the next page; null when done

Error codes

  • 401 — Missing or invalid API key
  • 403 — Plan cannot use the agent API
  • 404 — Job not found

curl

bash
curl -sS "https://gmapsleadfinder.com/api/v1/jobs/$JOB_ID/results?limit=100" \
  -H "Authorization: Bearer $GMF_API_KEY"

JavaScript

js
async function fetchAllRows(jobId) {
  const rows = [];
  let cursor = "0";
  while (cursor != null) {
    const url = new URL(`https://gmapsleadfinder.com/api/v1/jobs/${jobId}/results`);
    url.searchParams.set("limit", "100");
    url.searchParams.set("cursor", cursor);
    const res = await fetch(url, {
      headers: { Authorization: `Bearer ${process.env.GMF_API_KEY}` },
    });
    const page = await res.json();
    rows.push(...page.rows);
    cursor = page.nextCursor;
  }
  return rows;
}

Example response

json
{
  "jobId": "3f2c8a1e-9b4d-4c2a-8e1f-0a1b2c3d4e5f",
  "status": "completed",
  "columns": ["Name", "Phone", "Website", "Emails"],
  "rows": [
    {
      "Name": "Austin Smile Dental",
      "Phone": "(512) 555-0142",
      "Website": "https://example.com",
      "Emails": "hello@example.com"
    }
  ],
  "count": 1,
  "total": 42,
  "cursor": 0,
  "nextCursor": "1"
}

Typical workflow

  1. Call GET /api/v1/me to confirm creditsRemaining > 0.
  2. POST /api/v1/jobs with one keyword; store jobId.
  3. Poll GET /api/v1/jobs/{id} until status is completed, partial, or failed.
  4. GET /api/v1/jobs/{id}/results and follow nextCursor until null.

Errors & limits

Code Meaning
400Bad request (e.g. not exactly one keyword)
401Missing or invalid Bearer key
402No credits remaining
403Authenticated but plan cannot use agent API
404Job not found
409Another job is already running for this user (web or API)
  • One credit equals one place row collected.
  • API jobs accept exactly one keyword; use the web UI for multi-keyword batches.
  • Results column set follows Account → export columns.
  • Empty email/social cells mean nothing public was found—we never invent contacts.

Related