# Lead finder

> Find local businesses on the map and the addresses their websites publish. 8 REST endpoints with parameters, permissions and curl examples.

Canonical: https://ballast.to/docs/api/lead-finder

[API reference](https://ballast.to/docs/api)

Find local businesses on the map and the addresses their websites publish. 8 endpoints, each also a tool for your AI through [MCP](https://ballast.to/docs/mcp). Authentication and errors are on the [overview](https://ballast.to/docs/api#authentication).

## Kinds of business the lead finder can search

GET

/api/v1/lead-finder/categories

About 60 presets (dentists, accountants, plumbers...) with the OpenStreetMap tags each one searches.

MCP tool

list\_business\_categories

Read-only

Returns

- **`categories` required object\[\]**

cURL

```
curl https://ballast.to/api/v1/lead-finder/categories \
  -H "Authorization: Bearer $BALLAST_API_KEY"
```

## Find local businesses in a place or a map area

POST

/api/v1/lead-finder/searches

Searches OpenStreetMap (or Google Places with the workspace's own key, provider google, connected by an owner or admin in Integrations; at most 60 results, no map pins) for businesses of a category and/or a name. Give a place (a city or district, geocoded; a big one is searched within 50 km of its center) or a box. At most 2,500 km² and 1,000 businesses a search, 30 searches an hour per workspace. Results include phones, websites and any address OpenStreetMap lists; call read\_business\_websites to read their sites for the addresses they publish.

MCP tool

find\_businesses

Parameters

- **`provider` "osm" | "google"**
- **`categoryId` "restaurant" | "cafe" | "bar" | "bakery" | "fast\_food" | "catering" | "dentist" | "doctor" | "clinic" | "pharmacy" | "veterinary" | "physio" | "chiropractor" | "optician" | "psychologist" | "hair\_salon" | "beauty\_salon" | "barber" | "spa" | "nail\_salon" | "gym" | "yoga" | "tattoo" | "plumber" | "electrician" | "roofer" | "hvac" | "painter" | "carpenter" | "locksmith" | "landscaping" | "cleaning" | "moving" | "builder" | "lawyer" | "accountant" | "insurance" | "real\_estate" | "marketing" | "it" | "architect" | "consulting" | "financial" | "coworking" | "employment" | "car\_repair" | "car\_dealer" | "car\_wash" | "car\_rental" | "hotel" | "event\_venue" | "travel\_agency" | "florist" | "furniture" | "hardware" | "clothing" | "jewelry" | "pet\_store" | "bookstore" | "bicycle" | "childcare" | "driving\_school" | "language\_school" | "tutoring" | "music\_school" | "photographer" | "print\_shop" | null**: From list\_business\_categories
- **`name` string | null**: Part of the business's name
- **`place` string | null**: Where, as people write it: Cluj-Napoca, Shoreditch London, Austin TX
- **`bounds` object | null**: Or the map box to search, when no place is given
- **`limit` integer**: How many places to return (the dashboard asks for all; 0 = counts only)

Returns

- **`id` required string**
- **`provider` required "osm" | "google"**
- **`title` required string**: "Dentists, Cluj-Napoca": also the list added leads go to
- **`categoryId` required string | null**
- **`name` required string | null**
- **`place` required string | null**
- **`bounds` required object**: A box on the map in degrees, at most 2,500 km²
- **`country` required string | null**
- **`results` required number**
- **`truncated` required boolean**: More businesses are in the area than one search returns: zoom in
- **`createdAt` required string**
- **`attribution` required string**
- **`progress` required object**: Places by read status, and how many have an address (any, and a company one)
- **`places` required object\[\]**
- **`placesShown` required number**

cURL

```
curl -X POST https://ballast.to/api/v1/lead-finder/searches \
  -H "Authorization: Bearer $BALLAST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"provider":"osm","categoryId":"restaurant"}'
```

## A lead finder search with its businesses and read progress

GET

/api/v1/lead-finder/searches/{id}

Read-only

Parameters

- **`id` required path · string**
- **`limit` query · integer**

Returns the same fields as Find local businesses in a place or a map area.

cURL

```
curl https://ballast.to/api/v1/lead-finder/searches/<id> \
  -H "Authorization: Bearer $BALLAST_API_KEY"
```

## The last 100 lead finder searches (kept 90 days), and whether Google Places is connected

GET

/api/v1/lead-finder/searches

Read-only

Returns

- **`searches` required object\[\]**
- **`google` required object | null**: The workspace's own Google Places key, when connected (provider google on find\_businesses)

cURL

```
curl https://ballast.to/api/v1/lead-finder/searches \
  -H "Authorization: Bearer $BALLAST_API_KEY"
```

## Read businesses' websites for the addresses they publish

POST

/api/v1/lead-finder/searches/{id}/read

Queues the picked businesses (all with a website when none are picked) and reads each site in the background: the homepage and up to 6 contact, about or imprint pages, nothing its robots.txt keeps BallastBot out of. Keeps addresses on the business's own domain (a free-mail one only when that's all it lists), each labeled company or personal, plus phones and social links. Never guesses addresses. Call it again with the same id to see progress (places already read aren't read twice). At most 2,000 sites a day per workspace.

MCP tool

read\_business\_websites

Needs an active plan

Parameters

- **`id` required path · string**
- **`placeIds` string\[\] | null**: Places to read; left out = every place with a website
- **`limit` integer**: How many places to return (the dashboard asks for all; 0 = counts only)

Returns

- **`id` required string**
- **`provider` required "osm" | "google"**
- **`title` required string**: "Dentists, Cluj-Napoca": also the list added leads go to
- **`categoryId` required string | null**
- **`name` required string | null**
- **`place` required string | null**
- **`bounds` required object**: A box on the map in degrees, at most 2,500 km²
- **`country` required string | null**
- **`results` required number**
- **`truncated` required boolean**: More businesses are in the area than one search returns: zoom in
- **`createdAt` required string**
- **`attribution` required string**
- **`progress` required object**: Places by read status, and how many have an address (any, and a company one)
- **`places` required object\[\]**
- **`placesShown` required number**
- **`queued` required number**
- **`capped` required number**: Left out today: the 2,000 reads a day were reached

cURL

```
curl -X POST https://ballast.to/api/v1/lead-finder/searches/<id>/read \
  -H "Authorization: Bearer $BALLAST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"placeIds":{},"limit":0}'
```

## Add found businesses as leads

POST

/api/v1/lead-finder/searches/{id}/add

One lead per business with an address (company addresses first), through the same checks as an import: deduped, suppressed addresses skipped, the plan's contact limit applied, ESP detected and (verify) the connected verifier run. Leads go to a list named after the search unless another is given. company = the business name; city, address, category and the OpenStreetMap id go to custom fields. First names are empty: give {{first\_name}} a fallback in the sequence.

MCP tool

add\_found\_businesses

Needs an active plan

MCP asks to confirm

Parameters

- **`id` required path · string**
- **`placeIds` string\[\] | null**: Places to add; left out = every place with an address
- **`companyOnly` boolean**: Only company addresses (info@, office@...): businesses with only a personal address are left out
- **`list` object | null**: Defaults to a list named after the search
- **`existing` "skip" | "update"**
- **`verify` boolean**: Verify new addresses with the connected verifier (uses its credits)

Returns

- **`import` required object**
- **`added` required number**
- **`noEmail` required number**
- **`personalOnly` required number**

cURL

```
curl -X POST https://ballast.to/api/v1/lead-finder/searches/<id>/add \
  -H "Authorization: Bearer $BALLAST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"placeIds":{},"companyOnly":true}'
```

## Delete lead finder searches

POST

/api/v1/lead-finder/searches/delete

Their businesses and the addresses found go with them. Leads already added stay.

Parameters

- **`ids` required string\[\]**

Returns

- **`deleted` required number**

cURL

```
curl -X POST https://ballast.to/api/v1/lead-finder/searches/delete \
  -H "Authorization: Bearer $BALLAST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ids":[]}'
```

## Test the Google Places key again

POST

/api/v1/lead-finder/google/check

Owners and admins

cURL

```
curl -X POST https://ballast.to/api/v1/lead-finder/google/check \
  -H "Authorization: Bearer $BALLAST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```
