GoodFirms Companies & Reviews Scraper avatar

GoodFirms Companies & Reviews Scraper

Pricing

Pay per event

Go to Apify Store
GoodFirms Companies & Reviews Scraper

GoodFirms Companies & Reviews Scraper

🏢 Extract GoodFirms company profiles, agency leads, public contacts, services, locations, portfolios, ratings, and detailed client reviews into separate datasets.

Pricing

Pay per event

Rating

0.0

(0)

Developer

Stas Persiianenko

Stas Persiianenko

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

Turn public GoodFirms agency directories and company profiles into structured company and review data.

Use the scraper to build agency lead lists, enrich vendor shortlists, compare service providers, or monitor client feedback over time.

It accepts GoodFirms category pages, listing pages, and individual company profile URLs.

It returns two clean datasets:

  • 🏢 Companies — identity, website, description, services, pricing band, team size, founding year, locations, public contacts, social links, rating totals, and portfolio items.
  • Reviews — reviewer and project context, review text, dates, overall rating, and detailed quality, schedule, communication, and value ratings.

No GoodFirms login, cookies, or account credentials are required.

What does the GoodFirms scraper do?

The Actor opens public pages on goodfirms.co and extracts structured business information.

You can start from a broad service category such as web scraping companies.

You can also target one or more company profile URLs directly.

For category inputs, the Actor discovers unique company profiles and follows pagination until it reaches your company limit.

When profile enrichment is enabled, it visits each company profile and captures fields not available in the listing.

When review extraction is enabled, it follows public review pagination and saves individual reviews separately.

Who is it for?

Sales and lead-generation teams

Build prospect lists of agencies in a service category or location.

Export company websites, public contacts, services, size bands, and locations into a CRM.

Procurement and vendor research teams

Enrich a shortlist with verified company details, portfolio examples, ratings, and client feedback.

Compare agencies without copying profile pages manually.

Agencies and competitive-intelligence teams

Track competitor ratings, review volume, service positioning, and portfolio changes.

Schedule recurring runs and compare snapshots in your own database.

Reputation and customer-success teams

Collect recent public reviews with project context and detailed ratings.

Feed the Reviews dataset into dashboards, alerts, or sentiment-analysis workflows.

Why use this Actor?

  • Two purpose-built datasets instead of mixed company and review rows.
  • Listing and profile modes for cheap discovery or deeper enrichment.
  • Public contacts and services exposed by GoodFirms profiles.
  • Detailed review context including project questions and rating breakdowns when available.
  • Canonical deduplication by company profile URL and review ID.
  • Location filtering that fails closed when source location data is missing.
  • Date filtering for repeat review-monitoring jobs.
  • Residential proxy sessions with blocked media resources to reduce bandwidth.
  • JSON, CSV, Excel, XML, and RSS exports through Apify datasets.

What GoodFirms data can you extract?

DatasetFieldDescription
CompaniesnameCompany or agency name
CompaniesprofileUrlCanonical GoodFirms company profile URL
CompanieswebsitePublic company website
CompaniesdescriptionProfile description or positioning statement
CompaniesratingAggregate GoodFirms rating
CompaniesreviewCountNumber of public reviews shown by GoodFirms
CompanieshourlyRatePublished hourly price range
CompaniesteamSizeEmployee band shown on the profile
CompaniesfoundedYearPublished founding year
Companiesphone, emailPublic profile contact details when available
CompaniesaddressesStructured office locations
CompaniesservicesService catalog from the profile
CompaniessocialLinksPublic LinkedIn, Facebook, X, Instagram, and similar links
CompaniesportfolioItemsPortfolio titles and image URLs
Reviewstitle, bodyReview headline and public review text
ReviewspublishedAtReview publication timestamp
ReviewsreviewerName, reviewerRolePublic reviewer identity and role context
ReviewsprojectNameProject name when provided
ReviewsserviceProvidedService associated with the project
ReviewsprojectSummaryPublic project description
ReviewspositiveFeedbackWhat the reviewer appreciated most
ReviewsimprovementFeedbackWhat the reviewer said could improve
Reviewsdetailed ratingsQuality, schedule, communication, and value scores when exposed

How to scrape GoodFirms companies in 5 steps

  1. Open the Actor input page.
  2. Add a GoodFirms category, listing, or company profile URL.
  3. Choose whether to enrich company profiles and collect reviews.
  4. Set conservative company and review limits for your first run.
  5. Click Start and export the Companies or Reviews dataset.

For a quick test, use one company profile, one company, and two reviews.

That input normally finishes well within the default timeout.

Input options

GoodFirms URLs

Add one or more URLs from goodfirms.co.

Supported routes include:

  • service category pages;
  • ranked company listing pages;
  • location-specific listing pages;
  • individual /company/... profiles.

Other domains are rejected before browser extraction starts.

Category slug

Instead of a full URL, enter a path such as:

it-services/web-scraping

The Actor converts it to a GoodFirms URL and combines it with any supplied start URLs.

Location filter

Enter a city, region, or country such as India, California, or London.

A company is kept only when that text appears in a public address.

Profiles with no matching location do not pass the filter.

Company enrichment

Set enrichProfiles to false for listing-only collection.

Set it to true for website, description, team size, founding year, contacts, services, social links, multiple addresses, and portfolios.

Review extraction automatically enables profile enrichment.

Review controls

Use includeReviews to create review records.

Use maxReviewsPerCompany to cap pagination for each company.

Use reviewsDateFrom with an ISO date such as 2025-01-01 to skip older reviews. When a cutoff is set, reviews without a parseable publication date are excluded.

Proxy configuration

GoodFirms challenges ordinary datacenter traffic.

The default input therefore uses a US residential Apify Proxy session.

Keep the default unless you have already validated another proxy configuration.

Example input: company profile and reviews

{
"startUrls": [
{ "url": "https://www.goodfirms.co/company/infograins" }
],
"enrichProfiles": true,
"includeReviews": true,
"maxItems": 1,
"maxReviewsPerCompany": 10,
"reviewsDateFrom": "2025-01-01",
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": ["RESIDENTIAL"],
"apifyProxyCountry": "US"
}
}

Example input: category lead list

{
"startUrls": [
{ "url": "https://www.goodfirms.co/it-services/web-scraping?sort_by=rating" }
],
"locationFilter": "India",
"enrichProfiles": false,
"includeReviews": false,
"maxItems": 25,
"maxReviewsPerCompany": 0
}

Use listing-only mode when company identity, price range, rating, review count, and location are enough.

Example company output

{
"name": "Infograins",
"profileUrl": "https://www.goodfirms.co/company/infograins",
"website": "https://infograins.com",
"rating": 4.9,
"reviewCount": 100,
"hourlyRate": "$25 - $49",
"teamSize": "50 - 249",
"foundedYear": 2011,
"city": "Indore",
"region": "Madhya Pradesh",
"country": "in",
"services": ["Mobile App Development", "Web Development", "Software Development"],
"profileEnriched": true,
"sourceUrl": "https://www.goodfirms.co/company/infograins",
"scrapedAt": "2026-07-22T00:00:00.000Z"
}

Fields not published on a particular profile are returned as empty strings, empty arrays, or null for nullable numeric values.

Example review output

{
"reviewId": "58684",
"companyName": "Infograins",
"companyProfileUrl": "https://www.goodfirms.co/company/infograins",
"title": "Infograins Group was very professional and had the highest standards.",
"rating": 5,
"reviewerName": "Michele Bruno",
"reviewerRole": "Founder at Hospitality foods",
"projectName": "IT Staff Augmentation for IT services company",
"serviceProvided": "IT Services",
"qualityRating": 5,
"scheduleRating": 5,
"permalink": "https://www.goodfirms.co/company/infograins#review-58684"
}

The exact fields available depend on what the reviewer chose to publish.

Separate Companies and Reviews datasets

Company profiles and reviews have different shapes and different export use cases.

The Actor stores companies in the default Companies dataset.

It stores individual reviews in the separate Reviews dataset.

Open the run page and select the output you need.

Each dataset has its own table view and validation schema.

This avoids a type discriminator and makes CSV exports easier to use.

How much does it cost to scrape GoodFirms?

The Actor uses pay-per-event pricing.

A small one-time start event covers run setup.

Company records and review records are charged separately.

Current BRONZE prices are:

  • start: $0.0075 per run;
  • company: $0.0078892 per saved company;
  • review: $0.016044 per saved detailed review.

Higher Apify plans receive tiered per-record discounts. At DIAMOND, the company price is $0.002209 and the review price is $0.0044923.

Residential proxy transfer and platform usage are covered by Actor pricing rather than requiring a separate GoodFirms account.

For the cheapest discovery run, disable profile enrichment and reviews.

For due diligence, enrich only a small shortlist and cap reviews per company.

Tips for reliable GoodFirms extraction

  • 🎯 Start with one company and two reviews before scaling.
  • 📉 Use listing-only mode for broad lead discovery.
  • 🏢 Enrich only the companies that need contact and service details.
  • ⭐ Use a date cutoff for scheduled review monitoring.
  • 🌍 Keep the residential proxy default when GoodFirms blocks other traffic.
  • 🔗 Prefer canonical GoodFirms category and company URLs.
  • ⏱️ Increase limits gradually because profile and review pages require browser navigation.
  • 📊 Store snapshots in your own dataset or warehouse for change tracking.

Integrations and automation workflows

CRM enrichment

Send the Companies dataset to HubSpot, Salesforce, Airtable, or a spreadsheet.

Use profileUrl as a stable external key and website as a domain-matching field.

Vendor shortlist research

Start with a category listing in listing-only mode.

Filter candidates by location, rating, review count, and hourly rate.

Run a second enrichment job on the selected profile URLs.

Reputation monitoring

Schedule a profile run weekly.

Set reviewsDateFrom to your monitoring window.

Compare reviewId values with your stored review table and alert on unseen IDs.

BI and data warehouses

Connect the Apify dataset API to BigQuery, Snowflake, PostgreSQL, or a custom ETL job.

Keep Companies and Reviews as related tables joined by companyProfileUrl.

AI review analysis

Send review titles, bodies, project summaries, and detailed ratings to an LLM workflow.

Classify themes, summarize praise, or identify recurring improvement requests.

Use the API with Node.js

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/goodfirms-companies-reviews-scraper').call({
startUrls: [{ url: 'https://www.goodfirms.co/company/infograins' }],
maxItems: 1,
includeReviews: true,
maxReviewsPerCompany: 10
});
const companies = await client.dataset(run.defaultDatasetId).listItems();
console.log(companies.items);

The Reviews dataset is exposed separately on the run output page and in the run storage metadata.

Use the API with Python

import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/goodfirms-companies-reviews-scraper').call(run_input={
'startUrls': [{'url': 'https://www.goodfirms.co/company/infograins'}],
'maxItems': 1,
'includeReviews': True,
'maxReviewsPerCompany': 10,
})
for item in client.dataset(run['defaultDatasetId']).iterate_items():
print(item)

Use the API with cURL

curl -X POST \
"https://api.apify.com/v2/acts/automation-lab~goodfirms-companies-reviews-scraper/runs?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"startUrls": [{"url":"https://www.goodfirms.co/company/infograins"}],
"maxItems": 1,
"includeReviews": true,
"maxReviewsPerCompany": 10
}'

Poll the returned run ID, then read the datasets from the run output links.

Use GoodFirms data with MCP

Apify MCP lets Claude Code, Claude Desktop, Cursor, and VS Code run the Actor as a tool.

Claude Code

$claude mcp add --transport http apify "https://mcp.apify.com?tools=automation-lab/goodfirms-companies-reviews-scraper"

Claude Desktop, Cursor, or VS Code

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=automation-lab/goodfirms-companies-reviews-scraper"
}
}
}

Example prompts:

  • “Find 20 highly rated web scraping agencies on GoodFirms and return their locations and hourly rates.”
  • “Extract the latest 25 reviews for this GoodFirms company and summarize the strongest positive themes.”
  • “Build a vendor shortlist with websites, team sizes, services, ratings, and portfolio titles.”

Data quality and deduplication

Companies are deduplicated by canonical GoodFirms profile URL.

Review records are deduplicated by company profile URL plus public review ID.

Structured JSON-LD is preferred for stable company and rating fields.

Rendered page content is used only for fields not present in structured data, including team size, portfolios, reviewer roles, project answers, and rating breakdowns.

Every record includes sourceUrl and scrapedAt for provenance.

Limitations

GoodFirms can change its page structure or anti-bot controls without notice.

Public profile completeness varies by company.

Some profiles do not publish an email, phone number, portfolio, reviewer role, or detailed rating category.

Listing-only mode does not include all profile fields.

Review date cutoffs fail closed: reviews without a parseable source publication date are excluded when reviewsDateFrom is set.

The Actor collects public GoodFirms data only and does not visit agency websites to discover extra contacts.

Residential browser extraction is slower than direct API collection.

This Actor extracts information visible on public GoodFirms pages without login.

Scraping legality depends on your jurisdiction, purpose, contractual obligations, and how you use personal data.

Use the data responsibly.

Do not use it for harassment, discrimination, spam, or unlawful profiling.

Review GoodFirms terms, robots guidance, applicable privacy laws, and your organization’s compliance requirements.

If you process reviewer information, collect only what you need and apply appropriate retention and access controls.

Troubleshooting

The run says no matching companies were extracted

Check that every input URL is on goodfirms.co and points to a category, listing, or /company/... profile.

If you set locationFilter, confirm the exact city, region, or country appears on the public profile.

The filter intentionally fails closed when no matching location is published.

The run receives a security challenge

Use the default Apify residential proxy configuration.

Avoid replacing it with a datacenter-only group unless you have tested that route recently.

The Actor rotates sessions after blocked responses, but persistent target-side challenges can still exhaust retries.

Review output is smaller than expected

Increase maxReviewsPerCompany.

Remove or move reviewsDateFrom earlier.

Confirm the profile’s public review count and remember that some reviews may not expose a parseable date.

A field is empty

GoodFirms profiles vary in completeness.

An empty value means the field was not publicly exposed in the supported profile surfaces at extraction time.

Frequently asked questions

Can I scrape multiple GoodFirms categories in one run?

Yes. Add multiple listing URLs and set a shared maxItems cap.

Companies appearing in several categories are saved once.

Can I scrape only company listings without opening profiles?

Yes. Set enrichProfiles and includeReviews to false.

This is the fastest option for broad agency discovery.

Can I collect every review for a company?

Set maxReviewsPerCompany high enough for the profile’s public review count.

Start with a smaller value to confirm runtime and cost first.

Does the Actor need GoodFirms credentials?

No. It uses anonymous public pages.

Can I filter reviews by date?

Yes. Use an ISO date in reviewsDateFrom.

Can I use my own proxies?

Yes, through proxyConfiguration.

Residential Apify Proxy is the tested default.

Use source-specific Actors when provenance and source coverage matter.

Combine their datasets in your own warehouse for broader vendor intelligence.

Support

If a valid public GoodFirms page fails, open an Actor issue with:

  • the input URL;
  • the run ID;
  • the expected company or review;
  • the relevant log excerpt.

Do not include private credentials or unrelated personal information.

We use reproducible examples to investigate page changes and extraction gaps.