# GoodFirms Company Scraper (`parsebird/goodfirms-scraper`) Actor

Scrape GoodFirms companies from any category, location or directory listing: rating, reviews, hourly rate, employees, founded year, address, phone, website, plus service and industry focus, portfolio and clients from profiles.

- **URL**: https://apify.com/parsebird/goodfirms-scraper.md
- **Developed by:** [ParseBird](https://apify.com/parsebird) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.99 / 1,000 companies

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### GoodFirms Company Scraper

GoodFirms Company Scraper extracts **IT, software, and marketing service providers from GoodFirms.co**: company name, rating, review count, hourly rate, team size, founding year, full address, phone, website, and a highlighted client review. With profile details on, each company also gets its tagline, full description, service, industry, and client focus percentages, portfolio, notable clients, office locations, social links, and the public contact email listed on GoodFirms.

<table><tr>
<td style="border-left:4px solid #1F7AE0;padding:12px 16px;font-weight:600">
Paste any GoodFirms category, city, directory, or sorted listing and get every company on it, 48 per page, with 40+ fields including street address, phone, contact email, and the exact percentage split of each company's services, industries, and client sizes.
</td>
</tr></table>

##### Copy to your AI assistant

Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor.

```
Actor: parsebird/goodfirms-scraper — scrapes companies from GoodFirms.co listings and profiles. Input: {"searchUrls": ["https://www.goodfirms.co/companies/web-development-agency", "https://www.goodfirms.co/companies/web-development-agency/new-york?sort_by=rating", "https://www.goodfirms.co/company/sdlc-corp"] (listing, city, directory or sorted URLs, or /company/ profiles; also accepts "searchUrl": "<one URL>"), "maxItems": 0 (0 = no limit), "maxPages": 0 (per URL, 48 companies per page), "includeProfileDetails": true, "maxConcurrency": 5, "proxyConfiguration": {"useApifyProxy": true}}. Run via ApifyClient("YOUR_TOKEN").actor("parsebird/goodfirms-scraper").call(run_input=input). Output, one row per company: companyName, entityName, entityId, profileUrl, logoUrl, logoAlt, companyWebsite, companyWebsiteRaw, rating, reviewCount, shortDescription, hourlyRate, employees, founded, location, isVerified, whyChoose[], aiTools[], reviewHighlight{rating, snippet, reviewer, reviewerPosition, date}, streetAddress, city, region, postalCode, country, telephone, priceRange, searchUrl, scrapedAt; with profile details also tagline, about, foundedYear, email, socialLinks[], servicesOffered[], serviceFocus[{name, percent}], industryFocus[], clientFocus[], portfolioCount, notableClients[], portfolioItems[{title, industry, imageUrl}], locations[{isHeadquarters, country, address, phone}]. Pricing: pay per company. Get your API token at https://console.apify.com/account#/integrations. Full API spec: https://apify.com/parsebird/goodfirms-scraper/api
```

### What is GoodFirms Company Scraper?

GoodFirms Company Scraper is a **GoodFirms data extraction tool** that reads public [GoodFirms.co](https://www.goodfirms.co/) listings and company profiles and saves each company as one clean row. GoodFirms has no public API for its directory, so this scraper works as a **GoodFirms API alternative** for B2B lead generation and vendor research.

The easiest way to try it: keep the prefilled listing (`https://www.goodfirms.co/companies/web-development-agency`), click **Start**, and open the dataset. You get 20 web development companies with ratings, rates, addresses, phones, and focus areas.

No GoodFirms account is needed.

### What can GoodFirms Company Scraper do?

- 📋 **Scrape any listing** — categories, cities (`/companies/web-development-agency/new-york`), directories (`/directory/platform/app-development`), and sorted listings (`?sort_by=rating`). Pages are followed automatically.
- 🏢 **Scrape single profiles** — paste `goodfirms.co/company/...` links.
- 📍 **Full contact details** — street address, city, region, postal code, country, phone, website (without GoodFirms tracking tags), social links, and the contact email published on the profile.
- 🧩 **Focus breakdowns** — the percentage split of services, industries, and client sizes (small, medium, large business).
- 🗂️ **Portfolio and clients** — portfolio count, portfolio project titles and industries, and notable clients.
- ⭐ **Ratings and reviews** — rating, review count, and the highlighted review with reviewer name, position, and date.
- ⚡ **Listing-only mode** — turn off **Include profile details** to read 48 companies per request. In testing, 1,920 companies took about 2 minutes.

Because GoodFirms Company Scraper runs on the Apify platform, you also get:

- ⏰ [Scheduling](https://docs.apify.com/platform/schedules) to refresh lead lists regularly.
- 🔌 [API access](https://docs.apify.com/api/v2) and client libraries for Python and JavaScript.
- 🔗 [Integrations](https://apify.com/integrations) with Make, Zapier, Google Sheets, HubSpot via webhooks, Slack, and more.
- 📦 Export to JSON, CSV, Excel, XML, or HTML from the Storage tab or the API.

### What data can you extract from GoodFirms?

| Field | Description |
|-------|-------------|
| `companyName` / `entityId` / `profileUrl` | Company name, GoodFirms ID, and profile link |
| `logoUrl` / `logoAlt` | Company logo |
| `companyWebsite` | Company website without GoodFirms tracking tags (`companyWebsiteRaw` keeps the original link) |
| `rating` / `reviewCount` | GoodFirms rating and number of reviews |
| `hourlyRate` / `employees` / `founded` / `location` | e.g. `$25 - $49/hr`, `250 - 999`, `2000`, `Potomac, United States` |
| `streetAddress` / `city` / `region` / `postalCode` / `country` / `telephone` | Headquarters address and phone |
| `shortDescription` | Listing description |
| `reviewHighlight` | Highlighted review: rating, text, reviewer name and position, date |
| `isVerified` / `whyChoose` / `aiTools` | Verified badge, "Why choose" points, and AI tools listed on the card |
| `tagline` / `about` | Tagline and full company description (profile details) |
| `email` | Public contact email from the profile, when listed (profile details) |
| `socialLinks` | LinkedIn, Facebook, X, Instagram, and other profiles (profile details) |
| `servicesOffered` | All services the company lists (profile details) |
| `serviceFocus` / `industryFocus` / `clientFocus` | Percentage splits, e.g. `{"name": "Web Development", "percent": 12}` (profile details) |
| `portfolioCount` / `portfolioItems` / `notableClients` | Portfolio size, projects, and named clients (profile details) |
| `locations` | All offices with country, address, and phone (profile details) |

### How to scrape GoodFirms

1. Open [GoodFirms Company Scraper](https://apify.com/parsebird/goodfirms-scraper) and click **Try for free**.
2. On [goodfirms.co](https://www.goodfirms.co/), open a category, city, or directory, apply any sorting, and copy the URL from the address bar.
3. Paste it into **GoodFirms URLs**. Add more listings or company profile links if you like.
4. Set **Max companies** and choose whether to **Include profile details**.
5. Click **Start** and download the results as JSON, CSV, or Excel, or read them through the API.

### Input parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `searchUrls` | array | **Yes** | — | GoodFirms listing or profile URLs (`searchUrl` with a single URL is also accepted) |
| `maxItems` | integer | No | `0` | Total companies; `0` = no limit |
| `maxPages` | integer | No | `0` | Listing pages per URL (48 companies each); `0` = all |
| `includeProfileDetails` | boolean | No | `true` | Open each profile for focus, portfolio, contacts, and locations |
| `maxConcurrency` | integer | No | `5` | Profiles loaded in parallel (1-10) |
| `proxyConfiguration` | object | No | Apify Proxy | Proxy settings; the default is recommended |

**Example: one category**

```json
{
  "searchUrls": ["https://www.goodfirms.co/companies/web-development-agency"],
  "maxItems": 100
}
```

**Example: top-rated agencies in a city plus single profiles**

```json
{
  "searchUrls": [
    "https://www.goodfirms.co/companies/web-development-agency/new-york?sort_by=rating",
    "https://www.goodfirms.co/company/sdlc-corp"
  ],
  "maxPages": 2
}
```

**Example: fast listing-only export of a directory**

```json
{
  "searchUrls": ["https://www.goodfirms.co/directory/languages/top-software-development-companies"],
  "includeProfileDetails": false,
  "maxPages": 40
}
```

### Output example

One company with profile details (long lists shortened):

```json
{
  "companyName": "Instinctools",
  "entityName": "Instinctools",
  "entityId": "579",
  "profileUrl": "https://www.goodfirms.co/company/instinctools",
  "logoUrl": "https://assets.goodfirms.co/services/medium/instinctools.png?v=1790574638",
  "logoAlt": "Instinctools",
  "companyWebsite": "https://www.instinctools.com/",
  "companyWebsiteRaw": "https://www.instinctools.com/?utm_source=goodfirms.co&utm_medium=referral&utm_campaign=profile",
  "rating": 4.9,
  "reviewCount": 27,
  "shortDescription": "Instinctools is a leading web development agency with more than 25 years of experience delivering secure, scalable, and user-focused digital solutions…",
  "hourlyRate": "$25 - $49/hr",
  "employees": "250 - 999",
  "founded": "2000",
  "location": "Potomac, United States",
  "isVerified": false,
  "whyChoose": [
    "Trusted engineering partner for AI-driven growth",
    "Technology solutions built for scalable growth",
    "Transparent and flexible engagement approach"
  ],
  "aiTools": [],
  "reviewHighlight": {
    "rating": 5,
    "snippet": "The team delivers on time and within budget, proactively asking how to help the client and providing new ideas.",
    "reviewer": "Sample Reviewer",
    "reviewerPosition": "Head of Engineering",
    "date": "2023-10-25"
  },
  "streetAddress": "12430 Park Potomac Ave",
  "city": "Potomac",
  "region": "Maryland",
  "postalCode": "20854",
  "country": "US",
  "telephone": "+12028214280",
  "priceRange": "$25 - $49",
  "tagline": "Your AI-powered Engineering Partner",
  "about": "Meet Instinctools - a global AI-powered software engineering company with over 25 years of experience.…",
  "email": "contact@instinctools.com",
  "socialLinks": [
    "https://www.linkedin.com/company/instinctools",
    "https://www.facebook.com/instinctoolslabs",
    "https://twitter.com/instinctools_EE"
  ],
  "servicesOffered": ["Mobile App Development", "Web Development", "Software Development"],
  "serviceFocus": [
    { "name": "Mobile App Development", "percent": 10 },
    { "name": "Web Development", "percent": 10 },
    { "name": "Software Development", "percent": 10 }
  ],
  "industryFocus": [
    { "name": "Advertising & Marketing", "percent": 20 },
    { "name": "Neobank", "percent": 15 },
    { "name": "Education", "percent": 10 }
  ],
  "clientFocus": [
    { "name": "Small Business", "percent": 35 },
    { "name": "Medium Business", "percent": 45 },
    { "name": "Large Business", "percent": 20 }
  ],
  "portfolioCount": 68,
  "notableClients": ["Swiss Red Cross", "Daimler", "Fujitsu"],
  "portfolioItems": [
    {
      "title": "Dark Store Management Platform for a Grocery Retailer",
      "industry": "eCommerce",
      "imageUrl": "https://assets.goodfirms.co/579/thumb/1787649928_240px-160px-dark-store-management-platform-for-a-grocery-ret.png"
    }
  ],
  "locations": [
    { "isHeadquarters": true, "country": "United States", "address": "12430 Park Potomac Ave, Potomac, Maryland 20854", "phone": "+12028214280" },
    { "isHeadquarters": false, "country": "Germany", "address": "89 Hauptstaetter Str., Stuttgart, Baden-Wurttemberg BW 70178", "phone": "+4971166483690" }
  ],
  "searchUrl": "https://www.goodfirms.co/companies/web-development-agency",
  "scrapedAt": "2026-10-04T13:20:11.204Z"
}
```

This is a real result (lists shortened, reviewer's name replaced). You can download the dataset in JSON, CSV, Excel, XML, or HTML.

### Use cases

- **B2B lead generation** — build lists of agencies by service, city, size, and hourly rate, with phone, address, and contact email.
- **Vendor shortlisting** — compare rates, team sizes, ratings, and service focus before sending a request for proposal.
- **Competitor research** — see how competing agencies split their services and industries, and which clients they name.
- **Market mapping** — export a whole category or city to measure how many providers serve a niche and where they are.
- **Partnership and outreach** — find agencies with a specific focus (for example 50%+ AI) to partner with or sell to.

### How it works

1. GoodFirms Company Scraper opens each listing URL and reads the 48 company cards on each page, along with the structured data GoodFirms publishes for them (address, phone, highlighted review).
2. It follows the pages (`?page=2`, `?page=3`, …) until the listing ends or your limits are reached. Companies on several listings are saved once.
3. With **Include profile details**, it opens each company's GoodFirms profile, a few at a time, and adds the focus, portfolio, contact, and location data.
4. GoodFirms refuses many requests from cloud servers, so Apify Proxy is on by default, and refused requests are retried on a fresh IP.

### How much does it cost to scrape GoodFirms?

GoodFirms Company Scraper uses pay-per-event pricing. You pay per company saved, with or without profile details. There's no extra charge for compute or proxies.

| Event | Free plan | Bronze | Silver | Gold |
|-------|-----------|--------|--------|------|
| `company` — per company saved | $0.00299 | $0.00259 | $0.00229 | $0.00199 |
| Per 1,000 companies | **$2.99** | **$2.59** | **$2.29** | **$1.99** |

For example, 100 companies cost $0.30 on the Free plan and 1,000 companies cost $2.99. Use **Max companies** or a [spending limit](https://docs.apify.com/platform/actors/running/usage-and-resources) to cap a run. Apify's Free plan includes monthly platform credits you can use to try the scraper.

### Use GoodFirms Company Scraper with the API

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("parsebird/goodfirms-scraper").call(run_input={
    "searchUrls": ["https://www.goodfirms.co/companies/web-development-agency/new-york"],
    "maxItems": 100,
})
for c in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(c["companyName"], c["hourlyRate"], c["telephone"], c.get("email"))
```

**JavaScript**

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('parsebird/goodfirms-scraper').call({
    searchUrls: ['https://www.goodfirms.co/directory/platform/app-development'],
    maxItems: 200,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const aiHeavy = items.filter((c) => (c.serviceFocus ?? []).some((s) => s.name === 'Artificial Intelligence' && s.percent >= 20));
console.log(`${aiHeavy.length} of ${items.length} companies spend 20%+ on AI`);
```

See the [API tab](https://apify.com/parsebird/goodfirms-scraper/api) for all endpoints and the [Apify API client docs](https://docs.apify.com/api/client/python) for more options.

### Is it legal to scrape GoodFirms?

GoodFirms Company Scraper only reads pages that GoodFirms shows publicly to logged-out visitors. Company profiles are business information, but reviews and contact emails can include people's names and personal addresses. Make sure your use complies with data protection laws such as GDPR and CAN-SPAM, GoodFirms' terms, and other rules that apply to you, and consult a lawyer if in doubt. Read more in Apify's post [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

### Other B2B directory scrapers

- [Clutch.co Scraper - Companies, Reviews & Buyer Leads](https://apify.com/parsebird/clutch-scraper) — agencies from Clutch.co with reviews, buyer leads, and contact emails.
- [Clutch.co Reviews Scraper](https://apify.com/parsebird/clutch-reviews-scraper) — every review of chosen Clutch profiles.
- [Website Email, Phone Numbers & Social Media Profiles Finder](https://apify.com/parsebird/website-contact-finder) — contacts from any list of websites.
- [LinkedIn Company Scraper (Bulk)](https://apify.com/parsebird/linkedin-company-scraper) — company pages with size, industry, and followers.
- [Capterra Review Scraper](https://apify.com/parsebird/capterra-review-scraper) — software reviews from Capterra.

### FAQ

**Do I need a GoodFirms account?**
No. GoodFirms Company Scraper reads public pages without logging in.

**Which URLs can I use?**
Any GoodFirms page that lists companies: categories (`/companies/web-development-agency`), cities (`/companies/web-development-agency/new-york`), directories (`/directory/platform/app-development`), and sorted versions of these (`?sort_by=rating`), plus company profiles (`/company/...`). Some older category URLs, such as `/companies/software-development-company`, no longer exist on GoodFirms (they return "not found"). Open the category on goodfirms.co and copy its current URL.

**What does "Include profile details" change?**
It adds the tagline, full description, focus percentages, portfolio, clients, all offices, social links, and contact email from each company's profile. It takes one more request per company. The price is the same either way. Turn it off when you only need the listing fields and want the fastest run.

**How often is a contact email included?**
Only when the company publishes one on its GoodFirms profile. In a 200-company test, 181 profiles listed an email.

**How many companies does a listing have?**
It varies. The web development category had 847 pages of 48 companies when tested, while a city listing like New York had 18 pages.

**Do I need a proxy?**
Keep the default Apify Proxy. GoodFirms refuses many requests from cloud servers without one. If you turn it off and requests are refused repeatedly, the scraper switches to Apify Proxy by itself.

**Something isn't working. Where do I report it?**
Open an issue on the [Issues tab](https://apify.com/parsebird/goodfirms-scraper/issues) with your run ID.

# Changelog

This Actor's version history is a separate document: https://apify.com/parsebird/goodfirms-scraper/changelog.md

# Actor input Schema

## `searchUrls` (type: `array`):

Category, location, directory or sorted listing URLs copied from your browser (e.g. https://www.goodfirms.co/companies/web-development-agency/new-york), or company profiles (https://www.goodfirms.co/company/...). Listings are paged automatically; a URL with ?page=N starts from that page.

## `maxItems` (type: `integer`):

Total companies to save across all URLs. 0 = no limit.

## `maxPages` (type: `integer`):

Listing pages to read per URL (48 companies per page). 0 = all pages.

## `includeProfileDetails` (type: `boolean`):

Open each company's GoodFirms profile to add the tagline, full description, service, industry and client focus percentages, portfolio count and items, notable clients, services offered, office locations, social links, and public contact email when listed. Turn off for faster runs with listing data only. Same price either way.

## `maxConcurrency` (type: `integer`):

Company profiles loaded in parallel (1-10).

## `proxyConfiguration` (type: `object`):

GoodFirms refuses many requests from cloud servers, so Apify Proxy (datacenter) is on by default. If you turn it off and GoodFirms refuses requests repeatedly, the Actor switches to Apify Proxy by itself.

## Actor input object example

```json
{
  "searchUrls": [
    "https://www.goodfirms.co/companies/web-development-agency"
  ],
  "maxItems": 20,
  "maxPages": 0,
  "includeProfileDetails": true,
  "maxConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchUrls": [
        "https://www.goodfirms.co/companies/web-development-agency"
    ],
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("parsebird/goodfirms-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchUrls": ["https://www.goodfirms.co/companies/web-development-agency"],
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("parsebird/goodfirms-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchUrls": [
    "https://www.goodfirms.co/companies/web-development-agency"
  ],
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call parsebird/goodfirms-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,parsebird/goodfirms-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/qdH8zXi7E0H1XGlAh/builds/s7cpgjOcofvyWcoHE/openapi.json
