BBB Business Directory Contacts Scraper
Pricing
from $1.30 / 1,000 business exporteds
BBB Business Directory Contacts Scraper
Search public US BBB business directory cards by category and location. Export names, BBB ratings, categories, phones, addresses, service areas and profile URLs for company vetting.
Pricing
from $1.30 / 1,000 business exporteds
Rating
0.0
(0)
Developer
Automation Lab
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Export public BBB business directory contacts for repeat company vetting and prospect-list maintenance. Search a US business category or keyword and location, then collect business names, BBB ratings, categories, phones, business addresses, service areas and source profile links.
This Actor reads search-result cards, not individual business profiles. It does not extract reviews, complaints, private emails, personal contact enrichment or hidden records. It is independently operated and is not affiliated with or endorsed by the Better Business Bureau.
Who is it for?
- Procurement teams refreshing a supplier shortlist.
- Researchers comparing local business categories and BBB letter ratings.
- Sales operations teams maintaining public business telephone and mailing details.
- Analysts who need source-attributed directory rows rather than a website screenshot.
Why use this Actor?
Each run returns a consistent table with the original search URL, canonical BBB profile URL and extraction timestamp. Categories and service-area summaries remain arrays rather than flattened text. Missing fields stay null or empty arrays; the Actor does not invent contact details.
The workflow deliberately avoids profile-by-profile enrichment. You receive public directory cards with a clear record limit, deduplication and observable failure behavior.
Getting started
- Enter a business category such as
Plumber. - Enter a US city/state or ZIP code, such as
Austin, TX. - Set
maxItemsandmaxPagesfor your required coverage. - Run the Actor and inspect the Business contacts dataset view.
- Export JSON, CSV, Excel or other dataset formats through Apify.
Example input:
{"search":"Plumber","location":"Austin, TX","maxItems":30,"maxPages":5}
US residential proxies are selected automatically and paid by the Actor operator. No proxy subscription, login or source-site credentials are required from you.
Inputs and matching behavior
| Input | Default | Meaning |
|---|---|---|
search | Required | Category or keyword, trimmed and sent to BBB Category search. |
location | Required | US city/state or ZIP, trimmed and passed to BBB. |
maxItems | 30 | Global unique-profile result limit; integer 1–1000. |
maxPages | 5 | Maximum search pages starting at page 1; integer 1–30. |
BBB controls matching, category expansion and result order. search is not a local exact-name, exact-phrase or whole-word filter. Results may include nearby businesses or businesses serving your location; an address need not be inside the exact city boundary.
Unknown fields and invalid values fail validation. There is no explicit-profile URL input, review mode, distance filter or unlimited setting. Zero is not accepted for either limit.
Output fields
| Field | Meaning |
|---|---|
businessName | Business name on the directory card. |
profileUrl | Canonical BBB profile URL and deduplication key. |
categories | Category names supplied by BBB. |
bbbRating | BBB letter rating; not customer-review stars. |
phones | Public business telephone numbers. |
address, city, state, postalCode | Displayed business address components; street address may be withheld. |
hasServiceArea | Whether BBB marks the business as serving an area. |
serviceAreaLabel | Service-area description if supplied; often null. |
serviceAreas | Available summary areas or ZIP codes, not a complete territory boundary. |
isBbbAccredited | BBB directory accreditation flag when present. |
searchUrl | Source search page for this row. |
scrapedAt | UTC extraction time. |
One observed Austin directory record had these public values (timestamps and source query vary):
{"businessName": "Calixto Plumbing","profileUrl": "https://www.bbb.org/us/tx/austin/profile/plumber/calixto-plumbing-0825-1000223803","categories": ["Plumber", "Plumbing Renovation", "Commercial Plumber", "Plumbing Plan"],"bbbRating": "A+","phones": ["(512) 945-3143"],"address": "8410 Georgian Dr # B","city": "Austin","state": "TX","postalCode": "78753-6003","hasServiceArea": true,"serviceAreaLabel": null,"serviceAreas": ["Bell County, TX", "Burnet County, TX", "Lee County, TX", "Milam County, TX", "Travis County, TX", "Williamson County, TX"],"isBbbAccredited": true,"searchUrl": "https://www.bbb.org/search?find_country=USA&find_text=Plumber&find_loc=Austin%2C+TX&find_type=Category&page=1","scrapedAt": "2026-10-21T20:30:00.000Z"}
How much does it cost to export BBB business contacts?
Pricing is pay per event: a $0.005 start fee once per run plus a plan-tier price for each delivered unique business. The BRONZE item price is $0.002164 per business; consult the Pricing tab for the applicable tier. Per-business prices are FREE $0.0024886, BRONZE $0.002164, SILVER $0.0016879, and GOLD/PLATINUM/DIAMOND $0.0012984.
At that BRONZE rate, 1 business is $0.007164, 10 businesses are $0.02664 and 100 businesses are $0.2214. These examples exclude taxes and assume the stated item count is actually returned. An empty or failed run can still incur its start fee; duplicate cards do not incur item charges.
Spend tiers follow qualifying monthly Apify Store spend, not an invented per-Actor volume schedule. Proxy and platform operating costs are included. Any financial estimates are subject to refunds, disputes, fraud, taxes, corrections and contractual clawbacks; they are not guaranteed payouts.
Limits, coverage and failures
BBB currently returns up to 15 cards per search page. Duplicate canonical profiles can occur within and between pages. The Actor keeps the first card for each canonical profile, so multiple branch addresses under one profile are not separately exported. It may visit more pages than ceil(maxItems/15) to reach the requested unique count.
Pagination and stopping rules
Collection stops at the first of: maxItems, maxPages, BBB's reported final page, an empty valid search page, a billing limit or the run deadline. A result limit is a maximum, not a promise of full coverage. Ratings and contact details can change after extraction.
Blocked pages, missing state and malformed cards are errors, not fabricated empty results. Each page gets up to three attempts with fresh US residential Chromium sessions. There is no unbounded retry or paid data-provider fallback. Later page failure leaves earlier rows as partial data and marks the run failed.
Integrations
Export the dataset to a spreadsheet for supplier review, or send completed-run notifications to Make, Zapier or your own webhook. For recurring refreshes, schedule this Actor in Apify and compare stored snapshots downstream using profileUrl as a join key.
The Actor itself does not retain cross-run history, detect changes, send alerts or contact businesses. Keep full exports in your data pipeline when comparing larger lists.
API usage
Use a managed Apify token in an environment variable; do not embed tokens in shared scripts.
curl -X POST \-H "Authorization: Bearer $APIFY_TOKEN" \-H 'Content-Type: application/json' \'https://api.apify.com/v2/acts/automation-lab~bbb-business-directory-contacts/runs' \-d '{"search":"Plumber","location":"Austin, TX","maxItems":30,"maxPages":5}'
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('automation-lab/bbb-business-directory-contacts').call({search: 'Plumber', location: 'Austin, TX', maxItems: 30, maxPages: 5});const { items } = await client.dataset(run.defaultDatasetId).listItems({ limit: 30 });
Python:
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ['APIFY_TOKEN'])run = client.actor('automation-lab/bbb-business-directory-contacts').call(run_input={'search': 'Plumber', 'location': 'Austin, TX', 'maxItems': 30, 'maxPages': 5})items = client.dataset(run['defaultDatasetId']).list_items(limit=30).items
MCP: Claude Code, Claude Desktop, Cursor and VS Code
Claude Code:
$claude mcp add --transport http apify "https://mcp.apify.com?tools=automation-lab/bbb-business-directory-contacts"
Claude Desktop, Cursor and VS Code can use the equivalent HTTP-server configuration in their supported MCP settings (the wrapper key can differ by client):
{"mcpServers":{"apify":{"url":"https://mcp.apify.com?tools=automation-lab/bbb-business-directory-contacts"}}}
Example prompt: “Search BBB for plumbers serving Austin, TX; collect at most 30 businesses over five pages, then show names, BBB ratings, phones and profile links.” Authenticate using your client's supported secure Apify flow.
Discover actual tool names and schemas with tools/list. Selecting this Actor also adds run/data helpers; it does not expose exactly one tool. Discovery is read-only, not authorization to run.
For an authorized invocation, start once and keep the returned run ID and dataset ID. They are metadata, not rows. If still running after the server wait (at most 45 seconds), check that same run with bounded 2/4/8-second backoff capped at 10 seconds and a 120-second consumer deadline. Set client timeout above the selected wait plus transport margin. On timeout, recover the known run rather than starting another; if its ID is unknown, report uncertainty. At deadline report pending and stop. Report terminal failures and any partial rows honestly.
After success, read bounded dataset pages: for example 20 rows at a time, at most 100 rows and 64 KiB serialized UTF-8 content admitted to model context. Enforce byte limits host-side before model injection; summarize or omit oversized pages with disclosure. Track source offsets, stop at exhaustion/budget and report continuation offset and truncation. If your client cannot intercept oversized responses, do not claim a hard byte guarantee. Full exports belong in storage, not model context. Client discovery/caching varies; no numeric token savings are promised.
Legality, responsible use and privacy
Use public business data only for a lawful, appropriate purpose and comply with source terms, privacy rules and marketing laws. Public availability is not consent for unsolicited contact. The Actor does not make legal or procurement decisions for you.
Inputs are sent to BBB through Apify's US residential proxy network. Business names, public business phones, addresses and source links are written to your run's default dataset. Some businesses are sole traders, so public business details can still be personal data. The Actor does not extract private email addresses, reviews, complaints or other profile enrichment.
The runtime uses no AI model. The generated illustration is a development asset, not an inference service processing your inputs or scraped records. Browser sessions are ephemeral and closed after each attempt; there is no cross-run contact cache. Dataset and log retention follows your Apify account's storage settings. Delete datasets, key-value stores and runs through Apify when no longer needed; the Actor does not independently erase your saved exports.
Diagnostics and retention
Failed operations send sanitized diagnostic input, exceptions and Actor/build/run IDs to our private GlitchTip service for repair. Secret fields and URL queries are removed and reports are retained for 30 days. Normal logs contain counters and safe status summaries, not contact rows or proxy credentials.
FAQ and troubleshooting
Why are fewer businesses returned than requested? BBB may have fewer results, duplicate profiles, a source page cap or a run/billing limit. Increase maxPages within its supported range only when more source pages exist.
Why is an address or service-area label null? BBB does not supply every field for every card. Null does not mean the business lacks that information elsewhere.
Why does a plumber query include another primary category? BBB category expansion can return a business with multiple categories. Inspect the categories array and source page; this is not exact primary-category filtering.
What if the run fails with a directory HTTP or search-state error? The source may be challenging the browser or changing its format. The Actor already retries with fresh sessions. Do not interpret an earlier partial dataset as a complete search. Report the run ID to support.
Can I get reviews, complaint histories or private contacts? No. This product exports public directory cards only.
Related workflows and support
For other public business-directory workflows, browse the automation-lab portfolio. Coverage and fields vary by Actor; this tool does not combine other directories automatically.
Open an issue on this Actor's Apify page and include the run ID, expected behavior and a safe input example. Do not include credentials or private customer data. We aim to provide a substantive response to user-reported Store issues within 14 calendar days.