{
  "openapi": "3.0.1",
  "info": {
    "title": "BBB Businesses Scraper",
    "description": "BBB scraper for the Better Business Bureau (bbb.org): businesses in the US and Canada with name, BBB rating, accreditation, phone, address and category, plus optional full profile, reviews, complaints and the email found on the company website. Export to JSON, CSV or Excel.",
    "version": "0.0",
    "x-build-id": "PV8n7G2xwclpPQkIq"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/nice_dev~bbb-businesses-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-nice_dev-bbb-businesses-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/nice_dev~bbb-businesses-scraper/runs": {
      "post": {
        "operationId": "runs-sync-nice_dev-bbb-businesses-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/nice_dev~bbb-businesses-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-nice_dev-bbb-businesses-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "mode": {
            "title": "What to collect",
            "enum": [
              "search",
              "directory"
            ],
            "type": "string",
            "description": "**Search** = the BBB search (keyword × location), like on bbb.org; past its 225-result cap when **Go past the 225-result cap** is on. **Full directory** = every business BBB lists in the chosen states / cities (accredited or not, rated or not), read from BBB's own business index: **Location(s)** are then `TX` or `Austin, TX` (no ZIP codes) and **Search keyword(s)** filter on the category (`plumber`). Start URLs, when given, override both.",
            "default": "search"
          },
          "startUrls": {
            "title": "Start URLs",
            "maxItems": 1000,
            "type": "array",
            "description": "bbb.org URLs: search results (`https://www.bbb.org/search?find_text=plumber&find_loc=Austin%2C%20TX`, the filters set on the site are kept), category pages (`/us/tx/austin/category/plumber`) or business profiles (`/us/tx/austin/profile/plumber/calixto-plumbing-0825-1000223803`). When this list is not empty, the search fields below are ignored; filters, options, caps and monitoring still apply. Max 1 000 URLs.",
            "default": [],
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "query": {
            "title": "Search keyword",
            "maxLength": 200,
            "type": "string",
            "description": "Category or business name, as typed on bbb.org (e.g. `plumber`, `roofing`, `Roto-Rooter`). In **Full directory** mode: words that the business category must contain (empty = all categories)."
          },
          "searchQueries": {
            "title": "More search keywords",
            "maxItems": 100,
            "uniqueItems": true,
            "type": "array",
            "description": "Several keywords in one run: one search per keyword (times each location below). Added to **Search keyword**; businesses found by several searches are saved once.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "location": {
            "title": "Location",
            "maxLength": 200,
            "type": "string",
            "description": "City and state or province (`Austin, TX`, `Toronto, ON`), ZIP / postal code (`78701`) or state (`TX`). BBB searches AROUND this place (nearby cities come too; use **Distance** to narrow). In **Full directory** mode: `TX` or `Austin, TX` only."
          },
          "locations": {
            "title": "More locations",
            "maxItems": 100,
            "uniqueItems": true,
            "type": "array",
            "description": "Several locations in one run: every keyword is searched in every location (3 keywords × 4 locations = 12 searches, max 500). Added to **Location**.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "country": {
            "title": "Country",
            "enum": [
              "USA",
              "CAN"
            ],
            "type": "string",
            "description": "Country of the search: United States or Canada (BBB lists no other country).",
            "default": "USA"
          },
          "maxItems": {
            "title": "Max businesses",
            "minimum": 0,
            "maximum": 1000000,
            "type": "integer",
            "description": "Maximum number of businesses to save for the whole run (after deduplication and filters). 0 = no limit.",
            "default": 100
          },
          "maxItemsPerQuery": {
            "title": "Max businesses per search",
            "minimum": 0,
            "maximum": 1000000,
            "type": "integer",
            "description": "Cap for EACH search (keyword × location, or start URL), so that the first search cannot use up the whole **Max businesses** budget. 0 = no per-search cap.",
            "default": 0
          },
          "maximizeCoverage": {
            "title": "Go past the 225-result cap",
            "type": "boolean",
            "description": "BBB shows at most 225 businesses per search (15 pages). On: when a search has more, it is re-run with the other sort orders, each rating grade and each sub-category BBB proposes, and every business is kept once. Off = the first 225 only (faster).",
            "default": true
          },
          "sort": {
            "title": "Sort by",
            "enum": [
              "Relevance",
              "Distance",
              "Rating",
              "AToZ",
              "ZToA"
            ],
            "type": "string",
            "description": "Order of the BBB results (matters when a search has more businesses than you collect). Not used in Full directory mode: the businesses come in the order of BBB's business index, by local BBB office — with a state or a city, the offices that list the most businesses there first.",
            "default": "Relevance"
          },
          "includeDetails": {
            "title": "Full business profile",
            "type": "boolean",
            "description": "Open each BBB profile page: owners and managers (name + title), email, website, extra phones, licenses (number, agency), opening hours, social media, years in business, legal form, employees, description, BBB rating reasons, review and complaint totals, branches of multi-location businesses (the first 100 locations BBB lists for each). Billed per business delivered with its profile.",
            "default": false
          },
          "includeReviews": {
            "title": "Customer reviews",
            "type": "boolean",
            "description": "Full text of the customer reviews (stars, first name + initial, date) with the business reply and the rest of the exchange, newest first. Billed per review delivered.",
            "default": false
          },
          "maxReviewsPerBusiness": {
            "title": "Max reviews per business",
            "minimum": 0,
            "maximum": 5000,
            "type": "integer",
            "description": "Newest reviews kept per business. 0 = all of them. The run's memory rises with the caps (256 MB up to 400 reviews + complaints per business, 512 MB up to 1,200, 1 GB up to 2,500, 2 GB above; 0 counts as 5,000) and a run started with less is refused.",
            "default": 50
          },
          "includeComplaints": {
            "title": "Customer complaints",
            "type": "boolean",
            "description": "Full text of the complaints filed with BBB: type (billing, service, product…), status (answered, resolved…), date, and the whole thread of business and customer replies, newest first. Billed per complaint delivered.",
            "default": false
          },
          "maxComplaintsPerBusiness": {
            "title": "Max complaints per business",
            "minimum": 0,
            "maximum": 5000,
            "type": "integer",
            "description": "Newest complaints kept per business. 0 = all of them. Counted with the reviews for the run's memory (see Max reviews per business); with more than 16 businesses at a time (Max concurrency) the entries count double.",
            "default": 50
          },
          "complaintStatus": {
            "title": "Complaint status",
            "type": "array",
            "description": "Only the complaints with one of these statuses (filtered by BBB). Empty = all complaints. Needs Customer complaints.",
            "items": {
              "type": "string",
              "enum": [
                "answered",
                "resolved"
              ],
              "enumTitles": [
                "Answered",
                "Resolved"
              ]
            }
          },
          "complaintTypes": {
            "title": "Complaint types",
            "type": "array",
            "description": "Only the complaints of one of these types (filtered by BBB). Empty = all types. Needs Customer complaints.",
            "items": {
              "type": "string",
              "enum": [
                "serviceorrepair",
                "billingissues",
                "productissues",
                "salesadvertising",
                "customerservice",
                "order"
              ],
              "enumTitles": [
                "Service or repair issues",
                "Billing issues",
                "Product issues",
                "Advertising / sales issues",
                "Customer service issues",
                "Order issues"
              ]
            }
          },
          "enrichEmails": {
            "title": "Email from the company website",
            "type": "boolean",
            "description": "Visit the company's own website (home, contact and legal pages, 3 pages max) to find its email address when BBB shows none or another one. Needs **Full business profile** (the website comes from it). Charged as a separate `email-enriched` event, once per business where an email BBB does not show is found.",
            "default": false
          },
          "minRating": {
            "title": "Minimum BBB rating",
            "enum": [
              "A+",
              "A",
              "A-",
              "B+",
              "B",
              "B-",
              "C+",
              "C",
              "C-",
              "D+",
              "D",
              "D-",
              "F"
            ],
            "type": "string",
            "description": "Keep only the businesses rated at least this grade (`A+` best, `F` worst). Businesses not rated by BBB (NR) are dropped when this is set."
          },
          "accreditedOnly": {
            "title": "BBB Accredited businesses only",
            "type": "boolean",
            "description": "Keep only the businesses accredited by BBB.",
            "default": false
          },
          "minYearsInBusiness": {
            "title": "Minimum years in business",
            "minimum": 0,
            "maximum": 200,
            "type": "integer",
            "description": "Keep only the businesses open for at least this many years, as shown on their BBB profile. Needs Full business profile (the years are on the profile only). Businesses with no year shown are dropped when this is set."
          },
          "distance": {
            "title": "Distance",
            "enum": [
              "5",
              "10",
              "25",
              "50",
              "100"
            ],
            "type": "string",
            "description": "Search mode: keep the businesses within this many miles of **Location** (BBB's own distance filter). Empty = any distance."
          },
          "onlyQuoteRequests": {
            "title": "Accepts quote requests",
            "type": "boolean",
            "description": "Keep only the businesses that take quote requests through BBB (\"Get a Quote\").",
            "default": false
          },
          "requirePhone": {
            "title": "With a phone number only",
            "type": "boolean",
            "description": "Drop the businesses without a phone number.",
            "default": false
          },
          "requireWebsite": {
            "title": "With a website only",
            "type": "boolean",
            "description": "Drop the businesses without a website. Needs **Full business profile**.",
            "default": false
          },
          "requireEmail": {
            "title": "With an email only",
            "type": "boolean",
            "description": "Drop the businesses that show no email on their BBB profile (the company website is visited afterwards, only for the businesses kept: its emails do not count here). Needs **Full business profile**.",
            "default": false
          },
          "postedAfter": {
            "title": "Reviews and complaints after",
            "type": "string",
            "description": "Only the reviews and complaints dated on or after this date: `2026-09-01`, or a period before now such as `7 days`, `2 weeks`, `1 month` (API: `24 hours` and full ISO date-times work too). Applies to the review and complaint lists, not to the businesses. Needs Customer reviews or Customer complaints."
          },
          "postedBefore": {
            "title": "Reviews and complaints before",
            "type": "string",
            "description": "Only the reviews and complaints dated on or before this date (the whole day is included), or older than a period such as `30 days`. Needs Customer reviews or Customer complaints."
          },
          "excludeKeywords": {
            "title": "Exclude keywords",
            "maxItems": 50,
            "uniqueItems": true,
            "type": "array",
            "description": "Drop the businesses whose name or category contains one of these words (case and accents ignored).",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "onlyNew": {
            "title": "Only new businesses",
            "type": "boolean",
            "description": "Skip the businesses that a previous run (same **Memory key**) already delivered: they are not saved and not charged, and their pages are not even opened. First run = everything is new. To follow new reviews or complaints of known businesses, use **Reviews and complaints after** (e.g. `7 days`) instead.",
            "default": false
          },
          "stateKey": {
            "title": "Memory key",
            "pattern": "^[a-zA-Z0-9_-]{1,64}$",
            "maxLength": 64,
            "type": "string",
            "description": "Name of the memory used by **Only new businesses**. Give each schedule / task its own key (e.g. `austin-plumbers`) so that they do not share their memory. Letters, digits, `-` and `_`.",
            "default": "default"
          },
          "resetState": {
            "title": "Reset the memory",
            "type": "boolean",
            "description": "Forget everything remembered under this **Memory key** before the run: this run returns (and charges) every business again. Untick it afterwards.",
            "default": false
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Apify Proxy or your own proxies. Keep the default: it is included in the price. The residential Apify proxy is not available in this Actor.",
            "default": {
              "useApifyProxy": true
            }
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "minimum": 1,
            "maximum": 50,
            "type": "integer",
            "description": "Maximum number of requests processed in parallel.",
            "default": 8
          },
          "maxRequestsPerMinute": {
            "title": "Max requests per minute",
            "minimum": 10,
            "maximum": 2000,
            "type": "integer",
            "description": "Most requests to the site in any 60 seconds, all of them counted: search pages, profiles, review and complaint pages. A budget, not an even pace: up to this many can leave at once when the minute starts (spread them with the minimum delay below). Lower it if the site answers HTTP 429 / 403 in the log.",
            "default": 120
          },
          "minRequestIntervalMs": {
            "title": "Min delay between requests",
            "minimum": 0,
            "maximum": 60000,
            "type": "integer",
            "description": "Smallest gap between two requests, in milliseconds. Unlike the per-minute rate, this spreads the requests evenly instead of letting them go out in a burst. 0 = no gap.",
            "default": 0
          },
          "maxRequestRetries": {
            "title": "Max request retries",
            "minimum": 0,
            "maximum": 20,
            "type": "integer",
            "description": "Retries per request before it is marked as failed. Behind a proxy, a request the site turns away is also retried on a new proxy session up to 10 times without using up these retries.",
            "default": 5
          },
          "debugLog": {
            "title": "Debug log",
            "type": "boolean",
            "description": "Include debug messages in the run log.",
            "default": false
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}