Skip to content
All posts

How to find B2B prospects by business type and city

Leads and local businesses6 min read
How to find B2B prospects by business type and city: the post's first code sample

If you sell to small businesses (bookkeeping software, websites, payment terminals, IT support, insurance) your market is a type of business in a place: "accountants in Lyon", "vets in Denver". This playbook shows how to find B2B prospects by business type and city with POST /v1/places, then enrich, qualify and contact them without burning your reputation.

Step 1: Choose the business types

Start from who buys what you sell, not from what is easy to list. The API has 24 categories, the same ones the dashboard offers:

The grouping is ours; the ids are what you send. GET /v1/capabilities with your key returns the live list under entitlements.places.categories, so code can read it instead of hardcoding it. A few categories cover more than one kind of place: bar includes pubs, hotel includes guest houses, and clinic includes doctors' practices.

Pick two or three categories that share a problem you solve. Messaging reads better when it is specific to the trade.

Step 2: Choose the cities

Send a location as a city name with its country or state, such as "Lyon, France" or "Denver, CO". One search covers up to roughly a large metro area; a whole region or country is refused with a 400 asking for a smaller area. For a country, loop over its cities. For an exact patch of a city, send a bbox of [south, west, north, east] instead.

Start with cities where you can serve customers well, whether that is language, time zone or the ability to visit. A smaller list you can follow up on beats a large one you cannot.

Step 3: Filter for the signal you care about

The three filters, website, phone and email, each take "any", "yes" or "no". Pick them to match your offer:

Here is a real search for accountants in Lyon with a website, run on the Free plan:

curl
curl https://scrape.land/v1/places \
  -H "X-Api-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"category": "accountant", "location": "Lyon, France", "website": "yes"}'
JSON
{
  "attribution": "© OpenStreetMap contributors, ODbL (openstreetmap.org/copyright)",
  "bbox": [45.7073666, 4.7718132, 45.8082628, 4.8984161],
  "category": "accountant",
  "count": 8,
  "matched": 8,
  "preview": true,
  "preview_note": "Free plan: the first 10 matches. Every paid plan returns up to 200 per call.",
  "results": [
    {
      "name": "Develter Partenaires",
      "category": "accountant",
      "lat": 45.727069,
      "lon": 4.840048,
      "website": "https://develter-partenaires.com/",
      "phone": "+33 4 81 91 62 05",
      "email": "contact@develter-partenaires.fr",
      "osm_url": "https://www.openstreetmap.org/node/14069213066"
    },
    {
      "name": "OnlyCompta",
      "category": "accountant",
      "address": "39 Rue des remparts d'ainay, 69002",
      "city": "Lyon",
      "lat": 45.752645,
      "lon": 4.83191,
      "website": "https://www.onlycompta.fr",
      "phone": "+33481098181",
      "opening_hours": "Mo-Fr 08:00-17:30",
      "osm_url": "https://www.openstreetmap.org/relation/1235156"
    }
    … 6 more
  ],
  "units": 1
}

Eight matched, all eight came back, and it cost 1 unit. Of the eight, seven had a phone and two had an email. That ratio is typical: map data is good for names, locations, websites and phones, and thinner on emails. Coverage also varies by city and trade, because it depends on what people have mapped in OpenStreetMap, so treat a small matched as "few mapped", not "few exist".

Step 4: Enrich

Rows with a website and no email can be enriched from the company's own site: fetch the homepage and a contact page, and read the published email, phone and social links. Collect contact details from a list of websites with Python has a ready script; in the dashboard, the Local businesses tool has a Find emails on their websites button that does the same. Each page read is 1 request unit, so enrichment costs 1 or 2 units per company.

Step 5: Qualify

Not every row is a prospect. Before anyone gets a message, go through the list:

Step 6: Reach out properly

Good outreach is short, specific and easy to decline. Say who you are and why you are writing to this business in particular, offer one concrete thing, and include a clear way to opt out. Space follow-ups out and stop after one or two. When someone says no, remove them from every list you keep.

The legal part matters. Use only public business contact details. Follow the rules on unsolicited calls and email where you and they are: in the EU, GDPR and ePrivacy apply, and a sole trader's phone number or email can be personal data; several countries require prior consent for cold email, and many run do-not-call registers. Honour opt-outs every time. The data is © OpenStreetMap contributors under the ODbL, and our Acceptable Use Policy applies to what you do with it.

Ask an AI assistant instead

If you use Claude, Cursor or another client that supports MCP, the scrape.land MCP server has a find_local_businesses tool with the same category, location, website, phone, email and limit arguments. You can ask "find accountants in Lyon that have a website and list them with their phone numbers" and the assistant calls /v1/places on your account, billed exactly as the API. Setup takes one command: see how to use scrape.land from Claude with MCP.

What it costs

A search costs 1 request unit per 10 rows returned, at least 1. The Free plan (1,000 requests a month) returns the first 10 matches per search; every paid plan returns up to 200. Enrichment is 1 unit per page read. See pricing.

Next steps

To run several categories and cities in one go, use the script in export local business leads to CSV with Python. For a no-code version, see build a local lead list without code. Every request option is in the docs.

Start free with 1,000 requests Read the docs