Chamber of Commerce Scraper | US Business Leads
Pricing
from $2.00 / 1,000 results
Chamber of Commerce Scraper | US Business Leads
Collect Chamber of Commerce business data in real time. Search a keyword and any US city to stream names, phones, websites, emails, addresses, employee size, key contacts, ratings, and reviews as clean JSON — with webhooks, per-result pricing, and a free plan sample.
Pricing
from $2.00 / 1,000 results
Rating
0.0
(0)
Developer
Emmanuel
Maintained by CommunityActor stats
0
Bookmarked
4
Total users
2
Monthly active users
19 days ago
Last modified
Categories
Share
Chamber of Commerce Real-Time Data
Live Chamber of Commerce business directory intelligence: keyword + US city search, full business records, and lead enrichment with phones, websites, emails, employee size, and key contacts. Checkbox features — enable only what you need. Structured JSON streamed to your dataset in real time.
Free plan notice: on the Apify Free plan this Actor exports a small sample of results per run (2 records). Upgrade to a paid Apify plan for full, unlimited exports.
Who is this for
Built for teams that sell to, research, or audit US local businesses:
- Lead generation — pull plumbers, dentists, insurance agencies, contractors, chambers of commerce… with phone, website, email, employee size, and a named contact ready for outreach.
- Local market sizing — see how many businesses of a category exist in a city, how well reviewed they are, and who has a working web presence.
- CRM & enrichment pipelines — stream records straight into Sheets, Airtable, HubSpot, Pipedrive, or a custom endpoint via webhooks.
- Local SEO & citation audits — check addresses, phone numbers, websites, and categories across a market in one pass.
- Partner & network research — find chambers of commerce and business associations by city, with their contacts and employee size.
- AI agents & MCP workflows — feed live directory answers into an agent (see below).
Feature matrix
| Feature | What it does | Default |
|---|---|---|
| 🔎 Business search by keyword + location | Multi-task search: pair a keyword ("chamber of commerce", "plumber", "dentist"…) with a US city ("Los Angeles, CA", "Austin, TX"). Each task collects its businesses page by page — every business on every page is a row, with name, category, address, phone, rating, and review count as published. | On |
| 📋 Listing Details | Turn business page URLs or numeric listing ids into full records: phone, website, email(s), employees, key contact, hours, services, payment methods, coordinates. | Off |
| ⭐ Reviews | Public customer reviews for the businesses requested in Listing Details — one row per review, capped per business. | Off |
| 🔗 Scrape By URL | Paste a business page URL (one full record), a category page URL (one row per business on that page), or a city page URL (its catalog). | Off |
| 🎯 Lead details (enrich in place) | Adds website, email(s), employee size, contact name and title, hours, services, socials, and coordinates to every row. Enrich, never filter — businesses with no extra details are still exported. | On |
| 📤 Webhooks | JSON or Slack. Every record is POSTed to your URL the moment it is collected — CRM, Zapier, Make, n8n. | Off |
Features combine freely: search + lead details is the classic lead-gen run; Listing Details + Reviews is the deep-dive run; Scrape By URL re-collects a page you already know.
Input reference
🔎 Business search
| Field | Type | Default | Notes |
|---|---|---|---|
enableSearch | boolean | true | Master switch for search. |
searchTasks | array | 2 demo rows | One row per search: keyword, location, optional maxResults. |
maxResultsPerTask | integer | 10 | Global default cap per task; override per task with maxResults. |
maxPagesPerTask | integer | empty | Optional catalog page cap (50 businesses per page). Empty = keep going until this task's businesses are all collected or the category ends. |
Search tasks:
{"enableSearch": true,"searchTasks": [{ "keyword": "chamber of commerce", "location": "Los Angeles, CA", "maxResults": 10 },{ "keyword": "plumber", "location": "Austin, TX", "maxResults": 50 },{ "keyword": "commercial insurance agency", "location": "Chicago, IL", "maxResults": 100 }],"maxResultsPerTask": 10}
Keyword tips: the closer the keyword is to a directory category ("plumber", "dentist", "restaurant", "insurance agency"), the tighter the list. If no category matches the keyword, the run falls back to all businesses in that city and says so in the log.
📋 Listing details
| Field | Type | Default | Notes |
|---|---|---|---|
enableListingDetails | boolean | false | Collect full records for specific businesses. |
listingUrls | array | [] | Full business page URLs, one per line. |
listingIds | array | [] | Numeric listing ids, one per line (the number inside a business URL, e.g. 2002915560). |
enableReviews | boolean | false | One row per public review for the requested businesses. Requires Listing Details. |
maxReviewsPerBusiness | integer | 10 | Reviews collected per business (1–50). |
{"enableListingDetails": true,"listingUrls": ["https://www.chamberofcommerce.com/business-directory/california/los-angeles/chamber-of-commerce/2002915560-los-angeles-area-chamber-of-commerce"],"listingIds": ["2002110354"],"enableReviews": true,"maxReviewsPerBusiness": 10}
🔗 Scrape By URL
| Field | Type | Default | Notes |
|---|---|---|---|
enableScrapeByUrl | boolean | false | Collect directly from URLs instead of searching. |
scrapeUrls | array | [] | Business pages, category pages, or city pages. |
{"enableScrapeByUrl": true,"scrapeUrls": ["https://www.chamberofcommerce.com/business-directory/texas/austin/plumber/","https://www.chamberofcommerce.com/business-directory/california/los-angeles/food-dining/restaurant/","https://www.chamberofcommerce.com/business-directory/new-york/new-york/"]}
🎯 Lead details
| Field | Type | Default | Notes |
|---|---|---|---|
enableLeadDetails | boolean | true | Adds website, email(s), employee size, contact name/title, hours, services, payment methods, socials, coordinates. Adds a little extra time per record. |
Lead details never change how many rows you get — they only fill in more of each row. Emails are looked up on the business's own website when the listing publishes none.
⚙️ Output & limits
| Field | Type | Default | Notes |
|---|---|---|---|
maxItems | integer | 10000 | Global cap on total rows across all features. |
concurrency | integer | 3 | Parallel detail lookups (1–8). |
delayBetweenRequestsMs | integer | 250 | Polite pacing between directory pages (0–5000 ms). |
🌐 Connection
proxyConfiguration defaults to Apify residential proxy, country US. Change the country or provide your own proxy URLs only if you need to — no other setup is required.
Output field reference
Every row contains featureType (search, listing_details, reviews, scrape_by_url) and scrapedAt.
| Field | Type | Notes |
|---|---|---|
name | string | Business name. |
listingId | string | null | Directory listing id. |
profileUrl | string | null | Canonical business page. |
phone | string | null | Published phone number. |
website | string | null | Published website. |
email / emails | string | null / array | Published mailbox(es) plus ones found on the business's own site. |
street, city, state, zipCode, location | string | null | Address parts and the full address. |
category, categories | string | null / array | Primary category and the full category path. |
rating, reviewCount | number | null | Public rating and review count. |
employees, employeesMin, employeesMax | string / integer | null | Employee size as published (e.g. "2-5", "20+") with parsed bounds. |
contactName, contactTitle | string | null | Key contact and role, when the listing publishes one. |
verified | boolean | Owner-verified badge on the listing. |
hours, services, paymentMethods | arrays | Public business hours, services, and accepted payment methods. |
socials | object | Social profiles. |
geo | object | null | { lat, lng }. |
description, imageUrl, priceRange | string | null | About text, image, published price range. |
searchKeyword, searchLocation, searchCategory, searchTaskIndex, searchTaskLabel, position | — | Search context for each row (null on URL-driven rows). |
detailsFetched | boolean | True when lead details were merged into this row. |
sourceUrl, pageType | string | null | For Scrape By URL rows: the page and what kind it was. |
requested, found | string / boolean | For Listing Details rows: what you asked for, and whether it exists. |
businessName, reviewIndex, rating, date, author, source, text | — | Review rows. |
Dataset views included: Overview (everything) and Leads (contact-ready columns).
Webhook guide
Set webhookUrl (and webhookFormat) and every record is also pushed to your endpoint the moment it is saved. Webhook delivery failures never stop a run.
JSON (webhookFormat: "json") — the full record, POSTed as application/json:
{"featureType": "search","name": "Los Angeles Area Chamber of Commerce","listingId": "2002915560","phone": "213-580-7500","website": "http://www.lachamber.com/","email": "info@lachamber.com","employees": "20+","contactName": "Maria Gonzalez","contactTitle": "Membership Director","city": "Los Angeles","state": "CA","category": "Chamber Of Commerce","scrapedAt": "2026-09-30T12:00:00.000Z"}
Slack (webhookFormat: "slack") — a Slack-ready message payload ({"text": "..."}):
{"text": ":office: *Los Angeles Area Chamber of Commerce*\n*Category:* Chamber Of Commerce • *Employees:* 20+\n*Location:* 350 S Bixel St Los Angeles, CA 90017\n*Phone:* 213-580-7500\n*Website:* http://www.lachamber.com/"}
Using with AI agents (MCP)
The Actor is an Apify Actor, so any MCP-capable agent (Claude, Cursor, custom agents) can run it through the Apify MCP server and read the dataset as structured JSON.
Ask your agent things like:
"Run the Chamber of Commerce Real-Time Data actor for "roofing contractor" in "Dallas, TX" with lead details on, return 25 rows, and list the companies that have a website but no published email."
Or chain it: search a market → enrich → push to the CRM of your choice through the webhook.
FAQ
Do I need my own proxy? No. Apify residential proxy (US) is on by default and is the supported route. You can change the country or bring your own proxy URLs in the Connection section if you prefer.
What does the free plan get me? Up to 2 rows per run as a trial. Paid plans export everything the run collects.
How fresh is the data? Every row is collected during the run and stamped with scrapedAt; nothing is cached between runs.
How many rows can one run produce? As many as you ask for, up to your run's item cap and your max total charge for that run. Businesses stream to the dataset as they arrive, so long runs stay light.
Can I get emails? Yes — when the listing publishes a mailbox it is included, and lead details also look for one on the business's own website. Not every business publishes an email.
Do filters drop rows? No. Every discovered business is exported; enrichment only ever adds fields.
Can I run it on a schedule? Yes — a scheduled run with the same input gives you a fresh snapshot each time.
Delivery
- Streaming: each record is written to the dataset the moment it is collected. Memory stays flat on large runs.
- Charge limit aware: if your max total charge for the run is reached, the run stops cleanly with a summary instead of failing.
- Free tier: a free Apify plan exports up to 2 results per run (owner-configurable,
FREE_TIER_MODE=blockblocks free runs entirely). - Run summary: the key-value store entry
OUTPUTcarries totals and the paywall object (detected,isPaying,pricingTier,limited,blocked,freeTierMaxItems).
Local development
npm installcp local.input.example.json local.input.jsoncp .env.example .env # only needed when you want to use your own proxy poolnpm run start:localnpm run typechecknpm run buildnpm run test:smoke # offline checks of parsing, matching, and gating
Local runs write JSONL to output/local_results.jsonl. Set "useProxy": false in local.input.json when your own connection reaches the directory directly; the input's Connection section is ignored locally, and the platform always uses Apify proxy.