# gmaps for agents

gmaps finds local businesses on Google Maps and returns them as leads: name,
category, address, phone, website, rating and, when asked for, email and
other enrichment. A person describes who they want ("50 dentists in Austin
TX with a website"); a *campaign* runs that search and saves the results.
A *bulk run* does the same for a list of search queries at once.

You act for the account that owns the API key you were given, with that
account's plan limits and credits.

## Rules

- **Running a campaign or bulk run spends the user's credits.** Creating a
  draft and asking for an estimate are free. Before you run anything, get an
  estimate, tell the user the credit ceiling and the time, and wait for a
  clear yes. Do not run on your own initiative.
- The estimate is a ceiling. Only delivered leads are charged; a run holds
  its ceiling while it works and returns what it did not use.
- Send an `Idempotency-Key` header (any id unique to the request) on every
  POST that starts or cancels work, so a retry never runs it twice.
- A run is asynchronous. After starting one, poll it until its status is
  `completed`, `failed` or `cancelled`; do not start it again.
- On HTTP 429, wait before retrying. On any error, the JSON body's
  `error.code` and `error.message` say what went wrong; quote
  `error.request_id` to the user if they need support.
- Never print the API key back to the user or put it in a URL.
- Results are the user's business data. Do not send them anywhere the user
  did not ask you to.

## Authentication

Every request carries the key as a bearer token:

    Authorization: Bearer YOUR_API_KEY

The user creates a key in the app under Settings, Developers
(https://app.localicp.com/settings?tab=developers). API keys are part of the Growth and
Agency plans. If you have no key, ask the user for one; do not guess.

## Option 1: MCP

If you can use MCP tools, connect to this server and the tools describe
themselves (plan and estimate a campaign, run it, read its leads, the same
for bulk runs, and read the account's credits):

    https://mcp.localicp.com/mcp

Send the same `Authorization: Bearer` header. For example, in Claude Code:

    claude mcp add --transport http --scope user gmaps https://mcp.localicp.com/mcp \
      --header "Authorization: Bearer YOUR_API_KEY"

## Option 2: REST API

Base URL:

    https://app.localicp.com/api/v1

The machine-readable description of every endpoint, its parameters and its
responses is the OpenAPI 3.1 document, which needs no key:

    https://app.localicp.com/api/v1/openapi.json

### A first campaign

1. Check the key and the balance (free):

       curl https://app.localicp.com/api/v1/credits -H "Authorization: Bearer YOUR_API_KEY"

2. Create a draft (free). The response carries the campaign's `id`:

       curl -X POST https://app.localicp.com/api/v1/campaigns \
         -H "Authorization: Bearer YOUR_API_KEY" \
         -H "Idempotency-Key: A_UNIQUE_ID" \
         -H "Content-Type: application/json" \
         -d '{"prompt": "dentists in Austin TX", "target_count": 50}'

3. Estimate it (free), and show the user the result before going on:

       curl -X POST https://app.localicp.com/api/v1/campaigns/estimate \
         -H "Authorization: Bearer YOUR_API_KEY" \
         -H "Content-Type: application/json" \
         -d '{"campaign_id": "CAMPAIGN_ID"}'

4. Run it, once the user has agreed (spends credits):

       curl -X POST https://app.localicp.com/api/v1/campaigns/CAMPAIGN_ID/run \
         -H "Authorization: Bearer YOUR_API_KEY" \
         -H "Idempotency-Key: ANOTHER_UNIQUE_ID"

5. Poll until it has finished, then read the results page by page:

       curl https://app.localicp.com/api/v1/campaigns/CAMPAIGN_ID -H "Authorization: Bearer YOUR_API_KEY"
       curl "https://app.localicp.com/api/v1/campaigns/CAMPAIGN_ID/results?page=1" -H "Authorization: Bearer YOUR_API_KEY"

### Endpoints

- `GET /openapi.json` Read the v1 OpenAPI document
- `GET /pricing` Read pricing and plan limits
- `GET /credits` Read available credits
- `GET /place-fields` Read the place-field catalog
- `POST /campaigns/estimate` Estimate campaign cost and time
- `POST /campaigns` Create a campaign draft
- `GET /campaigns` List campaigns
- `GET /campaigns/{id}` Poll a campaign
- `POST /campaigns/{id}/run` Run a draft once
- `POST /campaigns/{id}/leads/enrich` Enrich saved leads on demand
- `POST /campaigns/{id}/cancel` Cancel a campaign
- `GET /campaigns/{id}/results` Read a page of results
- `GET /campaigns/{id}/results/{placeId}` Read one result
- `GET /leads` List leads across campaigns
- `GET /bulk` List bulk runs
- `POST /bulk` Create a bulk run draft
- `GET /bulk/{id}` Poll a bulk run
- `POST /bulk/{id}/run` Run a bulk draft
- `POST /bulk/{id}/cancel` Cancel a bulk run
- `GET /bulk/{id}/export` Export a bulk run
- `GET /usage` Read usage per API key
- `GET /usage/ledger` Download the credit statement
- `GET /campaigns/{id}/export` Export campaign results

## For people

The same reference, written for a person, is at https://app.localicp.com/docs.
