HELP CENTER

Build Targeted Prospect Lists with Business Listings API

Building a lead list by hand means opening Google Maps, scrolling one pin at a time, and copy-pasting names, numbers, and websites into a spreadsheet. A few hundred rows in, your earliest entries may already need a second check and half your afternoon is gone. Our Business Listings API does the same job in one request. You name a category and a location, and you get back every matching business, with its address, phone, website, and rating attached. Below, we will show you how to pull a targeted prospect list, filter it to the businesses worth contacting, and do it for a few cents.

What the Business Listings API gives you to work with

The Business Listings API sits inside our broader Business Data API suite, next to the reviews and profile information endpoints. The data you get through Business Listings API comes from our in-house Business Listings Database, which holds millions of point-of-interest records pulled from business entities on Google Maps and Google Business Profiles.

Each record is a structured business profile. For every listing you get the business name, a full address split into city, ZIP, and country code, a phone number, a website URL and domain, along with the category, working hours, and a rating with the average score and vote count. One request returns up to 1,000 businesses, and you can send up to 2,000 requests a minute.

For lead generation, the following data points the API returns do most of the work. Phone and website fields give you a way to reach out. Rating and vote count tell you which businesses are established and active and which have gone quiet. That’s the gap between a raw list and one you can actually work from.

The core use case: build a targeted prospect list

Here’s the workflow in one call. Let’s say you want to find every dentist in Austin. You make an API call to the Business Listings Search endpoint, indicating two things: a category and a location. The category can be retrieved from our Categories endpoint, which lists the exact category codes the database recognizes, like dentist, marketing_agency, and plumber. The location is a coordinate string in "latitude,longitude,radius" format, and the radius is set in kilometres.

For dentists within 20 km of downtown Austin, you pass "categories": ["dentist"] and a location_coordinate centered on the city. In the API response, you get back a JSON array of dentist listings, each carrying the contact fields we named earlier. Change the category and coordinates and the same call returns marketing agencies in London or plumbers in Chicago. The structure stays the same.

You can add a title parameter to match a keyword in the business name, or pass up to 10 categories at once to widen the net. For most prospecting jobs, one category and a location is enough to get a clean list.

Qualify and segment leads in the same call

A raw list of every business in a category still includes plenty you’d never call. The built-in filters and sorting handle that qualifying step for you, before the data reaches your spreadsheet.

Filters use a simple condition format. To keep only well-reviewed businesses, add ["rating.value", ">=", 4]. To float the strongest prospects to the top, sort with "order_by": ["rating.value,desc"]. You can stack up to eight filters and three sorting rules in one request, and the full list of filterable fields is available here in the docs.

The same mechanism sets up a second use case that tends to convert: finding businesses with a weak online presence. A listing with a high rating but no website is an easy pitch for a web design or SEO service, since the demand is already proven and the gap is obvious. Every record carries a url and domain field, so you can spot those gaps straight from the response and build a segment out of them. One dataset, filtered two ways, turns into two outreach campaigns.

Pull a list of businesses without websites

You don’t need a full app for this. A single API request will do. Let’s build the no-website segment: established businesses with solid ratings but no site to send customers to, which makes them a natural target for a web design or SEO pitch. The call below pulls dentists within 20 km of Austin and keeps only those rated 4.0 or higher, so you know the demand is there. From the response, you keep the listings whose website field comes back empty.

# Instead of 'login' and 'password' use your credentials from https://app.dataforseo.com/api-access
login="login"
password="password"
cred="$(printf ${login}:${password} | base64)"
curl --location --request POST \
"https://api.dataforseo.com/v3/business_data/business_listings/search/live" \
--header "Authorization: Basic ${cred}" \
--header "Content-Type: application/json" \
--data-raw '[
  {
    "categories": [
      "dentist"
    ],
    "location_coordinate": "30.267153,-97.743057,20",
    "filters": [
      [
        "rating.value",
        ">=",
        4
      ],
      "and",
      [
        "url",
        "=",
        null
      ]
    ],
    "order_by": [
      "rating.value,desc"
    ],
    "limit": 100
  }
]'

See our Business Listings Search docs for more details on how to structure the request and read the response. The API supports the Live method only, so there’s no polling and no task queue. You send the request and the results come straight back.

Here’s what an example response looks like:

{
  "version": "0.1.20260806",
  "status_code": 20000,
  "status_message": "Ok.",
  "time": "0.3336 sec.",
  "cost": 0.0156,
  "tasks_count": 1,
  "tasks_error": 0,
  "tasks": [
    {
      "id": "08111024-8284-0544-0000-369f3ae964f2",
      "status_code": 20000,
      "status_message": "Ok.",
      "time": "0.2896 sec.",
      "cost": 0.0156,
      "result_count": 1,
      "path": [
        "v3",
        "business_data",
        "business_listings",
        "search",
        "live"
      ],
      "data": {
        "api": "business_data",
        "function": "search",
        "categories": [
          "dentist"
        ],
        "location_coordinate": "30.267153,-97.743057,20",
        "filters": [
          [
            "rating.value",
            ">=",
            4
          ],
          "and",
          [
            "url",
            "=",
            null
          ]
        ],
        "order_by": [
          "rating.value,desc"
        ],
        "limit": 100
      },
      "result": [
        {
          "total_count": 75,
          "count": 10,
          "offset": 0,
          "offset_token": "eyJDdXJyZW50T2Zmc2V0IjoxMCwiUmVxdWVzdERhdGEiOnsibmFtZSI6bnVsbCwiZGVzY3JpcHRpb24iOm51bGwsImNhdGVnb3JpZXMiOlsiZGVudGlzdCJdLCJjb3VudHJ5X2NvZGUiOm51bGwsImNpdHkiOm51bGwsImlzX2NsYWltZWQiOm51bGwsIm9ubHlfZ29vZ2xlX2J1c2luZXNzIjpmYWxzZSwiZ2VvIjp7ImxvbmdpdHVkZSI6LTk3Ljc0MzA1NywibGF0aXR1ZGUiOjMwLjI2NzE1MywicmFkaXVzIjoyMC4wfSwic2VhcmNoX2FmdGVyX3Rva2VuIjpudWxsLCJvcmRlcl9ieSI6eyJvcmRlcl9maWVsZCI6InJhdGluZy52YWx1ZSIsIm9yZGVyX3R5cGUiOiJEZXNjIiwibmV4dCI6bnVsbH0sImxpbWl0IjoxMCwib2Zmc2V0IjpudWxsfSwiUmF3UXVlcnkiOnsidHlwZSI6ImFuZCIsImxlZnQiOnsiZmllbGQiOiJyYXRpbmcudmFsdWUiLCJ0eXBlIjoiZ3RlIiwidmFsdWUiOjR9LCJyaWdodCI6eyJmaWVsZCI6InVybCIsInR5cGUiOiJlcSIsInZhbHVlIjpudWxsfX0sIlNlYXJjaEFmdGVyRGF0YSI6WzUuMCwiMTQ2NDAyMjg4ODQzOTQ1NDIxMTIiXX0=",
          "items": [
            {
              "type": "business_listing",
              "title": "Carl Weber, DDS and Madison Family Dentistry",
              "original_title": null,
              "description": "Office of Dr. Carl Weber and Nichole Madison. Provides general dentistry services with care, accepts all PPO insurances.",
              "category": "Dentist",
              "category_ids": [
                "dentist"
              ],
              "additional_categories": null,
              "cid": "10608761461000907892",
              "feature_id": "0x865b32d2db3cbf37:0x9339e45755d02c74",
              "address": "13276 US-183 Ste 102, Austin, TX 78750",
              "address_info": {
                "borough": "Anderson Mill",
                "address": "13276 US-183 Ste 102",
                "city": "Austin",
                "zip": "78750",
                "region": "Texas",
                "country_code": "US"
              },
              "place_id": "ChIJN78829IyW4YRdCzQVVfkOZM",
              "phone": "+1512-335-9631",
              "url": null,
              "domain": null,
              "logo": "https://lh4.googleusercontent.com/-O8MhEB7hESM/AAAAAAAAAAI/AAAAAAAAAAA/b2JuF0rV0mc/s44-p-k-no-ns-nd/photo.jpg",
              "main_image": "https://lh3.googleusercontent.com/gps-cs-s/APNQkAFk71_wpRojeslJ5xARfuAmw28_51NwHmeGY0BZyWoniqyLhqhosjKCFVLwJ-nRJXMOROGNncpCRztYGduUcW95woNLaCwecHD3auIRzRVI7z_jd1Ww-bStcuMZ0lQYnu7gI1bYXQ=w408-h544-k-no",
              "total_photos": 11,
              "snippet": "13276 US-183 Ste 102, Austin, TX 78750",
              "latitude": 30.4425374,
              "longitude": -97.7852716,
              "is_claimed": true,
              "attributes": {
                "available_attributes": {
                  "accessibility": [
                    "has_wheelchair_accessible_entrance",
                    "has_wheelchair_accessible_parking",
                    "has_wheelchair_accessible_restroom"
                  ],
                  "amenities": [
                    "has_restroom"
                  ],
                  "planning": [
                    "recommends_appointment"
                  ],
                  "payments": [
                    "pay_credit_card",
                    "pay_debit_card",
                    "pay_mobile_nfc"
                  ]
                },
                "unavailable_attributes": null
              },
              "place_topics": {
                "staff": 5,
                "dentist": 4
              },
              "rating": {
                "rating_type": "Max5",
                "value": 5,
                "votes_count": 12,
                "rating_max": null
              },
              "hotel_rating": null,
              "price_level": null,
              "rating_distribution": {
                "1": 0,
                "2": 0,
                "3": 0,
                "4": 0,
                "5": 12
              },
              "people_also_search": [
                {
                  "cid": "11146278870090587681",
                  "feature_id": "0x0:0x9aaf8993ab311e21",
                  "title": "Nichole R. Madison, DDS",
                  "rating": {
                    "rating_type": "Max5",
                    "value": 5,
                    "votes_count": 5,
                    "rating_max": null
                  }
                },
                {
                  "cid": "16695248372791172705",
                  "feature_id": "0x0:0xe7b16ff09922de61",
                  "title": "Madison Family Dentistry, PLLC",
                  "rating": {
                    "rating_type": "Max5",
                    "value": 5,
                    "votes_count": 16,
                    "rating_max": null
                  }
                },
                {
                  "cid": "11268679691675246773",
                  "feature_id": "0x0:0x9c626479bdf620b5",
                  "title": "Balcones Family Dental",
                  "rating": {
                    "rating_type": "Max5",
                    "value": 4.9,
                    "votes_count": 398,
                    "rating_max": null
                  }
                },
                {
                  "cid": "6317261305304287681",
                  "feature_id": "0x0:0x57ab6bafd7fb89c1",
                  "title": "Austin Dentistry",
                  "rating": {
                    "rating_type": "Max5",
                    "value": 4.7,
                    "votes_count": 56,
                    "rating_max": null
                  }
                },
                {
                  "cid": "3146639514814513817",
                  "feature_id": "0x0:0x2bab1bf794ba0299",
                  "title": "myDental at Anderson Mill",
                  "rating": {
                    "rating_type": "Max5",
                    "value": 4.8,
                    "votes_count": 593,
                    "rating_max": null
                  }
                }
              ],
              "work_time": {
                "work_hours": {
                  "timetable": {
                    "sunday": null,
                    "monday": [
                      {
                        "open": {
                          "hour": 9,
                          "minute": 0
                        },
                        "close": {
                          "hour": 13,
                          "minute": 0
                        }
                      },
                      {
                        "open": {
                          "hour": 14,
                          "minute": 0
                        },
                        "close": {
                          "hour": 17,
                          "minute": 0
                        }
                      }
                    ],
                    "tuesday": [
                      {
                        "open": {
                          "hour": 8,
                          "minute": 0
                        },
                        "close": {
                          "hour": 12,
                          "minute": 0
                        }
                      },
                      {
                        "open": {
                          "hour": 13,
                          "minute": 0
                        },
                        "close": {
                          "hour": 16,
                          "minute": 0
                        }
                      }
                    ],
                    "wednesday": [
                      {
                        "open": {
                          "hour": 8,
                          "minute": 0
                        },
                        "close": {
                          "hour": 12,
                          "minute": 0
                        }
                      },
                      {
                        "open": {
                          "hour": 13,
                          "minute": 0
                        },
                        "close": {
                          "hour": 16,
                          "minute": 0
                        }
                      }
                    ],
                    "thursday": [
                      {
                        "open": {
                          "hour": 9,
                          "minute": 0
                        },
                        "close": {
                          "hour": 13,
                          "minute": 0
                        }
                      },
                      {
                        "open": {
                          "hour": 14,
                          "minute": 0
                        },
                        "close": {
                          "hour": 17,
                          "minute": 0
                        }
                      }
                    ],
                    "friday": null,
                    "saturday": null
                  },
                  "current_status": "close"
                }
              },
              "popular_times": null,
              "local_business_links": null,
              "contact_info": [
                {
                  "type": "telephone",
                  "value": "+15123359631",
                  "source": "google_business"
                }
              ],
              "check_url": "https://www.google.com/maps?cid=10608761461000907892&hl=en&gl=US",
              "last_updated_time": "2026-07-06 04:17:45 +00:00",
              "first_seen": "2024-07-28 19:10:18 +00:00",
              "services": null
            }
          ]
        }
      ]
    }
  ]
}

Every listing carries a url and domain field. The records that come back empty or null are your no-website leads, a pitch list you can start working on right away. Swap the category and coordinates and the same request builds that segment for any trade in any city.

Why using the API beats scraping leads from Maps by hand

Doing this by hand costs more than time. It costs consistency. A person copying listings may miss fields or mistype numbers, and can’t easily refresh the list next quarter. The API returns the same structured fields every time, so your data stays clean and easy to rerun.

Cost is the other half of the story. Pricing is $0.01 per request plus $0.0003 per row returned, so a list of 1,000 businesses makes for about $0.31: one task fee plus a thousand rows. You can check the exact math for your own volumes on our pricing page. Since all our APIs are pay-as-you-go, there’s no subscription to justify a one-off campaign and no per-seat cost as your prospecting grows.

Put those together and the choice is easy: a few cents and one request, or an afternoon of scrolling and a list that may already be out of date by the time you finish.

Start pulling business listings with the API

Lead generation comes down to a good list of prospects, and a good list starts with the right businesses. Name a category, name a place, and the Business Listings API hands you every match, with the contact details, ratings, and websites you need to decide who’s worth reaching out to. Filtering and sorting turn that raw list into a campaign you can work on immediately, and pay-as-you-go pricing keeps a one-off prospecting run down to cents. Whether you’re a solo operator building one list or an agency running many, it’s the same single API call.

If you’d rather skip the code, we keep a set of no-code lead enrichment templates that pull business data straight into your CRM through Make. There are prebuilt scenarios for Zoho, Salesforce, Pipedrive, MondayCRM, HubSpot, GoHighLevel, and ActiveCampaign, so you can enrich existing records without wiring up the integration yourself.

Try for free and pull your first prospect list from the sandbox.

Embed DataForSeo widget on your website


Embed code:
Preview: