Datasets API endpoint
Use Crawlora's Search the BBB businesses dataset API to search or inspect stored structured datasets as JSON. This page includes request parameters, cURL examples, response schema, validation behavior, credit cost, and a Playground link for testing before integration. Dataset endpoints read indexed records and do not apply proxy routing.
/datasets/bbb-businesses/searchSearches the BBB (Better Business Bureau) businesses index (dataset id enum value `bbb-businesses`) — business profiles crawled from bbb.org's own search/category-browse pages: computed A+-F letter-grade rating, paid-accreditation status, category, contact info, business details, operating hours, and products/services. Complaints, full reviews, and the full "reasons for rating"/service-area detail are NOT embedded here; each record instead carries complaints_url/reviews_url/more_info_url pointing at the live bbb-business-complaints/bbb-business-reviews/bbb-business-more-info endpoints for on-demand lookup. rating enum: `A+`, `A`, `A-`, `B+`, `B`, `B-`, `C+`, `C`, `C-`, `D+`, `D`, `D-`, `F`. sort enum: `relevance`, `rating_desc`, `rating_asc`, `accredited_first`, `name_asc`, `years_in_business_desc`. Developers commonly use this endpoint for repeatable dataset search, filtering, facets, local business enrichment, analytics, exports, and internal tools that need structured records beyond the limited manual refinement available in the Google Maps app. Authentication uses the x-api-key header, usage is metered with the credit cost shown on this page, and the request does not trigger live scraping or proxy routing.
Request parameters are generated from the active endpoint catalog. Dataset parameters filter, page, facet, or locate stored structured records; they do not configure a live scraper or proxy path.
| Parameter | Type | Required | Default | Description | Example |
|---|---|---|---|---|---|
| q | string | No | Full-text match on the business name/category, max 256 characters | ||
| category | string | No | Exact category filter, e.g. Plumber. Use the values returned by facets?facet=category | ||
| state | string | No | Exact 2-letter state/province filter, parsed from the profile URL, e.g. tx | ||
| city | string | No | Exact city filter, parsed from the profile URL | ||
| rating | string | No | Exact letter-grade rating filter. Enum: A+, A, A-, B+, B, B-, C+, C, C-, D+, D, D-, F Allowed values: A+, A, A-, B+, B, B-, C+, C, C-, D+, D, D-, F | ||
| min_rating_rank | integer | No | Numeric floor against the denormalized rating rank (A+=12 down to F=0), e.g. 10 for 'A- and above' | ||
| accredited | boolean | No | Accreditation filter; true keeps only accredited businesses | ||
| entity_type | string | No | Exact entity-type filter, e.g. Limited Liability Company (LLC) | ||
| run_id | string | No | Exact crawl run id filter | ||
| sort | string | No | Sort enum: relevance, rating_desc, rating_asc, accredited_first, name_asc, years_in_business_desc Allowed values: relevance, rating_desc, rating_asc, accredited_first, name_asc, years_in_business_desc | ||
| page | integer | No | 1 | Page number, defaults to 1 | |
| page_size | integer | No | 20 and maxes at 100 | Page size, defaults to 20 and maxes at 100; page * page_size must be <= 10000 | |
| x-api-key (header) | string | Yes | API key required |
curl -X GET "https://api.crawlora.net/api/v1/datasets/bbb-businesses/search?q=coffee&rating=A%2B&accredited=true&sort=relevance&page=1" \ -H "x-api-key: $CRAWLORA_API_KEY"
Send your scraping API key in the x-api-key header. Use the console API Keys page to rotate or select the active key.
Endpoint usage is metered in credits. The plan prices, included credits, limits, and overage rates below match the active backend billing configuration.
| Plan | Price | Included credits | Daily cap | Rate limit | Overage |
|---|---|---|---|---|---|
| Free | $0/mo | 2,000 | 500 daily credits | 5/min | No overage |
| Starter | $9/mo | 20,000 | 5,000 daily credits | 15/min | $0.75/1,000 overage credits when enabled |
| Growth | $29/mo | 100,000 | 25,000 daily credits | 45/min | $0.45/1,000 overage credits when enabled |
| Pro | $79/mo | 400,000 | No daily cap | 120/min | $0.30/1,000 overage credits |
| Business | $199/mo | 1,200,000 | No daily cap | 300/min | $0.20/1,000 overage credits |
| Enterprise | $499/mo | 5,000,000 | No daily cap | 1,000/min | $0.12/1,000 overage credits |
This endpoint reads stored indexed dataset records. It does not execute a live upstream Google Maps request, browser session, or proxy-routed scraping job.
- Each item carries `business_id`, `bbb_local_id`, `name`, `url`, `country`, `state`, `city`, `address`, `phone`, `website`, `rating`, `rating_rank`, `rating_reasons`, `accredited`, `accredited_since`, `years_in_business`, `category`, `categories`, business-detail fields (`bbb_file_opened`, `business_started`, `business_incorporated`, `entity_type`, `alternate_names`, `business_management`, `additional_phone_numbers`, `additional_websites`, `social_media`, `licensing_note`, `hours`, `products_and_services`), and the on-demand pointer fields `complaints_url`, `reviews_url`, `more_info_url`. - `rating_reasons` on this record is the shallow rating-card list bbb-business itself returns — often a single generic boilerplate bullet. Fetch `more_info_url` for the fuller per-factor reasons on a lower-rated business. - The maximum result window is `10000`; `page * page_size` must not exceed `10000`. - Invalid enum values return the standard invalid params envelope. - Returns an empty `items` array (not an error) when nothing matches or the dataset has no data yet. - Does not trigger live scraping. Example response: ```json { "code": 200, "msg": "OK", "data": { "dataset": "bbb-businesses", "items": [ { "business_id": "0825-1000223803", "bbb_local_id": "0825", "name": "Calixto Plumbing", "url": "https://www.bbb.org/us/tx/austin/profile/plumber/calixto-plumbing-0825-1000223803", "country": "us", "state": "tx", "city": "austin", "phone": "(512) 945-3143", "rating": "A+", "rating_rank": 12, "accredited": true, "category": "Plumber", "categories": ["Plumber", "Plumbing Renovation", "Commercial Plumber"], "complaints_url": "https://www.bbb.org/us/tx/austin/profile/plumber/calixto-plumbing-0825-1000223803/complaints", "reviews_url": "https://www.bbb.org/us/tx/austin/profile/plumber/calixto-plumbing-0825-1000223803/customer-reviews" } ], "page": 1, "page_size": 20, "total": 1, "sort": "accredited_first" } } ```
Crawlora does not silently return invalid dataset search results when filters, pagination, coordinates, or stored record lookups cannot be satisfied.
| Status | Common failure case |
|---|---|
| 400 | Invalid input, missing required parameter, invalid enum, bad coordinate pair, or result window beyond the dataset limit |
| 404 | Requested stored dataset item is not present |
| 429 | Plan or endpoint rate limit exceeded |
| 500 | Internal dataset query or storage error |
When possible, Crawlora returns structured error context so your integration can adjust filters, page size, location inputs, or lookup identifiers.
| Status | Description | Schema |
|---|---|---|
| 400 | Bad Request | #/definitions/app.Response |
| 429 | Too Many Requests | #/definitions/app.Response |
| 500 | Internal Server Error | #/definitions/app.Response |
{
"code": 200,
"msg": "OK",
"data": {
"dataset": "bbb-businesses",
"items": [
{
"business_id": "0825-1000223803",
"bbb_local_id": "0825",
"name": "Calixto Plumbing",
"url": "https://www.bbb.org/us/tx/austin/profile/plumber/calixto-plumbing-0825-1000223803",
"country": "us",
"state": "tx",
"city": "austin",
"phone": "(512) 945-3143",
"rating": "A+",
"rating_rank": 12,
"accredited": true,
"category": "Plumber",
"categories": [
"Plumber",
"Plumbing Renovation",
"Commercial Plumber"
],
"complaints_url": "https://www.bbb.org/us/tx/austin/profile/plumber/calixto-plumbing-0825-1000223803/complaints",
"reviews_url": "https://www.bbb.org/us/tx/austin/profile/plumber/calixto-plumbing-0825-1000223803/customer-reviews"
}
],
"page": 1,
"page_size": 20,
"total": 1,
"sort": "accredited_first"
}
}Request schema
No body schema
Response schema
#/definitions/datasets.bbbBusinessesSearchResponseDoc
| Field | Type | Required | Enum | Bounds | Example | Description |
|---|---|---|---|---|---|---|
| code | integer | No | 200 | |||
| data | datasets.BBBBusinessesSearchResponse | No | ||||
| data.dataset | string | No | ||||
| data.items | array | No | ||||
| data.items[].accredited | boolean | No | ||||
| data.items[].accredited_since | string | No | ||||
| data.items[].additional_phone_numbers | array | No | ||||
| data.items[].additional_websites | array | No | ||||
| data.items[].address | string | No | ||||
| data.items[].alternate_names | array | No | ||||
| data.items[].bbb_file_opened | string | No | ||||
| data.items[].bbb_local_id | string | No | ||||
| data.items[].business_id | string | No | ||||
| data.items[].business_incorporated | string | No | ||||
| data.items[].business_management | string | No | ||||
| data.items[].business_started | string | No | ||||
| data.items[].categories | array | No | ||||
| data.items[].category | string | No | Plumber | |||
| data.items[].city | string | No | ||||
| data.items[].complaints_url | string | No | On-demand pointers -- not crawled/embedded, see package doc above. | |||
| data.items[].country | string | No | State/City are parsed from the profile URL's /us|ca/<state>/<city>/... path segments -- BusinessResponse.Address is a free-text joined string, not structured, so it isn't a reliable filter/facet field on its own. | |||
| data.items[].crawled_at | string | No | ||||
| data.items[].discovery_source | string | No | Crawl bookkeeping. DiscoverySource records how the CURRENT document content was obtained (last-crawl mechanism), not first-discovery provenance -- keyword-sweep, category-grid, and Common Crawl discovery are deduplicated against the same business, so the same business is never double-enqueued no matter how many search/category cells or CC records surface it. A richer per-discovery-event location/category isn't tracked, only the coarse source. | |||
| data.items[].entity_type | string | No | Limited Liability Company (LLC) | |||
| data.items[].hours | array | No | ||||
| data.items[].hours[].day | string | No | ||||
| data.items[].hours[].hours | string | No | ||||
| data.items[].licensing_note | string | No | ||||
| data.items[].more_info_url | string | No | ||||
| data.items[].name | string | No | ||||
| data.items[].phone | string | No | ||||
| data.items[].products_and_services | array | No | ||||
| data.items[].rating | string | No | A+ | |||
| data.items[].rating_rank | integer | No | ||||
| data.items[].rating_reasons | array | No | ||||
| data.items[].reviews_url | string | No | ||||
| data.items[].run_id | string | No | ||||
| data.items[].schema_version | integer | No | ||||
| data.items[].social_media | array | No | ||||
| data.items[].state | string | No | ||||
| data.items[].url | string | No | ||||
| data.items[].website | string | No | ||||
| data.items[].years_in_business | string | No | ||||
| data.items[].years_in_business_num | integer | No | YearsInBusinessNum is a best-effort leading-digit parse of YearsInBusiness (a free-text upstream string, e.g. "3"), -1 when unparseable. Denormalized purely for numeric sorting -- YearsInBusiness itself stays a keyword, so a lexicographic string sort would wrongly rank "9" ahead of "12". | |||
| data.page | integer | No | ||||
| data.page_size | integer | No | ||||
| data.sort | string | No | ||||
| data.total | integer | No | ||||
| msg | string | No | OK |
Use environment variables for secrets and keep Crawlora API keys server-side.
curl -X GET "https://api.crawlora.net/api/v1/datasets/bbb-businesses/search?q=coffee&rating=A%2B&accredited=true&sort=relevance&page=1" \
-H "x-api-key: $CRAWLORA_API_KEY"Crawlora is designed for responsible structured public web data workflows. Customers are responsible for using Crawlora in compliance with applicable laws, third-party rights, target-platform rules, and Crawlora terms.
Read Crawlora terms