BBB Scraper (Reviews, Complaints and Grades, No Login) avatar

BBB Scraper (Reviews, Complaints and Grades, No Login)

Pricing

from $0.28 / 1,000 reviews

Go to Apify Store
BBB Scraper (Reviews, Complaints and Grades, No Login)

BBB Scraper (Reviews, Complaints and Grades, No Login)

Scrape BBB reviews, customer complaints and business profiles: stars, review text, business replies, complaint type and status, BBB grade, accreditation and years in business. Rank any business against its local rivals and get only new reviews on schedules. No login. From $0.50 per 1,000 rows.

Pricing

from $0.28 / 1,000 reviews

Rating

0.0

(0)

Developer

locaihost data

locaihost data

Maintained by Community

Actor stats

0

Bookmarked

6

Total users

6

Monthly active users

2 days ago

Last modified

Share

Get Better Business Bureau data for any US or Canadian business as clean JSON or CSV rows: customer reviews with the business's replies, complaints with the whole exchange, and a business row with BBB grade, accreditation, complaint counts, phone and address. No login, no cookies, no account.

  • Check a company before you deal with it: BBB grade, accreditation date, complaint counts and alerts next to its newest reviews and complaints.
  • Size up a business in one row: turn on Add a reputation summary per business for its complaint trend, how many complaints it answered and resolved, how fast it replies, its top complaint types and its star mix. See Reputation summary.
  • Rank a business against its local competitors: turn on Benchmark against local competitors for its rank among businesses with the same BBB category in the same city, plain-English highlights and the competitor list. See Competitor benchmark.
  • Find trade licences about to expire: set Licences expiring within to list businesses whose licence ends in the next 30, 60 or 90 days. See Licence expiry watch.
  • Monitor your own BBB profile: schedule it daily with onlyNew and get only the reviews and complaints filed since the last run.
  • Read what customers complain about: complaint type, status and the business's response for a competitor, ready to group and count.
  • Build a list of local businesses: search BBB by trade and city ("plumber" near "Austin, TX", or several cities and ZIP codes at once) and get grade, accreditation, category, phone, address and approximate map position for each. Keep only accredited ones if you like.
  • Feed analysis and dashboards: one flat row per review or complaint, with the same review columns as our Trustpilot and Sitejabber scrapers.

Quick start

Paste this into the JSON tab of the input and click Start:

{"businesses": ["https://www.bbb.org/us/wa/seattle/profile/ecommerce/amazoncom-1296-7039385"], "maxReviewsPerBusiness": 20, "maxComplaintsPerBusiness": 10}

You get one business row, the 20 newest reviews and the 10 newest complaints: 31 rows in about 30 seconds. A link to the business's reviews or complaints page works too.

More examples:

{"searchQueries": ["plumber"], "searchLocation": "Austin, TX", "maxBusinessesPerSearch": 50}
{"searchQueries": ["roofing contractor"], "searchLocation": "Denver, CO", "maxBusinessesPerSearch": 20, "detailsForFoundBusinesses": true, "maxReviewsPerBusiness": 10, "maxComplaintsPerBusiness": 10}
{"searchQueries": ["electrician"], "searchLocation": "Austin, TX", "searchLocations": ["Round Rock, TX", "78701"], "maxBusinessesPerSearch": 100, "accreditedOnly": true}
{"businesses": ["https://www.bbb.org/us/wa/seattle/profile/ecommerce/amazoncom-1296-7039385"], "maxReviewsPerBusiness": 0, "maxComplaintsPerBusiness": 500, "dateFrom": "90 days"}

What data can I get?

Every row has type: review, complaint, business, summary (with Add a reputation summary per business), benchmark (with Benchmark against local competitors), or not-found (free, says what to change).

GroupFields
ReviewreviewId, rating (1 to 5), text, publishedAt, reviewerName (the display name BBB shows, like "Robert S")
Review repliesreplyText, replyPublishedAt (the business's reply), reviewerFollowUpText, reviewerFollowUpAt, businessFollowUpText, businessFollowUpAt
ComplaintcomplaintId, complaintType (like "Delivery Issues"), status (Resolved, Answered, Unanswered and so on), filedAt, text
Complaint exchangebusinessResponseText, businessResponseAt (the first response), messages (the whole exchange in order: from, date, text)
Business gradebusinessId, name, bbbRating (A+ to F, or NR), isAccredited, accreditedSince, stars, reviewCount
Complaint countscomplaintCount (BBB stops counting at 10,000), complaintsClosedLast12Months, complaintsClosedLast3Years, alertCount (government actions and other alerts BBB shows)
Business detailsprimaryCategory, categories, phone, email (only if the business publishes one), address, city, state, zipCode, country, websiteUrl, domain, yearsInBusiness, businessStartedAt, legalEntityType, employees, isClosed, localBbb
Map positionlatitude, longitude: where BBB places the business. BBB rounds many to 2 decimals (about 1 km, often the city centre), so treat them as approximate
Licenceslicenses: each licence BBB lists, with number, agency (like "Texas State Board of Plumbing Examiners") and expiresAt. From the business's own page, so search rows have it only with Full details for businesses found
Reputation summaryOne summary row per business: complaint trend, answered and resolved shares, response days, top complaint types, star mix, reply rate. Fields in Reputation summary
Competitor benchmarkOne benchmark row per business: rank among local competitors, rank and percentile per measure, highlights, competitor list. Fields in Competitor benchmark
Licence watchlicenseExpiresInDays, licenseStatus, licenseAgencies, expiringLicenses on business rows, with Licences expiring within. Fields in Licence expiry watch
ContextcompanyName, companyDomain, reviewUrl, complaintsUrl, companyUrl, source, query, searchLocation, rank, input, scrapedAt

Review rows use the same columns as our Trustpilot and Sitejabber review scrapers (fields BBB doesn't have, like title or reviewerCountry, are null), so you can stack the outputs into one table.

Real rows from one run (2026-10-18, shortened):

[
{
"type": "review",
"site": "bbb",
"reviewId": "1296_7039385_889440",
"companyName": "Amazon.com",
"companyDomain": "amazon.com",
"rating": 1,
"text": "Worked for their fulfillment center and I just read a job description that said work in a supported team environment? Never have I been supported in the two years I have been employed with Amazon...",
"publishedAt": "2026-10-10",
"replyText": null,
"reviewUrl": "https://www.bbb.org/us/wa/seattle/profile/ecommerce/amazoncom-1296-7039385/customer-reviews#1296_7039385_889440"
},
{
"type": "complaint",
"site": "bbb",
"complaintId": "1296_7039385_25375731",
"companyName": "Amazon.com",
"complaintType": "Delivery Issues",
"status": "Resolved",
"filedAt": "2026-10-11",
"text": "Placed order June 23 for 4 items. Returned all 4 items June 26 through ******* which stopped providing receipts for Amazon returns. Only refunded for 3 items...",
"businessResponseText": "Hello *****,\n\nI'* ***** ***** from Amazon.com. I'm writing in response to a complaint filed on your behalf by the Better Business Bureau...",
"businessResponseAt": "2026-10-12",
"messages": [
{"from": "business", "date": "2026-10-12", "text": "Hello *****, ..."},
{"from": "consumer", "date": "2026-10-13", "text": "Hi BBB,\n\nI'm satisfied with the business's resolution to complaint ID ********. ..."}
]
},
{
"type": "business",
"site": "bbb",
"businessId": "1296-7039385",
"name": "Amazon.com",
"bbbRating": "A+",
"isAccredited": true,
"accreditedSince": "1996-08-01",
"stars": 1.11,
"reviewCount": 4694,
"complaintCount": 10000,
"complaintsClosedLast12Months": 17345,
"complaintsClosedLast3Years": 61018,
"alertCount": 4,
"primaryCategory": "Ecommerce",
"phone": "(888) 280-4331",
"address": "202 Westlake Ave N Ste 2",
"city": "Seattle",
"state": "WA",
"zipCode": "98109-5264",
"country": "US",
"websiteUrl": "https://www.amazon.com",
"yearsInBusiness": 31,
"legalEntityType": "Corporation",
"localBbb": "BBB Great West + Pacific",
"latitude": 47.620049,
"longitude": -122.338104,
"licenses": [{"number": "601720490", "agency": "Washington Secretary of State", "expiresAt": null}],
"source": "company"
}
]

The dataset has seven views (Reviews, Complaints, Businesses, Summary, Competitor benchmark, Licence expiry watch, Not found (free)) and exports to JSON, CSV, Excel or HTML. The run's SUMMARY record has pages read, rows by kind, free rows by reason and timing.

Reputation summary

Other BBB scrapers give you raw rows. Turn on Add a reputation summary per business ("includeSummary": true) and each business also gets one summary row, worked out from the reviews and complaints the run read for it. Nothing extra is fetched for it, and it holds counts only: no consumer names and no review or complaint text.

{"businesses": ["https://www.bbb.org/us/wa/seattle/profile/ecommerce/amazoncom-1296-7039385"], "maxReviewsPerBusiness": 100, "maxComplaintsPerBusiness": 500, "includeSummary": true}
FieldWhat it is
bbbRating, isAccredited, accreditedSince, yearsInBusiness, businessStartedAtBBB grade and accreditation, years in business
stars, reviewCount, complaintCountBBB's own average and totals, for scale
periodFrom, periodToThe days the numbers cover. periodTo is the day of the run
basisHow many complaints and reviews the numbers come from and how far back, so a small sample is obvious
complaintsRead, complaintsFrom, complaintsCompleteComplaints read, the day they are complete from, and whether every complaint BBB shows was read
complaintsByMonthThe last 12 calendar months, oldest first: month, count, partial. A month the run didn't read back to is null, not 0. The current month is month to date
complaintsLast90Days, complaintsPrior90Days, complaintTrendPctComplaints in the last 90 days, the 90 before, and the change in percent. null when the read doesn't reach back 180 days
complaintsAnsweredShareShare (0 to 1) the business responded to: a public reply, or BBB status Resolved, Answered or Unresolved
complaintsResolvedShare, complaintsAnsweredNotResolvedShare, complaintsUnresolvedShareBBB's own statuses: Resolved; Answered (the business responded, the customer didn't accept or didn't reply); Unresolved or Unanswered
complaintStatusCountsComplaints per BBB status, as BBB spells it
medianResponseDays, p90ResponseDaysDays from a complaint being filed to the business's first public reply: median and 90th percentile
topComplaintTypesUp to 5 most common complaint types, with counts
reviewsRead, reviewsFrom, reviewsCompleteThe same for reviews
averageStars, starCountsAverage stars and the count per star ("1" to "5") of the reviews read
reviewsRepliedShare, reviewsByMonthShare of reviews with a business reply, and reviews per month

Real summary row for Amazon.com from a run with 200 complaints and 50 reviews (2026-10-20, months shortened to the last 3). 200 complaints cover about two weeks for Amazon, so the 90-day trend is null; for a business whose whole list was read it is filled in:

{
"type": "summary",
"site": "bbb",
"businessId": "1296-7039385",
"companyName": "Amazon.com",
"companyDomain": "amazon.com",
"bbbRating": "A+",
"isAccredited": true,
"accreditedSince": "1996-08-01",
"yearsInBusiness": 31,
"businessStartedAt": "1995-07-01",
"stars": 1.1,
"reviewCount": 4693,
"complaintCount": 10000,
"periodFrom": "2026-10-01",
"periodTo": "2026-10-20",
"basis": "Complaints: the newest 200 of 10,000+ (2026-10-01 to 2026-10-16). Reviews: the newest 50 of 4,693 (2026-10-06 to 2026-10-15).",
"complaintsRead": 200,
"complaintsComplete": false,
"complaintsFrom": "2026-10-01",
"complaintsByMonth": [
{"month": "2026-08", "count": null, "partial": false},
{"month": "2026-09", "count": null, "partial": false},
{"month": "2026-10", "count": 200, "partial": false}
],
"complaintsLast90Days": null,
"complaintsPrior90Days": null,
"complaintTrendPct": null,
"complaintsAnsweredShare": 1,
"complaintsResolvedShare": 0.39,
"complaintsAnsweredNotResolvedShare": 0.61,
"complaintsUnresolvedShare": 0,
"complaintStatusCounts": {"Resolved": 78, "Answered": 122},
"medianResponseDays": 2,
"p90ResponseDays": 6,
"topComplaintTypes": [
{"complaintType": "Product Issues", "count": 78},
{"complaintType": "Service or Repair Issues", "count": 47},
{"complaintType": "Delivery Issues", "count": 33},
{"complaintType": "Billing Issues", "count": 24},
{"complaintType": "Sales and Advertising Issues", "count": 9}
],
"reviewsRead": 50,
"reviewsComplete": false,
"reviewsFrom": "2026-10-06",
"averageStars": 1.04,
"starCounts": {"1": 49, "2": 0, "3": 1, "4": 0, "5": 0},
"reviewsRepliedShare": 0,
"reviewsByMonth": [
{"month": "2026-08", "count": null, "partial": false},
{"month": "2026-09", "count": null, "partial": false},
{"month": "2026-10", "count": 50, "partial": true}
],
"companyUrl": "https://www.bbb.org/us/wa/seattle/profile/ecommerce/amazoncom-1296-7039385",
"input": "https://www.bbb.org/us/wa/seattle/profile/ecommerce/amazoncom-1296-7039385",
"scrapedAt": "2026-10-20T03:47:54.922Z"
}

Complaint themes (added 2026-10-21). Every summary row also has complaintThemesByMonth, risingThemes and themeSummary, worked out from the complaints already read (no extra pages):

FieldWhat it is
complaintThemesByMonthThe last 12 months, oldest first: month, types (complaints per BBB complaint type that month, null for months the run didn't read back to) and partial
risingThemesComplaint types with at least 3 complaints in the last 90 days and at least twice as many as in the 90 days before: complaintType, last90Days, prior90Days. An empty list means none are rising. null when the read doesn't reach back 180 days
themeSummaryOne plain sentence, like the one below

From a real run on a large plumbing company (300 complaints read, 2025-05-23 to 2026-10-11):

{
"risingThemes": [],
"themeSummary": "Service or Repair Issues is the most common complaint type (223 of 300 read). No complaint type has at least doubled over the last 90 days.",
"complaintThemesByMonth": [
{"month": "2026-08", "types": {"Service or Repair Issues": 20, "Customer Service Issues": 2, "Billing Issues": 2}, "partial": false},
{"month": "2026-09", "types": {"Billing Issues": 7, "Service or Repair Issues": 16}, "partial": false}
]
}

Raise Max complaints per business to read back at least 180 days, otherwise risingThemes stays null instead of guessing.

How to read it:

  • The numbers cover only what the run read. Lists come newest first, so the review and complaint limits set how far back a summary reaches. For a big company, 500 complaints may be a few weeks; for a local business, 100 is usually its whole history (complaintsComplete: true). basis always says which.
  • Items left out of the output by Star ratings or Only with a business response still count, because the run read them. Published on or after sets where the period starts.
  • With Only new since the last run, the summary covers what is new since the last run, and a business with nothing new gets no summary (and no charge).
  • For businesses found by a search, turn on Full details for businesses found: without it the run reads no reviews or complaints, so there is nothing to summarise.
  • Summary rows count towards Max rows in total and the run's maximum cost. A summary is sent once a business's lists are read, so a run that stops at either limit first returns no summary for that business.

Competitor benchmark

Turn on Benchmark against local competitors ("benchmarkCompetitors": true) and each business gets one benchmark row: where it stands among businesses with the same BBB category in the same city. It works with business links and with searches.

{"businesses": ["https://www.bbb.org/us/az/phoenix/profile/roofing-contractors/elevate-roofing-pros-llc-1126-1000126260"], "benchmarkCompetitors": true, "competitorsToCompare": 10, "maxReviewsPerBusiness": 0, "maxComplaintsPerBusiness": 0, "includeBusinessInfo": false}

That input returns the benchmark row only. Leave the limits at their defaults and you also get the business's own reviews, complaints and business row.

{"searchQueries": ["roofing contractor"], "searchLocation": "Phoenix, AZ", "maxBusinessesPerSearch": 5, "benchmarkCompetitors": true, "maxReviewsPerBusiness": 0, "maxComplaintsPerBusiness": 0}

How the competitors are chosen: the run searches BBB for the business's primary category near its city, keeps businesses with the same primary category whose BBB link is in the same city, and takes the first Competitors to compare (3 to 25, default 10). If the city has fewer than 3, it uses other businesses in the same state and cohortScope says so. Fewer than 3 competitors found gives a free not-found row instead of a benchmark.

FieldWhat it is
rankOverall, overallRank, overallOf, overallPercentilePosition among the business and its competitors, like "5 of 11" (1 is best), and the share of competitors it beats (0 to 100, ties count half). The overall rank averages the percentiles of the measures below
benchmarkMetricsOne entry per measure: grade, stars, complaintsLast12Months, answeredShare, resolvedShare, avgResponseDays. Each has value, rank (1 is best), of, percentile, betterThan, tiedWith, worseThan, cohortMedian, higherIsBetter. rank is null when the business has no figure or fewer than 3 businesses do
highlights2 to 4 plain sentences, like "Slower to reply than 8 of 10 local competitors (6 days on average)"
cohortThe competitors, best overall first: name, url, grade, stars, complaintsLast12Months, avgResponseDays, isAccredited, overallRank
cohortScope, competitorsCompared, primaryCategory, city, state, basisWhere the competitors are, how many, and how the numbers were worked out

Real row (2026-10-20, shortened to two competitors and three measures):

{
"type": "benchmark",
"companyName": "Elevate Roofing Pros LLC",
"primaryCategory": "Roofing Contractors",
"cohortScope": "Phoenix, AZ",
"competitorsCompared": 10,
"rankOverall": "5 of 11",
"overallRank": 5,
"overallPercentile": 55,
"highlights": [
"BBB grade A is below 7 of 10 local competitors",
"Rated higher than 5 of 9 local competitors (5 stars)"
],
"benchmarkMetrics": [
{"metric": "grade", "value": "A", "rank": 8, "of": 11, "percentile": 15, "betterThan": 0, "tiedWith": 3, "worseThan": 7, "cohortMedian": "A+"},
{"metric": "stars", "value": 5, "rank": 1, "of": 10, "percentile": 78, "betterThan": 5, "tiedWith": 4, "worseThan": 0, "cohortMedian": 4.94},
{"metric": "complaintsLast12Months", "value": 0, "rank": 1, "of": 11, "percentile": 65, "betterThan": 3, "tiedWith": 7, "worseThan": 0, "cohortMedian": 0}
],
"cohort": [
{"name": "BL Roofing LLC", "grade": "A+", "stars": 5, "complaintsLast12Months": 0, "avgResponseDays": null, "isAccredited": true, "overallRank": 1},
{"name": "Reyes Roofing LLC", "grade": "A+", "stars": 4.94, "complaintsLast12Months": 1, "avgResponseDays": 8, "isAccredited": true, "overallRank": 4}
]
}

Honest limits:

  • Grade, stars and complaintsLast12Months (complaints BBB closed in the last 12 months) are BBB's own figures. The answered, resolved and reply-time measures come from each business's newest page of complaints (up to 10), keeping those filed in the last 12 months. Small local businesses often have none, so those three measures are frequently not ranked. of says how many businesses had a figure.
  • Counts are not adjusted for business size: a large company with more customers has more complaints.
  • Competitors are the ones BBB's search returns first (it lists accredited businesses first), not every business in the city.
  • Each benchmark reads about 13 pages (the competitors' pages and one to four search pages). A competitor shared by several businesses in one run is read once. Competitors' own rows are not returned unless you turn on Also return the competitors' business rows (charged as business rows).
  • A run's maximum cost is respected: a benchmark is not started when the remaining budget can't pay for it.
  • Benchmarks start on 2026-11-04. Before that date the run says so, charges nothing for it and carries on with the rest of your input.

Licence expiry watch

BBB lists trade licences (number, issuing body, expiry date) on business pages. Set Licences expiring within (licenseExpiringWithinDays, 1 to 365) and the run returns only businesses with at least one licence expiring inside that window, or expired in the last 30 days (flagged). Businesses that don't match are not returned and not charged.

{"searchQueries": ["plumber"], "searchLocation": "Austin, TX", "maxBusinessesPerSearch": 50, "licenseExpiringWithinDays": 60}

It also works with businesses links and with several search locations. It opens each business's own page, so it turns on Full details for businesses found for you, and it returns business rows only: reviews, complaints and summaries are skipped.

FieldWhat it is
licenseExpiresInDaysDays until the soonest matching licence expires. Negative means it already expired (up to 30 days ago)
licenseStatusexpiring, or expired-recently when a matching licence ended in the last 30 days
licenseAgenciesThe bodies that issued the matching licences
expiringLicensesOnly the matching licences: number, agency, expiresAt, expiresInDays

licenses still lists every licence BBB shows for the business. Real row (2026-10-20, shortened):

{
"type": "business",
"name": "Calixto Plumbing",
"primaryCategory": "Plumber",
"city": "Austin",
"state": "TX",
"licenseExpiresInDays": 41,
"licenseStatus": "expiring",
"licenseAgencies": ["Texas State Board of Plumbing Examiners"],
"expiringLicenses": [{"number": "44648", "agency": "Texas State Board of Plumbing Examiners", "expiresAt": "2026-11-30", "expiresInDays": 41}]
}

Limits: only licences BBB shows on the business's page and only those with an expiry date; BBB's list is what the business or the issuing body reported, so check the issuing body before acting on a date. Days are counted from the day of the run.

How much does it cost?

You pay per review, complaint or business row returned. A reputation summary is charged as one business row ($0.0005 each on the Free and Starter plans), and only when you turn it on. There is no charge for Apify platform usage on top.

RowFree and StarterScaleBusiness
Review$0.50 per 1,000$0.375 per 1,000$0.275 per 1,000
Complaint$0.50 per 1,000$0.375 per 1,000$0.275 per 1,000
Business$0.50 per 1,000$0.375 per 1,000$0.275 per 1,000
Reputation summary, complaint themes included (charged as a business row)$0.50 per 1,000$0.375 per 1,000$0.275 per 1,000
Competitor benchmark (from 2026-11-04)$40 per 1,000$30 per 1,000$22 per 1,000

That is $0.50 per 1,000 rows of any kind on the Free and Starter plans, except benchmark rows ($0.04 each on Free and Starter), which read about 13 pages each. The licence expiry watch uses business rows at the usual price. Plus $0.00005 per run start for each GB of memory ($0.0001 at the default 2 GB). Apify's free $5 monthly credit covers about 10,000 reviews. Free-plan runs stop at 1,000 rows each; any paid Apify plan removes the cap.

What's free: links that are not BBB businesses, searches with no results and unusable inputs (each comes back as a free not-found row saying what to change), reviews left out by Star ratings or Only with a business response, businesses skipped by Accredited businesses only, the same business listed twice in a search or found in two search locations, reviews and complaints skipped by onlyNew, and business rows whose grade, stars and counts haven't changed under onlyNew. To cap a run's spend, set Maximum cost per run in the run options, or Max rows in total in the input.

Limits, stated up front

  • Only what a logged-out visitor sees. Every review and complaint page on BBB is public, so the run reads each list in order, 10 per page, up to 2,000 pages per list.
  • BBB covers the United States and Canada only.
  • Search works like BBB's own search box (a business name or a trade, with an optional city and state or ZIP code) and BBB shows at most 225 results per search. To cover a big area, add more cities or ZIP codes in More search locations: each search runs in each place. BBB's search ranks accredited businesses first and matches similar spellings, so a name search for a large company that isn't accredited can return other businesses; the run's status message says so, and a business link always works. A search result has what the result card shows: grade, accreditation, category, phone and address, but no review stars or counts. Turn on Full details for businesses found to open each business's page as well; its reviews and complaints are then read with your limits too.
  • Star ratings apply to reviews only. Published on or after applies to both lists: they come newest first, so the run stops reading at that date.
  • About reviewers it keeps only the display name BBB shows. Complaints have no consumer name field: BBB masks consumers' names and numbers in complaint texts with asterisks, and the rows keep its masking. Consumer names in complaint text are removed: names BBB's masking misses (signed names, "My name is …", the customer's name in a reply's greeting, staff signatures, half-masked names like ***** A *****) become [name removed]. E-mail addresses and phone numbers in reviews and in consumers' complaint messages are replaced with [contact removed]. Business replies keep the business's own role addresses and phone numbers; personal-looking e-mail addresses in them are removed. Business rows never include the names of the owners and managers BBB lists.
  • BBB sits behind Cloudflare's visitor check, so pages are read in a real browser from US addresses. That makes the first page of a run take a few seconds, and very large businesses read their deep pages more slowly.
  • Big requests are split fairly across the run's time limit. If time runs short, the run ends successfully with the rows so far and says what to narrow.

Only new since last run, and schedules

Turn on Only new since the last run and schedule the Actor daily or weekly. Each run returns only reviews and complaints that earlier runs with the same businesses, searches and filters did not, and stops reading a list at the first item it already sent. A run with nothing new charges nothing. Business rows come back only when the grade, stars or counts changed, so a schedule also tracks grade changes. Set up a schedule under Schedules in Apify Console.

Integrations: API, n8n, Make and AI agents

API. Run it and get the rows back in one call:

curl -X POST "https://api.apify.com/v2/acts/locaihost~bbb-reviews/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"businesses": ["https://www.bbb.org/us/wa/seattle/profile/ecommerce/amazoncom-1296-7039385"], "maxReviewsPerBusiness": 0, "maxComplaintsPerBusiness": 50}'

Apify's API clients for Python and JavaScript work the same way.

n8n, Make, Zapier, Google Sheets, Slack, webhooks. Apify's built-in integrations send each run's dataset wherever you need it, for example each new complaint into a Slack channel.

AI agents (MCP). Add this Actor to Claude, Cursor or any MCP client with https://mcp.apify.com/?tools=locaihost/bbb-reviews, then ask something like "What are the most common complaint types against this roofing company on BBB this year, and does it respond?"

FAQ

How much does it cost to scrape BBB reviews?

$0.50 per 1,000 reviews, complaints or businesses on the Free and Starter plans, less on Scale and Business. Apify's free $5 monthly credit covers about 10,000 reviews.

What is the reputation summary, and how far back does it go?

One extra row per business with its complaint trend, the share of complaints it answered and resolved, median days to its first reply, top complaint types, star mix and review reply rate, worked out from the reviews and complaints the run read. Turn on Add a reputation summary per business. It goes back as far as the run reads, so raise Max complaints per business and Max reviews per business for a longer period; its basis field says how many items it is based on.

What does a competitor benchmark show, and what does it cost?

One row per business with its rank among local competitors that share its BBB category and city, the rank and percentile for grade, stars, complaints and reply times, plain-English highlights and the competitor list. $0.04 per benchmark row on the Free and Starter plans from 2026-11-04. See Competitor benchmark.

How do I find businesses whose licence is about to expire?

Set Licences expiring within to a number of days and run a search such as "plumber" near "Austin, TX". Only businesses with a matching licence are returned. See Licence expiry watch.

Can I use it through the API or from Python?

Yes. Use the run-sync-get-dataset-items call above, or Apify's Python and JavaScript clients. Every run's data is also available as JSON, CSV or Excel from its dataset.

Can I use it from an AI agent?

Yes. Through the Apify MCP server (https://mcp.apify.com/?tools=locaihost/bbb-reviews) any MCP client can call it with a list of BBB links or a search and read the rows back.

The Actor reads only pages any logged-out visitor can open; it never logs in or uses cookies from an account. BBB's own terms restrict automated collection, so check them against your use. It keeps only a reviewer's display name, keeps BBB's own masking in complaints and removes contact details typed into reviews and complaints. Reviews and complaints are written by members of the public: respect copyright when republishing them, follow privacy law (such as GDPR or CCPA) if you store reviewer names, and never use the data to contact, profile or harass reviewers or complainants. You are responsible for how you use the results.

Search for it by name: put the name in Search (and its city in Search near). Each result's companyUrl is the link to use in BBB business links. That works well for local businesses. For a large company BBB's search can rank other businesses first (it puts accredited ones on top), so if the results don't show it, search the web for the company name plus "BBB" and paste the bbb.org link.

Can I get only accredited businesses, or search many cities at once?

Yes. Turn on Accredited businesses only (the others are skipped and cost nothing), and list extra cities or ZIP codes in More search locations. A business found in two places is returned and charged once.

Why are some fields empty?

In a summary row, a month or trend is null when the run didn't read back that far, and the complaint or review fields are null when that list wasn't read (its limit was 0). replyText is empty when the business didn't reply, and the follow-up fields when there was no further exchange. title, language and reviewerCountry are always null because BBB doesn't show them. Search results leave stars, reviewCount and the complaint counts empty (turn on Full details for businesses found to get them). email and websiteUrl exist only where the business published them on BBB.

More from locaihost data

Did it help?

If this saved you time, a quick rating on the Store helps other people find it.

Support

Something not working, or a field you need? Open an issue on the Issues tab: we answer issues within 24 hours.