BBB Scraper — Better Business Bureau Ratings, Complaints, Leads
BBB's directory, not just the accredited shop window.
Better Business Bureau business profiles for the United States and Canada, read from BBB's own sitemaps and profile pages rather than only from its search box. Up to 76 fields per business: letter rating, accreditation, complaint and review counts, years in business, legal entity type, owners and officers, phone, website and coordinates.
oswaldocarabano/bbb-business-scraper
{
"searchTerms": ["plumber"],
"locations": ["Austin, TX"],
"maxItems": 100,
"fetchProfiles": true
}- Version
- v0.1.13
- Memory
- 512 MB
- Browser
- none
- Proxy
- None needed: plain HTTP, no login
Short answer
The BBB Scraper extracts Better Business Bureau business profiles for the United States and Canada with up to 76 fields per business: letter rating, accreditation, complaints closed in the last three years and twelve months, review count and average stars, years in business, legal entity type, owners and officers, phone, website and coordinates. Profile fields were measured on 120 profiles sampled from BBB's sitemap: phone 97.5%, owners 71.7%, website 53.3%. BBB's search box and its directory describe different markets: 96.7% of 1,411 search results were accredited, against 0% of a 200-profile sample from the general sitemap, because accredited businesses sit in a separate sitemap. Pricing is $0.003 per business plus $0.006 for the full profile.
Key points
- The BBB Scraper returns up to 76 fields per business, 35 of which exist only on the profile page and not in BBB's search results.
- BBB's search box returned 96.7% accredited and 90.8% A+ businesses across 1,411 results, so a dataset built from search alone describes BBB's paying members rather than the market.
- A 200-profile sample from BBB's general profile sitemap was 0% accredited, 47.5% A+ and 45% not rated; accredited businesses are published in a separate sitemap of 39 files.
- Owners and officers appear on 71.7% of 120 sampled profiles, and websites on 53.3%, so neither should be treated as always present.
- Review and complaint text is never collected: the output carries counts and the average star rating, not anything a consumer wrote.
- BBB's email address is obfuscated on the page and the Actor does not reverse it; the output carries a `has_email` flag instead.
- BBB's search filter accepts single letters only, so asking it for `A+` returns zero results; the Actor's `ratings` input therefore takes A to F.
What it does
Better Business Bureau business profiles for the United States and Canada, read from BBB's own sitemaps and profile pages rather than only from its search box. Up to 76 fields per business: letter rating, accreditation, complaint and review counts, years in business, legal entity type, owners and officers, phone, website and coordinates.
{
"business_name": "Example Plumbing LLC",
"legal_name": "Example Plumbing LLC",
"category_name": "Plumber",
"category_id": "10113-000",
"rating": "A+",
"rating_score": 100,
"is_accredited": true,
"accreditation_date": "2024-12-02",
"complaints_closed_3y": 0,
"complaints_closed_12m": 0,
"reviews_total": 1,
"review_average_stars": 5,
"years_in_business": 5,
"type_of_entity": "Limited Liability Company (LLC)",
"business_started": "2020-05-01",
"principals": [{ "name": "Example Owner", "title": "Managing Member" }],
"phone": ["(512) 555-0123"],
"phone_e164": ["+15125550123"],
"website": "https://example.com/",
"city": "Austin",
"state": "TX",
"postal_code": "78748",
"latitude": 30.3,
"longitude": -97.76,
"has_email": true,
"accepts_quote_requests": true,
"report_url": "https://www.bbb.org/us/tx/austin/profile/plumber/example-0825-1000000000"
}Why this one
The directory, not the shop window
BBB's search box is dominated by accredited businesses, which pay BBB a fee for accreditation: 96.7% of 1,411 search results were accredited. The BBB Scraper also reads BBB's profile sitemaps — 575 files of 10,000 profiles — which is the only route that reaches businesses BBB does not promote. The difference is measured rather than asserted, with both sample sizes published.
Profile fields, not just search fields
A BBB search result carries roughly the fields a listing card shows. The profile page adds 35 more: complaints closed in three years and twelve months, years in business, legal entity type, incorporation date, owners and officers, alternate trading names and every location. `fetchProfiles` is on by default and is billed as its own event, so leaving it off is a real saving.
Filters that actually filter
BBB's search API has an accredited parameter that it silently ignores. The `onlyAccredited` input reads BBB's own accredited listings instead, and on Austin plumbers it narrowed 2,409 businesses to 505. The `ratings` input accepts the single letters BBB honours, because BBB returns nothing for `A+` even though 90.8% of search results carry it.
Columns removed rather than shipped empty
Four fields BBB returns — `score`, `outOfBusinessStatus`, `serviceAreaDescription` and `accreditationStatus` — were filled on 0% of the measured sample, and three more were 0.0% on the profile sample. None of them is in the output, because a column that is always empty is the appearance of data rather than data.
Use cases
- Build B2B lead lists of local service businesses by trade, city or state, with phone, website and address ready for a CRM.
- Screen a vendor before signing: letter rating, accreditation, complaints closed in three years and twelve months, years in business and entity type.
- Enrich an existing CRM by matching on name and city and appending rating, complaint counts and owners.
- Track a market on a schedule and watch ratings, accreditation and complaint counts move.
- Measure how far BBB's accredited members differ from the rest of a local market, using the sitemap and accredited sitemap separately.
Input
Every field has a default, and the defaults are deliberately small so a first run is cheap enough to inspect before you commit to a sweep. This table mirrors the Actor's own input schema field for field.
| Field | Default | What it does |
|---|---|---|
searchTermsstring[] | [] | Category or tradeWhat kind of business to look for, such as `plumber`, `roofing` or `dentist`. Matches BBB's own category names. |
locationsstring[] | [] | CitiesCities as `City, ST`, such as `Austin, TX`. Leave empty to cover whole states, or everything. |
statesstring[] | [] | States or provincesTwo-letter codes such as `TX`, `CA` or `ON`, for a whole state rather than single cities. |
countrystring | USA | Country`USA` or `CAN`. BBB covers the United States and Canada. |
maxItemsinteger | 100 | Maximum businessesHow many businesses to return. Charged per business delivered, never for failed rows. Hard cap 50,000 per run. |
onlyAccreditedboolean | false | Only BBB Accredited businessesUses BBB's own accredited listings rather than the search API's accredited parameter, which BBB ignores. Measured on Austin plumbers: 2,409 businesses down to 505. |
fetchProfilesboolean | true | Include full profile datapersonal dataFetches each business's profile page and adds about 35 fields: website, years in business, legal form, complaint and review counts, owners and officers, every location. One extra request per business, billed as its own event. |
modestring | auto | How to find businesses`auto`, `sitemap`, `category` or `search`. `auto` uses category pages when a trade and a place are both set, and the sitemap otherwise. Only the sitemap reaches the whole directory. |
ratingsstring[] | [] | Only these BBB letter ratingsSingle letters A, B, C, D or F; a letter covers its family. BBB returns zero results for `A+`, so it is not accepted. |
onlyQuoteRequestsboolean | false | Only businesses that accept quote requestsKeeps businesses that take quote requests through BBB, a commercial-intent signal. |
sortOrdersstring[] | ["AToZ", "ZToA"] | Sort orders to sweep (search mode)BBB caps every query at 225 results. Sweeping A-Z and Z-A reaches up to 450 distinct businesses per query. |
includeCategoriesboolean | false | Also export BBB's category taxonomyWrites BBB's category tree to a separate dataset, at the platform minimum price. |
maxConcurrencyinteger | 4 | Parallel requestsKept deliberately low. BBB served 20 consecutive requests without a block in testing, and the default starts under that rather than hunting for the ceiling. |
Output and fill rates
A field being in the schema is not the same as it having a value. The percentages below were counted on real runs; the sample sizes are in Measurements. Anything not listed here is not promised.
| Field | Filled | Meaning |
|---|---|---|
business_namestring | 100% | With `legal_name`, `category_name`, `category_id` and every category BBB assigns in `categories`. |
ratingstring | 100% | BBB's letter rating, A+ to F, or NR for not rated. With `rating_score`. In a 200-profile sitemap sample, 45% were NR. |
is_accreditedboolean | 100% | BBB accreditation status. 96.7% true in 1,411 search results, 0% in 200 general-sitemap profiles. |
complaints_closed_3yinteger | 100% | With `complaints_closed_12m` and `complaints_total`. Counts only, never complaint text. |
reviews_totalinteger | 100% | With `review_average_stars`. Counts and the average only, never review text. |
years_in_businessinteger | 100% | With `type_of_entity`, `bbb_file_opened` and the local BBB. Profile field, measured on 120 sitemap profiles. |
phonestring[] | 97.5% | With `phone_e164`. Profile sample of 120. |
addressstring | 87.5% | Street address, with `city`, `state`, `postal_code`, `latitude` and `longitude`, which were filled on every sampled row. |
business_starteddate | 82.5% | When the business says it started. Profile sample of 120. |
service_areas_summarystring[] | 73% | Counties or ZIP codes served. Measured on 1,411 businesses from BBB's search, which skews accredited. |
principalsobject[] | 71.7% | Owners and officers, name and title, as BBB publishes them. Personal data in the EU and UK. |
websitestring | 53.3% | Profile sample of 120. |
logo_urlstring | 36.3% | Measured on 1,411 businesses from BBB's search. |
business_incorporateddate | 35% | Incorporation date. Profile sample of 120. |
accreditation_datedate | 22.5% | Profile sample of 120, a general-sitemap sample in which almost no business is accredited. |
alternate_namesstring[] | 18.3% | Other trading names. Profile sample of 120. |
products_and_servicesstring | 14.2% | Profile sample of 120. `business_description` was 11.7% on the same sample. |
has_emailboolean | 100% | Whether BBB shows an email. The address itself is obfuscated by BBB and is not reconstructed. |
report_urlstring | 100% | The BBB profile URL, with `fetched_at` and `from_cache` describing the row's age. |
Every key is always present. A field that exists but is empty comes back as explicit null, so a parser never has to guess.
Datasets
Different record types go to different datasets, so the main table never carries columns that are blank on most rows.
defaultOne row per business, up to 76 fields, with four views: Overview, Contact, Trust signals and Everything.billedcategoriesBBB's own category taxonomy: code, name, family and where it was seen. Only when `includeCategories` is on.billederrorsWhat could not be fetched, and why.never billed
Pricing
Pay per delivered result. Charges are applied as each row is produced rather than in a lump at the end, so an aborted run bills only for what it actually gave you.
| Event | Price | Notes |
|---|---|---|
apify-actor-startActor start | $0.00001 | The platform minimum, a thousandth of a cent. |
businessBusiness delivered | $0.003 | One business row: BBB rating, accreditation, category, phone, address and coordinates. Error rows are never charged. |
business_profileFull profile data | $0.006 | Adds 35 profile fields to a business: complaints and reviews closed, years in business, legal entity type, owners, website and every location. |
categoryCategory row | $0.00001 | One row of BBB's category taxonomy, only when you ask for it. Set at the platform minimum because Apify does not accept a zero price. |
Measurements
Each figure is shown with the method that produced it. A benchmark without a method is a marketing claim wearing a number's clothes.
Profile fill-rate sample
120 profiles from BBB's sitemap
Drawn from 6 different files of the profile sitemap index, 0 failures and 0 blocks. Every profile-field rate on this page comes from that sample.
Listing fill-rate sample
1,411 businesses from BBB's search
BBB's own search results, measured on 18 September 2026. Used only for the listing fields marked as such, because the sample skews accredited.
Search box against directory
96.7% accredited in search, 0% in the general sitemap
1,411 search results against 200 profiles from 10 files of the general profile sitemap. Accredited businesses have their own sitemap of 39 files, which is why the general one samples at 0%.
A+ share
90.8% in search, 47.5% in the general sitemap
Same two samples. 45% of the 200 sitemap profiles were not rated (NR).
Directory size
about 5.75 million profiles
575 sitemap files of exactly 10,000 profile URLs each, counted on 18 September 2026. A count of URLs BBB publishes, not of active businesses.
Throughput
1,000 businesses in 120 seconds
One platform run at concurrency 6: 1,007 requests, 0 blocks, 0 timeouts, 0 retries.
Accredited filter
2,409 to 505 businesses
Austin plumbers with and without `onlyAccredited`, which reads BBB's accredited listings because the search API's own accredited parameter is ignored.
What it will not do
Stated plainly so you can judge fit before spending anything.
- No review or complaint text, only counts and the average star rating. The text is written by identifiable consumers and is not republished.
- No email addresses. BBB obfuscates them to stop harvesting, and the output carries `has_email` instead.
- Canada is supported but unmeasured: every fill rate on this page comes from US samples.
- BBB caps a search or category query at 15 pages of 15, which is 225 businesses; sweeping A-Z and Z-A together reaches up to 450 per query.
- A city filter is strict only where BBB has a city category page. When a trade has none, the Actor falls back to BBB's search, which covers the surrounding metro area.
- BBB's robots.txt disallows every URL with a query string (`Disallow: /*?`) while explicitly allowing profile pages. Sitemap discovery and profile pages fall inside what it allows; the `search` mode and paginated category pages use query strings that it disallows.
- BBB's terms of use license the site for direct use and not for sale, republication or aggregation. Read them before building a product on the output.
- A single run is capped at 50,000 businesses.
Privacy
- Business profiles include the names and titles of owners and officers as BBB publishes them, on 71.7% of 120 sampled profiles. In the EU and UK that is personal data, and the buyer needs a lawful basis to process it.
- Consumer reviews and complaint texts are not collected, only their counts.
- Email addresses are not reconstructed from BBB's obfuscation.
- Removal requests: privacy@actorstack.dev
See also the data removal process.