---
name: find-new-sales-territory-locations
description: Find newly observed local business locations by comparing repeatable Google Maps scans.
---

# Find new locations to sell into

Feed territory reps locations that are new to your location database. This
two-city, two-page scan uses **4 calls,
$0.00060** at $0.15 per 1,000 successful calls. This is a reusable plan, not a measured run.

## 1. Require the previous snapshot

For a first scan, ask for the business category and two cities. For repeat scans,
use the supplied baseline's category, cities and locale rather than choosing new ones.

Delta mode requires a supplied accumulated `baseline.csv` containing `place_id`,
`first_seen_at`, `last_seen_at` and a `scan_fingerprint` on every row. The
fingerprint is the same canonical JSON string for the whole scan: exact
query-city pairs sorted alphabetically, then `gl`, `hl` and sorted page
offsets, with fixed key order and no whitespace. Also save this fingerprint and
its readable parameters in `manifest.json`. Require explicit country and language
values. A baseline with missing or mixed fingerprints cannot produce a delta.
For example, use this exact key order and serialization for these inputs:

```json
{"queries":["restaurants in Austin, TX","restaurants in Round Rock, TX"],"gl":"us","hl":"en","starts":[0,20]}
```

Without a usable baseline, save a separate first baseline and return no
additions; do not overwrite an incompatible history. Check your key first:

```bash
curl --fail-with-body --silent --show-error https://api.litescrape.com/api/keys/status \
  -H "Authorization: Bearer $LITESCRAPE_API_KEY"
```

Read `remaining_calls` and `concurrency_limit`; never exceed either or the
agreed four-call cap. Use unique raw filenames by city, page and scan timestamp.

## 2. Scan each city the same way

Use the exact category query, cities, `gl`, `hl` and pages recorded in
the baseline fingerprint. Two cities at starts 0 and 20 equal four calls.

```bash
curl --fail-with-body --silent --show-error -G https://api.litescrape.com/api/google/maps \
  -H "Authorization: Bearer $LITESCRAPE_API_KEY" \
  --data-urlencode 'q=restaurants in Austin, TX' \
  --data-urlencode 'type=search' --data-urlencode 'start=0' \
  --data-urlencode 'gl=us' --data-urlencode 'hl=en' \
  -o austin-0.json
```

Keep `place_id`, title, address, phone, website, category, source URL, query
and retrieval time. Deduplicate current results by `place_id`.

The public Maps endpoint does not accept `device`; do not copy that parameter
from a Search request. A baseline is usable only after every required
query/page succeeded or its earlier page established exhausted pagination.
If any required request fails, set `coverage_complete=false`, save the partial
observations separately and leave any prior baseline unchanged. Do not report
zero additions or generate a delta from an incomplete scan.

## 3. Calculate observations, not openings

Compare this scan's fingerprint to the baseline before calculating a delta. If
the exact query, cities, `gl`, `hl` or pages changed, write
`status=fingerprint_changed` and do not label any result new. With a matching
fingerprint, add only IDs never present in the accumulated baseline to
`new-locations.csv`. For existing IDs found today, update `last_seen_at`; retain
prior IDs absent today without changing their first-seen date. A ranking dropout
then reappearance is not new again. If a CRM export is supplied, subtract
matching location IDs locally and retain the exclusion reason. Keep separately
supplied opening evidence in a distinct `recently_opened_confirmed` status.
Report overlap, prior dropouts and never-seen additions separately: even scans
minutes apart can return different established businesses. A query for
restaurants can return bars or groups/franchises. Apply supplied category and
ownership requirements to the rep queue, preserving `qualification_status` and
evidence; unknown ownership is not verified independence. Keep all seen IDs in
history even when excluded from outreach so they cannot reappear as new.

## 4. Write rep and baseline files

Write `new-locations.csv`:

```text
place_id,name,address,phone,category,source_url,first_seen_at,last_seen_at,status,qualification_status,qualification_evidence
```

Write `baseline.csv` with `place_id`, name, address, `first_seen_at`,
`last_seen_at`, source query and `scan_fingerprint`. Write `manifest.json` with the immutable
fingerprint, coverage completeness, calls, current count, new-to-database count,
overlap/dropout counts, qualification/CRM exclusions and stop reason. Keep a
`current-locations.csv` containing contact and source fields, not only the compact
history. Stop at the agreed cap, empty continuation or
exhausted balance. A non-retryable 400 is a failed request, not an empty market.
Stop immediately on 401, 403 or 402; retry a 429 or transient 5xx once only
within cap, then record the error and incomplete coverage. Never print the key or send it to a source
link. Maps coverage and ranking change, so the output cannot establish an
opening, closure, move or CRM absence.
