# BBB Scraper – Business data & emails

Extract 50+ fields, emails, phones, ratings & accreditation from BBB profiles and searches at scale. Export JSON/CSV, schedule runs, proxy rotation & automatic captchas included. Ideal for B2B lead gen, CRM enrichment & supplier checks.

## Actor Statistics

- Total users: 81
- Monthly users: 32
- Runs succeeded: 100.00%
- Categories: Other, Lead generation

## Pricing

$4.95 / 1,000 results

## Input Schema

- **key\_words** (type: array): List of keywords to search for. It's recommended to use specific keywords rather than keywords with very general meanings to refine your search.
- **locations** (type: array): A list of locations for which scraping will be performed. While this parameter is optional, it's recommended to use specific locations to refine your search. For example, use a keyword and a list of zip codes for a state. This way, you can get the most results.
- **countries** (type: string): Select the country for scraping. (United States or Canada.)
- **maxRecordsPerLocation** (type: integer): For a keyword and a list of locations, the entered limit will be extracted for each location. Otherwise, if this parameter is left at 0, then everything that can be obtained will be extracted.
- **maxRecordsGlobal** (type: integer): Maximum number of records to scrape for a specific search. This parameter is independent of the total number displayed by https://www.bbb.org/.

## API example

## BBB Scraper – Business data & emails

- **OpenAPI Version:** `3.1.1`
- **API Version:** `0.0`

Extract 50+ fields, emails, phones, ratings & accreditation from BBB profiles and searches at scale. Export JSON/CSV, schedule runs, proxy rotation & automatic captchas included. Ideal for B2B lead gen, CRM enrichment & supplier checks.

### Servers

- **URL:** `https://api.apify.com/v2`

### Operations

#### Executes an Actor, waits for its completion, and returns Actor's dataset items in response.

- **Method:** `POST`
- **Path:** `/acts/autoscraping~better-business-bureau/run-sync-get-dataset-items`
- **Tags:** Run Actor

##### Request Body

###### Content-Type: application/json

- **`countries` (required)**

  `string`, possible values: `"USA", "CAN"`, default: `"USA"` — Select the country for scraping. (United States or Canada.)

- **`key_words` (required)**

  `array` — List of keywords to search for. It's recommended to use specific keywords rather than keywords with very general meanings to refine your search.

  **Items:**

  `string`

- **`locations`**

  `array` — A list of locations for which scraping will be performed. While this parameter is optional, it's recommended to use specific locations to refine your search. For example, use a keyword and a list of zip codes for a state. This way, you can get the most results.

  **Items:**

  `string`

- **`maxRecordsGlobal`**

  `integer`, default: `10` — Maximum number of records to scrape for a specific search. This parameter is independent of the total number displayed by https://www.bbb.org/.

- **`maxRecordsPerLocation`**

  `integer`, default: `0` — For a keyword and a list of locations, the entered limit will be extracted for each location. Otherwise, if this parameter is left at 0, then everything that can be obtained will be extracted.

**Example:**

```
{
  "key_words": [
    ""
  ],
  "locations": [
    ""
  ],
  "countries": "USA",
  "maxRecordsPerLocation": 0,
  "maxRecordsGlobal": 10
}
```

##### Responses

###### Status: 200 OK

#### Executes an Actor and returns information about the initiated run in response.

- **Method:** `POST`
- **Path:** `/acts/autoscraping~better-business-bureau/runs`
- **Tags:** Run Actor

##### Request Body

###### Content-Type: application/json

- **`countries` (required)**

  `string`, possible values: `"USA", "CAN"`, default: `"USA"` — Select the country for scraping. (United States or Canada.)

- **`key_words` (required)**

  `array` — List of keywords to search for. It's recommended to use specific keywords rather than keywords with very general meanings to refine your search.

  **Items:**

  `string`

- **`locations`**

  `array` — A list of locations for which scraping will be performed. While this parameter is optional, it's recommended to use specific locations to refine your search. For example, use a keyword and a list of zip codes for a state. This way, you can get the most results.

  **Items:**

  `string`

- **`maxRecordsGlobal`**

  `integer`, default: `10` — Maximum number of records to scrape for a specific search. This parameter is independent of the total number displayed by https://www.bbb.org/.

- **`maxRecordsPerLocation`**

  `integer`, default: `0` — For a keyword and a list of locations, the entered limit will be extracted for each location. Otherwise, if this parameter is left at 0, then everything that can be obtained will be extracted.

**Example:**

```
{
  "key_words": [
    ""
  ],
  "locations": [
    ""
  ],
  "countries": "USA",
  "maxRecordsPerLocation": 0,
  "maxRecordsGlobal": 10
}
```

##### Responses

###### Status: 200 OK

\####### Content-Type: application/json

- **`data`**

  `object`

  - **`actId`**

    `string`

  - **`buildId`**

    `string`

  - **`buildNumber`**

    `string`

  - **`containerUrl`**

    `string`

  - **`defaultDatasetId`**

    `string`

  - **`defaultKeyValueStoreId`**

    `string`

  - **`defaultRequestQueueId`**

    `string`

  - **`finishedAt`**

    `string`, format: `date-time`

  - **`id`**

    `string`

  - **`meta`**

    `object`

    - **`origin`**

      `string`

    - **`userAgent`**

      `string`

  - **`options`**

    `object`

    - **`build`**

      `string`

    - **`diskMbytes`**

      `integer`

    - **`memoryMbytes`**

      `integer`

    - **`timeoutSecs`**

      `integer`

  - **`startedAt`**

    `string`, format: `date-time`

  - **`stats`**

    `object`

    - **`computeUnits`**

      `integer`

    - **`inputBodyLen`**

      `integer`

    - **`rebootCount`**

      `integer`

    - **`restartCount`**

      `integer`

    - **`resurrectCount`**

      `integer`

  - **`status`**

    `string`

  - **`usage`**

    `object`

    - **`ACTOR_COMPUTE_UNITS`**

      `integer`

    - **`DATA_TRANSFER_EXTERNAL_GBYTES`**

      `integer`

    - **`DATA_TRANSFER_INTERNAL_GBYTES`**

      `integer`

    - **`DATASET_READS`**

      `integer`

    - **`DATASET_WRITES`**

      `integer`

    - **`KEY_VALUE_STORE_LISTS`**

      `integer`

    - **`KEY_VALUE_STORE_READS`**

      `integer`

    - **`KEY_VALUE_STORE_WRITES`**

      `integer`

    - **`PROXY_RESIDENTIAL_TRANSFER_GBYTES`**

      `integer`

    - **`PROXY_SERPS`**

      `integer`

    - **`REQUEST_QUEUE_READS`**

      `integer`

    - **`REQUEST_QUEUE_WRITES`**

      `integer`

  - **`usageTotalUsd`**

    `number`

  - **`usageUsd`**

    `object`

    - **`ACTOR_COMPUTE_UNITS`**

      `integer`

    - **`DATA_TRANSFER_EXTERNAL_GBYTES`**

      `integer`

    - **`DATA_TRANSFER_INTERNAL_GBYTES`**

      `integer`

    - **`DATASET_READS`**

      `integer`

    - **`DATASET_WRITES`**

      `integer`

    - **`KEY_VALUE_STORE_LISTS`**

      `integer`

    - **`KEY_VALUE_STORE_READS`**

      `integer`

    - **`KEY_VALUE_STORE_WRITES`**

      `number`

    - **`PROXY_RESIDENTIAL_TRANSFER_GBYTES`**

      `integer`

    - **`PROXY_SERPS`**

      `integer`

    - **`REQUEST_QUEUE_READS`**

      `integer`

    - **`REQUEST_QUEUE_WRITES`**

      `integer`

  - **`userId`**

    `string`

**Example:**

```
{
  "data": {
    "id": "",
    "actId": "",
    "userId": "",
    "startedAt": "2025-01-08T00:00:00.000Z",
    "finishedAt": "2025-01-08T00:00:00.000Z",
    "status": "READY",
    "meta": {
      "origin": "API",
      "userAgent": ""
    },
    "stats": {
      "inputBodyLen": 2000,
      "rebootCount": 0,
      "restartCount": 0,
      "resurrectCount": 0,
      "computeUnits": 0
    },
    "options": {
      "build": "latest",
      "timeoutSecs": 300,
      "memoryMbytes": 1024,
      "diskMbytes": 2048
    },
    "buildId": "",
    "defaultKeyValueStoreId": "",
    "defaultDatasetId": "",
    "defaultRequestQueueId": "",
    "buildNumber": "1.0.0",
    "containerUrl": "",
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0,
      "DATASET_READS": 0,
      "DATASET_WRITES": 0,
      "KEY_VALUE_STORE_READS": 0,
      "KEY_VALUE_STORE_WRITES": 1,
      "KEY_VALUE_STORE_LISTS": 0,
      "REQUEST_QUEUE_READS": 0,
      "REQUEST_QUEUE_WRITES": 0,
      "DATA_TRANSFER_INTERNAL_GBYTES": 0,
      "DATA_TRANSFER_EXTERNAL_GBYTES": 0,
      "PROXY_RESIDENTIAL_TRANSFER_GBYTES": 0,
      "PROXY_SERPS": 0
    },
    "usageTotalUsd": 0.00005,
    "usageUsd": {
      "ACTOR_COMPUTE_UNITS": 0,
      "DATASET_READS": 0,
      "DATASET_WRITES": 0,
      "KEY_VALUE_STORE_READS": 0,
      "KEY_VALUE_STORE_WRITES": 0.00005,
      "KEY_VALUE_STORE_LISTS": 0,
      "REQUEST_QUEUE_READS": 0,
      "REQUEST_QUEUE_WRITES": 0,
      "DATA_TRANSFER_INTERNAL_GBYTES": 0,
      "DATA_TRANSFER_EXTERNAL_GBYTES": 0,
      "PROXY_RESIDENTIAL_TRANSFER_GBYTES": 0,
      "PROXY_SERPS": 0
    }
  }
}
```

#### Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.

- **Method:** `POST`
- **Path:** `/acts/autoscraping~better-business-bureau/run-sync`
- **Tags:** Run Actor

##### Request Body

###### Content-Type: application/json

- **`countries` (required)**

  `string`, possible values: `"USA", "CAN"`, default: `"USA"` — Select the country for scraping. (United States or Canada.)

- **`key_words` (required)**

  `array` — List of keywords to search for. It's recommended to use specific keywords rather than keywords with very general meanings to refine your search.

  **Items:**

  `string`

- **`locations`**

  `array` — A list of locations for which scraping will be performed. While this parameter is optional, it's recommended to use specific locations to refine your search. For example, use a keyword and a list of zip codes for a state. This way, you can get the most results.

  **Items:**

  `string`

- **`maxRecordsGlobal`**

  `integer`, default: `10` — Maximum number of records to scrape for a specific search. This parameter is independent of the total number displayed by https://www.bbb.org/.

- **`maxRecordsPerLocation`**

  `integer`, default: `0` — For a keyword and a list of locations, the entered limit will be extracted for each location. Otherwise, if this parameter is left at 0, then everything that can be obtained will be extracted.

**Example:**

```
{
  "key_words": [
    ""
  ],
  "locations": [
    ""
  ],
  "countries": "USA",
  "maxRecordsPerLocation": 0,
  "maxRecordsGlobal": 10
}
```

##### Responses

###### Status: 200 OK

### Schemas

#### inputSchema

- **Type:**`object`

* **`countries` (required)**

  `string`, possible values: `"USA", "CAN"`, default: `"USA"` — Select the country for scraping. (United States or Canada.)

* **`key_words` (required)**

  `array` — List of keywords to search for. It's recommended to use specific keywords rather than keywords with very general meanings to refine your search.

  **Items:**

  `string`

* **`locations`**

  `array` — A list of locations for which scraping will be performed. While this parameter is optional, it's recommended to use specific locations to refine your search. For example, use a keyword and a list of zip codes for a state. This way, you can get the most results.

  **Items:**

  `string`

* **`maxRecordsGlobal`**

  `integer`, default: `10` — Maximum number of records to scrape for a specific search. This parameter is independent of the total number displayed by https://www.bbb.org/.

* **`maxRecordsPerLocation`**

  `integer`, default: `0` — For a keyword and a list of locations, the entered limit will be extracted for each location. Otherwise, if this parameter is left at 0, then everything that can be obtained will be extracted.

**Example:**

```
{
  "key_words": [
    ""
  ],
  "locations": [
    ""
  ],
  "countries": "USA",
  "maxRecordsPerLocation": 0,
  "maxRecordsGlobal": 10
}
```

#### runsResponseSchema

- **Type:**`object`

* **`data`**

  `object`

  - **`actId`**

    `string`

  - **`buildId`**

    `string`

  - **`buildNumber`**

    `string`

  - **`containerUrl`**

    `string`

  - **`defaultDatasetId`**

    `string`

  - **`defaultKeyValueStoreId`**

    `string`

  - **`defaultRequestQueueId`**

    `string`

  - **`finishedAt`**

    `string`, format: `date-time`

  - **`id`**

    `string`

  - **`meta`**

    `object`

    - **`origin`**

      `string`

    - **`userAgent`**

      `string`

  - **`options`**

    `object`

    - **`build`**

      `string`

    - **`diskMbytes`**

      `integer`

    - **`memoryMbytes`**

      `integer`

    - **`timeoutSecs`**

      `integer`

  - **`startedAt`**

    `string`, format: `date-time`

  - **`stats`**

    `object`

    - **`computeUnits`**

      `integer`

    - **`inputBodyLen`**

      `integer`

    - **`rebootCount`**

      `integer`

    - **`restartCount`**

      `integer`

    - **`resurrectCount`**

      `integer`

  - **`status`**

    `string`

  - **`usage`**

    `object`

    - **`ACTOR_COMPUTE_UNITS`**

      `integer`

    - **`DATA_TRANSFER_EXTERNAL_GBYTES`**

      `integer`

    - **`DATA_TRANSFER_INTERNAL_GBYTES`**

      `integer`

    - **`DATASET_READS`**

      `integer`

    - **`DATASET_WRITES`**

      `integer`

    - **`KEY_VALUE_STORE_LISTS`**

      `integer`

    - **`KEY_VALUE_STORE_READS`**

      `integer`

    - **`KEY_VALUE_STORE_WRITES`**

      `integer`

    - **`PROXY_RESIDENTIAL_TRANSFER_GBYTES`**

      `integer`

    - **`PROXY_SERPS`**

      `integer`

    - **`REQUEST_QUEUE_READS`**

      `integer`

    - **`REQUEST_QUEUE_WRITES`**

      `integer`

  - **`usageTotalUsd`**

    `number`

  - **`usageUsd`**

    `object`

    - **`ACTOR_COMPUTE_UNITS`**

      `integer`

    - **`DATA_TRANSFER_EXTERNAL_GBYTES`**

      `integer`

    - **`DATA_TRANSFER_INTERNAL_GBYTES`**

      `integer`

    - **`DATASET_READS`**

      `integer`

    - **`DATASET_WRITES`**

      `integer`

    - **`KEY_VALUE_STORE_LISTS`**

      `integer`

    - **`KEY_VALUE_STORE_READS`**

      `integer`

    - **`KEY_VALUE_STORE_WRITES`**

      `number`

    - **`PROXY_RESIDENTIAL_TRANSFER_GBYTES`**

      `integer`

    - **`PROXY_SERPS`**

      `integer`

    - **`REQUEST_QUEUE_READS`**

      `integer`

    - **`REQUEST_QUEUE_WRITES`**

      `integer`

  - **`userId`**

    `string`

**Example:**

```
{
  "data": {
    "id": "",
    "actId": "",
    "userId": "",
    "startedAt": "2025-01-08T00:00:00.000Z",
    "finishedAt": "2025-01-08T00:00:00.000Z",
    "status": "READY",
    "meta": {
      "origin": "API",
      "userAgent": ""
    },
    "stats": {
      "inputBodyLen": 2000,
      "rebootCount": 0,
      "restartCount": 0,
      "resurrectCount": 0,
      "computeUnits": 0
    },
    "options": {
      "build": "latest",
      "timeoutSecs": 300,
      "memoryMbytes": 1024,
      "diskMbytes": 2048
    },
    "buildId": "",
    "defaultKeyValueStoreId": "",
    "defaultDatasetId": "",
    "defaultRequestQueueId": "",
    "buildNumber": "1.0.0",
    "containerUrl": "",
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0,
      "DATASET_READS": 0,
      "DATASET_WRITES": 0,
      "KEY_VALUE_STORE_READS": 0,
      "KEY_VALUE_STORE_WRITES": 1,
      "KEY_VALUE_STORE_LISTS": 0,
      "REQUEST_QUEUE_READS": 0,
      "REQUEST_QUEUE_WRITES": 0,
      "DATA_TRANSFER_INTERNAL_GBYTES": 0,
      "DATA_TRANSFER_EXTERNAL_GBYTES": 0,
      "PROXY_RESIDENTIAL_TRANSFER_GBYTES": 0,
      "PROXY_SERPS": 0
    },
    "usageTotalUsd": 0.00005,
    "usageUsd": {
      "ACTOR_COMPUTE_UNITS": 0,
      "DATASET_READS": 0,
      "DATASET_WRITES": 0,
      "KEY_VALUE_STORE_READS": 0,
      "KEY_VALUE_STORE_WRITES": 0.00005,
      "KEY_VALUE_STORE_LISTS": 0,
      "REQUEST_QUEUE_READS": 0,
      "REQUEST_QUEUE_WRITES": 0,
      "DATA_TRANSFER_INTERNAL_GBYTES": 0,
      "DATA_TRANSFER_EXTERNAL_GBYTES": 0,
      "PROXY_RESIDENTIAL_TRANSFER_GBYTES": 0,
      "PROXY_SERPS": 0
    }
  }
}
```

## BBB Scraper – Business Data & Contact Emails

Extract full business profiles from the Better Business Bureau (BBB), including contact emails, to accelerate your B2B prospecting efforts.

### Overview

This actor scrapes listings, searches, or individual profiles from BBB.org, extracting over 50 key fields and a contact email in approximately 75% of cases. Ideal for lead generation, CRM enrichment, and market reputation analysis. It uses rotating proxies and automatic CAPTCHA handling to ensure stability and scalability.

### Why choose this actor?

| Feature                | Competitors          | This Actor                    |
|------------------------|----------------------|-------------------------------|
| Email extraction       | ❌ Not available      | ✅ Included                    |
| Anti-blocking coverage | Varies               | Rotating proxy + auto-retry   |
| Speed                  | 1–2 req/s            | Optimized for 3 req/s         |
| Data freshness         | 3–12 months          | Continuously updated          |
| Pricing                | $5–20/month          | $14.95/month (flat rate)      |

### Use Cases

- Prospect BBB-accredited businesses and send customized B2B offers.
- Enrich your CRM with trust metrics such as ratings, complaints, and accreditation status.
- Evaluate suppliers by checking for recent complaints and direct email contact.
- Create dashboards for sectoral or regional BBB data analysis.

### Key Features

- Extracts contact email and phone numbers from BBB profiles (if publicly available).
- Flexible input: keyword + location, search result URLs, or direct profile links.
- Parses 50+ structured fields: contact info, reputation data, geolocation, timestamps.
- Uses managed residential proxies.
- Supports JSON, CSV, Parquet export formats and Dataset API access.
- Maintained monthly with updated selectors and anti-bot mechanisms.
- Retrieves up to 330–340 results per query (vs native limit of ~220).

### How It Works

1. **Queue builder** → Generates a list of URLs (search → profile) from your input.
2. **Crawler** → Navigates each URL using rotating proxies; handles CAPTCHA and retries.
3. **Extractor** → Parses selectors, normalizes email, enriches with geo-coordinates.
4. **Output store** → Saves results to an Apify Dataset for download or API access.
5. **Limitations** → BBB has a limitation of 15 results per 15 pages. In order to obtain more results you have to iterate over "location" field.

### Input Parameters

| Field                   | Type     | Required | Description                                                                                      |
|-------------------------|----------|----------|--------------------------------------------------------------------------------------------------|
| `countries`             | string   | yes      | Country in English                                                                               |
| `keywords`              | string   | yes      | Search terms (business type, service, category, etc.)                                            |
| `locations`             | string   | optional | City/State/zipcode                                                                               |
| `maxRecordsGlobal`      | integer  | optional | Maximum number of results to fetch (default = 10)                                                |
| `maxRecordsPerLocation` | integer  | optional | Maximum number of records per location. Leave at "0" if you do not want to use it. (default = 0) |

### Output (Full Example)

```json
{
    "id": "0000_0000000_000000",
    "businessId": "0000000",
    "tobId": "10126-000",
    "bbbId": "0000",
    "businessName": "Example Roofing Solutions, LLC",
    "tobText": "Roofing Contractors",
    "bbbName": "BBB serving Sample Region",
    "rating": "A+",
    "ratingScore": 95,
    "accreditationStatus": "Accredited",
    "bbbMember": true,
    "charitySeal": false,
    "isCharity": 0,
    "accreditedCharity": false,
    "logoUri": "https://example.com/logo.png",
    "Type of Entity": "LLC",
    "Business Started": "1/1/2010",
    "Business Started Locally": "3/10/2012",
    "Business Incorporated": "5/5/2013",
    "phone": "(555) 111-2222, (555) 333-4444",
    "Email Business": "info@example.com",
    "Additional Email Addresses": "info@example2.com, info@example3.com",
    "Principal Contacts": [
        {
            "name": "Mr. John Example",
            "role": "Founder"
        }
    ],
    "Customer Contacts": [
        {
            "name": "Ms. Jane Sample",
            "role": "Customer Success"
        }
    ],
    "Social Media": "https://facebook.com/example, https://twitter.com/example",
    "Web Site": "https://www.example.com",
    "Additional Websites": "https://www.example2.com, https://www.example3.com",
    "address": "123 Sample Street",
    "city": "Sampletown",
    "state": "EX",
    "postalcode": "12345",
    "location": "38.897957,-77.036560",
    "categories": "Roofing Contractors",
    "serviceAreaDescription": "Available across Example State",
    "hasServiceArea": true,
    "serviceArea": "Example State",
    "serviceAreasSummary": "Serving all cities within Example State",
    "reportUrl": "/us/ex/sampletown/profile/roofing-contractors/example-roofing-solutions-llc-0000-0000000",
    "localReportUrl": "/us/ex/sampletown/profile/roofing-contractors/example-roofing-solutions-llc-0000-0000000/addressId/000000",
    "leaveReviewUrl": "/us/ex/sampletown/profile/roofing-contractors/example-roofing-solutions-llc-0000-0000000/customer-reviews",
    "requestAQuoteUrl": "/quote-request",
    "businessLoginUrl": "/example-region/login",
    "url_register": "https://www.bbb.org/us/ex/sampletown/profile/roofing-contractors/example-roofing-solutions-llc-0000-0000000",
    "requestAQuoteUrlId": 1,
    "Local BBB Url": "https://www.bbb.org/local-bbb/bbb-serving-example-region",
    "BBB File Opened": "6/1/2011",
    "raqEnabled": true,
    "outOfBusinessStatus": ""
}
```

### Pricing

This actor operates under a simple subscription model:

- $14.95/month (unlimited usage within platform limits)
- Free users can access up to 2 min of trial for testing purposes

### Email Coverage

- \~75% success rate for businesses with a public-facing website
- Micro-enterprises may only list phone numbers → `email = null`

### Legal Disclaimer

This actor is not affiliated with or endorsed by the Better Business Bureau (BBB).

It extracts data from publicly accessible pages on bbb.org, without bypassing logins or technical protections. By using it, you agree to review and comply with BBB’s [Terms of Use](https://www.bbb.org). Use is at your own risk.

The author assumes no liability for any legal, contractual, or ethical consequences. This tool is provided as-is for informational, internal, or research purposes. Commercial reuse of the data may require prior authorization from BBB.

### Update Policy

- Weekly checks for UI and CAPTCHA changes.
- Major changes documented in the actor’s CHANGELOG.
- Limit imposed by BBB.org per search is 15 results per 15 pages.

### FAQ

**Does this actor extract private emails?**\
No. It only collects emails made publicly visible by BBB. No external enrichment is performed.

**What proxy should I use?**\
For large-scale runs, we recommend Apify US residential proxies.
