Brownbook Scraper [From $2💰] | 44M+ Business Data avatar

Brownbook Scraper [From $2💰] | 44M+ Business Data

Pricing

from $1.90 / 1,000 results

Go to Apify Store
Brownbook Scraper [From $2💰] | 44M+ Business Data

Brownbook Scraper [From $2💰] | 44M+ Business Data

Scrape 44M+ global business listings from brownbook.net: name, address, phone, email, website, categories, hours, reviews, ratings, social links and claim status. Public sitemap tree and a challenge-free JSON API - no browser, no CAPTCHA.

Pricing

from $1.90 / 1,000 results

Rating

0.0

(0)

Developer

Ahmed Jasarevic

Ahmed Jasarevic

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

10 days ago

Last modified

Categories

Share

Brownbook Scraper — Scrape 44M+ Global Business Listings As brownbook.net Data

Scrape 44M+ global business listings from brownbook.net — names, addresses, phones, emails, websites, socials, categories, opening hours, photos, videos, reviews, ratings and claim status — as structured brownbook.net data you can export and schedule. Built for lead-gen agencies, citation-building services, business data aggregators and sales teams that need a B2B contact database without a ZoomInfo or D&B contract.

Main Use Cases For B2B Lead Lists And Local SEO Citation Data

  • B2B lead list / sales intelligence data — one row per company with phone, mobile, email, website and socials, ready to qualify.
  • NAP data for local SEO citation building — name, address, phone, website, city / state / zipCode, plus claimed, claimVerified, claimEndDate to find listings that still need claiming.
  • Global business database / business data aggregator feeds — the full 92-field record including NAICS business data (naicsCode, naicsTitle, naicsBreadcrumb), categories, tags, services, payment options.
  • Company email phone database — email, emails, additionalEmails, phone, mobile, voip, additionalPhones (see Legal on outreach).
  • CRM enrichment — pass known IDs to businessIds, get one rich record back per ID, no crawling.
  • Change monitoring — schedule the highest leaf sitemaps (most recently updated listings) and diff updatedAt / lastmod.

Build A Global Business Database Without Official API Access

brownbook.net is a Next.js site on Vercel behind Cloudflare. Its search UI is CAPTCHA-gated, but its sitemap tree and JSON API are not. This Actor enumerates IDs from the public sitemap tree — sitemap index → 31 index files → ~46,531 leaf sitemaps of 1,000 URLs each — then reads GET https://api.brownbook.net/app/api/v1/businesses/resource/<id> for the complete 92-field record as plain JSON. Extraction runs on CheerioCrawler: pure HTTP, no browser, no session pool, no cookies, no API key, no CAPTCHA solver. Reviews land in a second dataset, brownbookreviews. Endpoints, rejected alternatives and measured costs are below.

Input Parameters

FieldTypeRequiredDefaultNotes
sitemapIndexstring (select)No"1"Index file "1"…"31"; each lists 1,501 leaf sitemaps (~1.5M businesses). Comma-separated lists work over the API ("2,3,4").
sitemapLeafCountstring (select)No"1"Leaf sitemaps to expand; 1 leaf = 1,000 business URLs. Presets "1"…"1501" = 1,000 … 1,501,000 businesses.
businessIdsstringNo""Comma/space-separated numeric IDs fetched in full, e.g. "53562541, 53562540". Skips discovery.
startUrlsarrayNo[]Explicit leaf sitemaps (.../sitemap/50000.xml) or resource/<id> records instead of default discovery.
countrySamplebooleanNofalse30-row sample + total count per country from https://api.brownbook.net/businesses?country=<cc> (no pagination — coverage stats).
countriesstringNo"us,gb,de,au,ca,fr"Comma-separated ISO codes; only used in sample mode.
detailbooleanNotruetrue = 92-field record per ID; false = sitemap IDs only (cheapest).
includeMediabooleanNotrueFetch photo/video URLs; +1 request per business.
includeReviewsbooleanNotrueWrite reviews to brownbookreviews (business rows keep rating + reviewCount). Embedded reviews free; possible extras cost up to 5 requests.
maxReviewsPerBusinessintegerNo0Cap review rows per business — 0 = all, hard max 25 (5 pages × 5). Lowers Review charges and skips comments calls once hit.
maxItemsintegerNo5000Hard cap on business rows (1–250,000). Free accounts always capped at 50; review rows never consume this budget.
proxyobjectNo{ "useApifyProxy": false }Standard Apify proxy picker; applies to sitemap, JSON API and enrichment requests.

Legacy inputs still work: sitemapLeaves is read as sitemapIndex and maxLeafSitemaps as sitemapLeafCount.

Modes

ModeTriggerOutput
Sitemap (default)sitemapIndex / sitemapLeafCount setFull business records from the sitemap tree
By IDbusinessIds setOne rich record per ID — best for enrichment
Start URLsstartUrls setWhatever URLs you pass (leaf sitemaps or resource/<id>)
Country samplecountrySample: true30-row sample per country + totalFound counts
Taxonomynothing setCountry coverage, top categories, full category taxonomy

Output Fields

DatasetContains
defaultBusiness records plus meta rows (run_summary, sitemap_index, …)
brownbookreviewsOne row per review (business rows keep only rating and reviewCount)

The reviews dataset is an alias declared in .actor/actor.json (storages.datasets.brownbookreviews) and opened with Actor.openDataset({ alias }), so the platform creates it at run start with its own schema and the Reviews view and lists it in the run's Storage tab beside the default dataset (the Output tab carries a direct Reviews link). includeReviews: false leaves it untouched. Aliases allow letters, digits and underscores while dataset names reject underscores — hence lowercase brownbookreviews.

Default-dataset rows are tagged with type: business (full listing, fields below), business_sample (30-row country sample), country_coverage (per-country record counts), taxonomy (category/country taxonomies), sitemap_index (the discovered sitemap tree), business_url (sitemap IDs only, detail: false), run_summary (run configuration).

business fields

Identity & claim status — id, legacyBusinessId, name, shortName, slug, url, claimed, claimVerified, claimEndDate, approvedAt, businessProfileCompleted, profileCompleted, subscribed, userId, duplicateOf, closed, closedDate

Location — country, countryCode, state, city, area, address, addressLine1, addressLine2, addressLine3, addressExtra, zipCode, postcode, serviceArea, lat, lng

Contact — phone, mobile, voip, fax, email, emails, website, websites, websitesHost, additionalPhones, additionalWebsites, additionalEmails

Social links — socials (map), socialsPresent, facebook, twitter, instagram, linkedin, tiktok, youtube, skype, blog

Classification — categories, category, naicsCode, naicsTitle, naicsBreadcrumb, naicsConfidence, tags, services, products, specials, brands, associations, languages, paymentOptions, yearEstablished

Content & media — description, businessHours (day → intervals), hoursDisplay, specialOffers, logoUrl, imageCount, images, videoCount, videos, rating, reviewCount

Meta — createdAt, updatedAt, indexedAt, lastmod, scrapedAt, source

Meta rows and views

Non-business rows carry totalFound (per-country counts), indexCount (31), totalLeafSitemaps (~46,531), estimatedBusinessUrls (~46.5M), data (raw payload), mode (which of the five modes ran) and isPaying. Two views ship with the dataset: Businesses (name, city, countryCode, category, phone, email, website, claimed) and Contact leads (name, phone, mobile, email, website, facebook, instagram, linkedin, url).

brownbookreviews fields

type (review), reviewId, businessId, businessName, businessUrl, businessCountryCode, rating, comment, status, authorId, author, authorCountry, authorAvatar, mediaUrl, reply, createdAt, updatedAt, source, scrapedAt.

reviewId (not id): id is a reserved keyword when declared in a dataset schema — the platform rejects it with NOT SUPPORTED: keyword "id", use "$id".

Example Input And Output

First 5,000 US listings (5 leaf sitemaps): { "sitemapIndex": "1", "sitemapLeafCount": "5", "maxItems": 5000 }

Enrich specific businesses: { "businessIds": "53562541,53562540,53562539" }

Cheapest pass — IDs only, no detail calls: { "detail": false, "maxItems": 20 }

Targeted leaf sitemaps (recently-updated listings): { "startUrls": ["https://www.brownbook.net/sitemap/46000.xml"] }

Country coverage statistics: { "countrySample": true, "countries": "us,gb,de,au,ca,fr,de,it" }

A business row:

{
"type": "business",
"id": 53562541,
"name": "Riverside Dental Studio",
"url": "https://www.brownbook.net/business/53562541/riverside-dental-studio/",
"claimed": true,
"claimVerified": true,
"closed": false,
"countryCode": "us",
"city": "Chicago",
"address": "1420 W Riverside Drive, Chicago, IL 60610",
"zipCode": "60610",
"lat": 41.9217,
"lng": -87.6513,
"phone": "+1 312 555 0142",
"email": "reception@riversidedental.example",
"website": "https://www.riversidedental.example",
"category": "Dentist",
"naicsCode": "621210",
"rating": 4.7,
"reviewCount": 18,
"lastmod": "2026-09-18T07:31:12Z",
"scrapedAt": "2026-10-07T09:14:22Z",
"source": "brownbook"
}

A review row from brownbookreviews:

{
"type": "review",
"reviewId": 88123456,
"businessId": 53562541,
"businessName": "Riverside Dental Studio",
"rating": 5,
"comment": "Seen on time, friendly team, clear pricing.",
"author": "J. Moreno",
"createdAt": "2026-06-12T15:02:10Z",
"scrapedAt": "2026-10-07T09:14:22Z",
"source": "brownbook"
}

Brownbook API Endpoints And The Sitemap Enumeration Strategy

Endpoints used

PurposeEndpoint
Sitemap index (root)https://api.brownbook.net/sitemap_indexes.xml
Index files (31)https://www.brownbook.net/sitemap/index_<n>.xml
Leaf sitemaps (~46,531)https://www.brownbook.net/sitemap/<n>.xml — 1,000 URLs each
Business detail (the data source)GET https://api.brownbook.net/app/api/v1/businesses/resource/<id>
Photos & videosGET .../api/v1/businesses/resource/<id>/media
Reviews (paginated, 5 per page)GET .../api/v1/business/<id>/comments?page=<n>
Country coverage + countsGET .../api/v1/businesses/countries
Top countriesGET .../api/v1/businesses/countries/top
Top categoriesGET .../api/v1/businesses/categories/top
Full category taxonomyGET .../api/v1/uberall-categories
City autocompleteGET .../api/v1/autocomplete/cities/?search=<q>
Country sample (30 rows)GET https://api.brownbook.net/businesses?country=<cc>

Why this strategy

  1. Embedded JSON blob → not viable. The homepage ships Next.js App Router RSC flight data (self.__next_f.push) with only shell markup — no __NEXT_DATA__, no application/ld+json, no listing data.
  2. Algolia / third-party search backend → none. No algoliasearch(), Meilisearch, Elasticsearch, TypeSense or Coveo anywhere in the bundle.
  3. Internal JSON API → found. The frontend bundle calls baseURL: "https://api.brownbook.net/app" with api/v1/... routes; businesses/resource/<id> returns the complete 92-field record as plain JSON with no cookies, no API key and no Cloudflare challenge.
  4. The CAPTCHA route is deliberately skipped. POST /app/api/v1/businesses/search returns HTTP 422 Please complete the CAPTCHA verification to continue. This Actor never calls it.
  5. Sitemap tree → the enumeration key. robots.txt publishes Sitemap: https://api.brownbook.net/sitemap_indexes.xml, expanding into 31 index files → ~46,531 leaf sitemaps → ~46.5M <loc>https://www.brownbook.net/business/<id>/<slug>/</loc> URLs. Every record is keyed by its numeric ID, so the corpus is reachable without search: sitemap for IDs, JSON API for data.

Result: CheerioCrawler only — no Playwright, no browser, no session pool, no CAPTCHA solver, no Chrome process to pay for, yet the Actor still defaults to 2 GB of RAM (see below).

Scrape Brownbook Business Listings At Scale: Cost, RAM And Pricing

  • 1 request per business for the full record — the API response is parsed straight from the crawl response, so it is not fetched twice. +1 request when includeMedia is on.
  • Reviews are free when embedded in the detail record; only businesses that may have more (5+ embedded, or none embedded but a rating) hit /business/<id>/comments, capped at 5 pages of 5. Typical run: 2–3 requests per business, worst case 7.
  • 2,048 MB RAM by default (range 256–4,096). Pure HTTP makes memory cheap in compute units, but on Apify the CPU share grows with memory and too little of it throttles the autoscaled pool to ~3 in-flight requests. Same 1,000-business crawl: 59 s / $0.06 at the 2 GB default, 132 s / $0.08 at 1 GB, 240 s / $0.10 at 512 MB (100 businesses: ~5–9 s). 1 GB is the trap in the middle — half the RAM halves the CPU share, so the run more than doubles and costs more; a faster run is usually the cheaper run.
  • Concurrency capped at 8 (run time scales almost linearly with it), retries capped at 3, 90 s per-request timeout. Raising the cap to 16 on the same crawl gave no gain (69 s vs 59 s): the pool settles at ~7–8 in flight, because per-request latency and CPU, not the cap, are the limit. maxRequestsPerCrawl, maxItems, concurrency and timeouts are all hard-capped.
  • Free accounts are capped at 50 businesses; paying accounts are unlimited up to maxItems (250,000).

Pay-per-event pricing

Reviews are billed separately from businesses: only items pushed to the default dataset are charged by the built-in result event, while reviews-dataset items are never billed automatically — which is why billableReviews() issues an explicit charge.

EventBilled whenPrice
resulta business row is written to the default dataset$0.002 (FREE) → $0.0019 (GOLD+)
Reviewa review row is written to brownbookreviews$0.001 → $0.0009
Actor Startthe run starts$0.00005

Setup — Apify Console → this Actor → Monetization → Pay per event: add a custom event named Review (it must match REVIEW_EVENT in src/routes.ts) with the per-row price; optionally enable the synthetic apify-default-dataset-item event to bill business rows too (the platform charges dataset writes, no code needed); set minimalMaxTotalChargeUsd so a run cannot start without covering one result.

billableReviews() in src/main.ts then behaves like this:

  • Not on pay-per-event, or Review not registered → reviews pushed free and a one-off [charge] warning says the setup is missing.
  • On pay-per-event → Actor.charge({ eventName: 'review', count }) runs before each review batch and only chargedCount rows are pushed.
  • Budget exhausted (eventChargeLimitReached) → remaining reviews are dropped and the platform stops the run.
  • Any charging error → the batch is pushed unpaid and logged; billing trouble never loses data.

maxItems and the review charge budget are independent. maxReviewsPerBusiness is the cheapest lever on the review bill: a cap of 5 skips most comments calls and cuts Review charges directly.

Integrations & Automation

  • Apify API — every input field is a JSON property, so any run is one POST of the input object to the Actor's run endpoint (the Console's API tab pre-fills the exact URL and token); results come back from the dataset endpoint as JSON, CSV, Excel, XML, HTML or RSS.
  • Webhooks — fire on run success or dataset item creation and push rows into your CRM, warehouse or lead queue; the reviews dataset can carry its own webhook.
  • Zapier and Make — native Apify integrations, so a finished run can append rows to Google Sheets, Airtable, HubSpot or Slack without code.
  • Recommended schedule: weekly new-listing monitoring. Brownbook is community-edited, so a recurring run beats one giant crawl — schedule weekly with startUrls on the highest leaf sitemaps (most recently updated listings) and a modest maxItems, then diff updatedAt / lastmod. Recurring schedules also improve Store recommendation signals.

Local Development

npm ci · npm run build (tsc) · npm run lint (eslint, zero warnings policy) · npm test (vitest: sitemap parsing + row building) · npm run start:dev. Local runs read input from storage/key_value_stores/default/INPUT.json, e.g. { "businessIds": "53562541,53562540", "maxItems": 10 }. Set APIFY_USER_IS_PAYING=1 to lift the 50-record free-account cap while testing; results land in storage/datasets/default and storage/datasets/brownbookreviews.

FAQ

What is the best way to access Brownbook business listings at scale?

Enumerate IDs from the public sitemap tree, then read each record from the JSON API. The index expands into 31 files and ~46,531 leaf sitemaps of 1,000 URLs, every <loc> carrying the numeric ID; GET .../businesses/resource/<id> returns the 92-field record as plain JSON with no cookies, API key or challenge. The search route (POST .../businesses/search) returns HTTP 422 CAPTCHA verification and is never called.

Is there an official Brownbook API?

Yes for records, no for bulk export: api.brownbook.net record, media, comments, countries, categories and autocomplete endpoints answer as plain JSON without authentication (docs.brownbook.net documents the API), but the search route is CAPTCHA-gated (HTTP 422). Bulk access means the published sitemap tree plus the per-record API — this Actor's entire path.

What are the alternatives to Brownbook for global business data?

Store options: brownbook-business-scraper, brownbook-business-scraper and brownbook-email-scraper, plus yellowpages-scraper and yelp-business-scraper. Commercial benchmarks are ZoomInfo, D&B, Infobel, Kompass, Yellow Pages and Yelp; this Actor is the pay-per-event route to Brownbook's 44M+ listings — the one that skips the CAPTCHA-gated search UI by enumerating the sitemap tree.

Can I export NAP data from Brownbook for local SEO citation building?

Yes — a core job of this Actor. Business rows carry name, address, addressLine1/2/3, city, state, zipCode/postcode, country/countryCode, lat/lng, phone and website; the Contact leads view flattens phone, mobile, email, website and socials, while claimed, claimVerified and claimEndDate show which listings still need claiming.

Are there cheaper alternatives to ZoomInfo and D&B for global business contact data?

Directory-based sources are the usual answer, and this Actor bills per event instead of by subscription: result $0.002 (FREE) → $0.0019 (GOLD+) per business row, Review $0.001 → $0.0009, Actor Start $0.00005 per run. Free accounts are capped at 50 businesses; paying accounts go to maxItems (250,000).

Can I legally scrape Brownbook listings for a commercial project?

Only public surfaces: robots.txt allows / and the sitemap tree, and the disallowed /ajax/, /account/*, /businesses/ and /review/add/ are never touched — no login, no authentication bypass, no CAPTCHA solving. Compliance with Brownbook's terms and data-protection law (GDPR/CCPA, since rows include contact data) is your responsibility — see Legal.


SEO Keywords

brownbook scraper, brownbook API, brownbook.net data, brownbook alternative, brownbook business listings, global business database, B2B contact database, company email phone database, citation building data, NAP data for local SEO, business directory data export, business data aggregator, sales intelligence data, B2B lead list, NAICS business data, Yellow Pages alternative, Yelp alternative for B2B, ZoomInfo alternative, D&B alternative, Infobel alternative, Kompass alternative

For AI Agents & LLM Apps

Machine-oriented reference for calling this Actor.

Purpose — enumerate brownbook.net business IDs from the public sitemap tree and return 92-field business records plus a separate reviews dataset.

Minimal working input (sitemap mode, trimmed to the free-account ceiling): { "sitemapIndex": "1", "sitemapLeafCount": "1", "maxItems": 50 }

Variant — enrichment mode (no crawling, one record per known ID): { "businessIds": "53562541,53562540", "maxItems": 10 }

Output field list — default dataset, grouped: identity/claim (id, legacyBusinessId, name, shortName, slug, url, claimed, claimVerified, claimEndDate, duplicateOf, closed); location (country, countryCode, state, city, area, address, addressLine1/2/3, zipCode, postcode, serviceArea, lat, lng); contact (phone, mobile, voip, fax, email, emails, website, websites, additionalPhones, additionalWebsites, additionalEmails); socials (socials, socialsPresent, facebook, twitter, instagram, linkedin, tiktok, youtube, skype, blog); classification (categories, category, naicsCode, naicsTitle, naicsBreadcrumb, naicsConfidence, tags, services, products, paymentOptions, yearEstablished); content/media (description, businessHours, hoursDisplay, logoUrl, imageCount, images, videoCount, videos, rating, reviewCount); meta (createdAt, updatedAt, indexedAt, lastmod, scrapedAt, source); meta rows (type, totalFound, indexCount, totalLeafSitemaps, estimatedBusinessUrls, data, mode, isPaying). Reviews dataset: type, reviewId, businessId, businessName, businessUrl, businessCountryCode, rating, comment, status, authorId, author, authorCountry, authorAvatar, mediaUrl, reply, createdAt, updatedAt, source, scrapedAt.

Behaviors an agent should know

  • Mode priority — businessIds, startUrls or countrySample: true each trigger their own mode; otherwise sitemap discovery runs from sitemapIndex / sitemapLeafCount; with nothing set the run emits coverage/taxonomy rows only. detail: false returns sitemap IDs only, with no contact fields.
  • Bill-relevant defaults — includeMedia: true adds 1 request per business, includeReviews: true writes review rows the Review event bills, maxReviewsPerBusiness: 0 keeps every review (max 25 per business), maxItems defaults to 5000; free accounts stay hard-capped at 50 businesses and review rows never consume that budget.
  • sitemapIndex accepts a comma-separated list over the API ("2,3,4"); sitemapLeaves and maxLeafSitemaps are accepted as legacy aliases.
  • Keep the 2 GB default memory — CPU share scales with memory (1 GB measured 132 s / $0.08, 512 MB 240 s / $0.10, versus 59 s / $0.06 at 2 GB on the same 1,000 businesses). Concurrency is fixed at 8 (16 measured no gain), 3 retries, 90 s timeout.
  • reviewId, never id — the platform rejects id in a dataset schema with NOT SUPPORTED: keyword "id", use "$id".
  • Two datasets — business rows in default, reviews in the alias brownbookreviews; read them separately.

Billing model — pay per event: result ($0.002 → $0.0019 per business row), Review ($0.001 → $0.0009 per review row), Actor Start ($0.00005 per run).

This Actor is an independent third-party tool. It is not affiliated with, endorsed by, sponsored by or connected with brownbook.net or its operator.

It accesses only what the site publishes for all user-agents: the public sitemap tree (robots.txt allows / and the sitemap; it disallows /ajax/, /account/*, /businesses/ and /review/add/, none of which this Actor touches) and the public JSON record endpoints, which answer without cookies, credentials or an API key. No login, no authentication bypass, no CAPTCHA solving — the CAPTCHA-gated search endpoint (POST .../businesses/search, HTTP 422) is deliberately never called, and no browser is driven.

Output includes published business contact data — names, addresses, phone numbers, emails, websites and social profiles — plus third-party submitted review content. You are responsible for your own compliance with brownbook.net's terms of service and with applicable data-protection law (GDPR/CCPA where your use covers EU or California personal data), and this contact data must not be used for unsolicited commercial outreach in violation of applicable law. This Actor is a data-collection tool; it provides no legal advice and claims no particular use is permitted.