# Clutch.co Agency Directory Scraper — B2B Leads & Company Data (`dc83/clutch-b2b-intelligence`) Actor

Turn the Clutch.co agency directory into B2B leads for lead generation: 19 always-present company data fields, public client reviews, the agency's real website, and an optional AI ICP-fit score. $2.50/1,000, 98.1% complete. Never charged for an empty or blocked result. JSON/CSV, API, schedule.

- **URL**: https://apify.com/dc83/clutch-b2b-intelligence.md
- **Developed by:** [Vitalii Kurovskyi](https://apify.com/dc83) (community)
- **Categories:** Lead generation, AI
- **Stats:** 2 total users, 1 monthly users, 81.8% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 agency profile scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### What is Clutch.co Scraper?

**Clutch.co Scraper** turns the **Clutch.co agency directory** — any category, search, or
profile URL on it — into **B2B leads** you can work: clean, guaranteed-complete **company data**
with each agency's public client reviews, its real website, and an optional **AI ICP-fit score**
that tells you which agencies to act on first.

![How Clutch.co Scraper works: paste a Clutch listing URL, get complete agency records with reviews, add an optional AI ICP-fit score, export to JSON, CSV, Google Sheets or the API](https://raw.githubusercontent.com/dc83-lab/apify-actor-assets/main/clutch-b2b-intelligence/01-how-it-works.png)

- **Feed it a listing, not a URL list** — hand it a Clutch category or search page and it
  expands the listing into full profiles, pagination included. No need to already own the URLs.
- **Get a schema with no holes** — every field is always present. Missing data becomes a typed
  default (empty string, `null`, empty array), never a dropped key or a half-filled record.
- **Get the agency's *real* website**, decoded from Clutch's outbound redirect and stripped of
  tracking parameters — the key you actually need for outreach.
- **Get the public reviews** — reviewer, role, project, rating, text, and an ISO date for every
  review Clutch renders on the profile.
- **Rank the list with AI** — an optional per-agency decision object: ICP fit, pain signals,
  risk flags, and the one outreach angle to lead with, every claim backed by a verbatim quote.
- **Never pay for nothing** — you are **never** charged for an empty, not-found, blocked, or
  failed result, on **either** paid event.
- **Export anywhere** — JSON, CSV, Excel, XML, HTML, RSS; Google Sheets, Airtable, Make,
  Zapier, webhooks; the Apify API; scheduled runs; and any AI agent via an MCP server.

Built for **lead generation**, agency shortlisting, competitive research, and market mapping —
anywhere you need structured company data out of a directory that only publishes it as pages.
The difference is **reliability and presentation, not raw volume**: a complete schema, fair
billing, and an AI layer that ranks who to contact instead of dumping rows.

***

### What data can this scraper extract?

Every agency record always contains **every** field below. When a value is genuinely absent on
the source you get its typed default — never a dropped key.

Every emitted dataset row carries a `type` discriminator. Agency records are
`type: "agency_profile"`; the optional AI artifact is a **separate** `type: "agency_intelligence"`
row. Filter on `type` to split the two.

| Field | Type | Description | Default when absent |
|---|---|---|---|
| `type` | string | Row discriminator — always `"agency_profile"` for an agency record | `"agency_profile"` |
| `name` | string | Agency name | `""` |
| `tagline` | string | Short positioning line | `""` |
| `locations` | array | `{ city, region, country, line }` per office | `[]` |
| `size` | string | Employee band, e.g. `"50 - 249"` | `""` |
| `hourlyRate` | string | e.g. `"$100 - $149 / hr"` | `""` |
| `minProjectBudget` | string | e.g. `"$10,000+"` | `""` |
| `services` | array | Service-line strings | `[]` |
| `industries` | array | Industry strings | `[]` |
| `resolvedWebsite` | string | The agency's **real** site (redirect decoded, tracking params stripped) | `""` |
| `companyEmail` | string | Public work email — **see the note below: Clutch does not publish these** | `""` |
| `companyPhone` | string | Public phone | `""` |
| `socialLinks` | array | LinkedIn / X / Facebook profile URLs | `[]` |
| `rating` | number | null | Aggregate rating in `[0, 5]` | `null` |
| `reviewCount` | integer | Reviews the agency has on Clutch **in total** | `0` |
| `reviewsIncluded` | integer | Reviews actually present in `reviews` on this row (see below) | `0` |
| `sourceUrl` | string | The Clutch profile URL this record came from | `""` |
| `scrapedAt` | string | ISO-8601 UTC timestamp of when this row was scraped | `""` |
| `reviews` | array | Public reviews (see below), when `includeReviews` is on | `[]` |

> **`companyEmail` is almost always `""`, and that is the source, not the scraper.** Clutch does
> not render a public email on its agency profiles — it routes contact through its own form. The
> field stays in the schema so the record shape never changes, but do not plan a workflow around
> it. For outreach, use `resolvedWebsite` (the agency's real domain, redirect-decoded) as the key.

> **`reviewCount` and `reviewsIncluded` are different numbers on purpose.** `reviewCount` is the
> agency's lifetime total as Clutch reports it; `reviewsIncluded` is how many this run returned —
> the reviews Clutch renders on the profile page itself, which for a heavily-reviewed agency is
> the most recent page of them, not all several hundred. Compare the two before you treat a
> record's `reviews` array as complete.

Each **review** is likewise guaranteed-complete:

| Field | Type | Description | Default when absent |
|---|---|---|---|
| `reviewer` | string | Reviewer name | `""` |
| `role` | string | Reviewer role & company | `""` |
| `project` | string | Project title | `""` |
| `rating` | number | null | Review rating in `[0, 5]` | `null` |
| `reviewRating` | number | null | The same value under a name that cannot collide with the agency's own `rating` — this is what the **Reviews** table view shows | `null` |
| `text` | string | Public review text | `""` |
| `date` | string | Review date, normalized to ISO `YYYY-MM-DD` | `""` |
| `sourceUrl` | string | The profile URL the review came from | `""` |

The run's Output tab has a third table view, **Reviews**, which expands every review out of its
agency record into one row per review — the same data you already paid for, reshaped for export.

***

### How much does Clutch.co Scraper cost?

This actor is **pay-per-event**: you pay for results, not for run time.

| Event | Price | Charged when |
|---|---|---|
| `agency_profile` | **$0.0025** / agency — **$2.50 per 1,000** | A complete agency record is stored |
| `agency_intelligence` | **$0.035** / agency | A valid, grounded AI artifact is produced (opt-in) |

**Residential proxy and compute are included.** They are paid out of our side, never added to
your bill — the price above is the price.

On the [Apify Free plan](https://apify.com/pricing) you get **$5 of credit every month**, which
scrapes **2,000 agency profiles** here without costing you anything.

**The fair-billing promise:** you are **never** charged for an empty, not-found, blocked, or
failed result — for either event. A profile that comes back empty is free. An AI artifact the
model can't ground is free. Charges happen strictly *after* a real result is stored.

`agencyIntelligence` is **off by default** — you only ever incur the premium event when you
explicitly turn it on.

**Why pay-per-event:** you pay for stored results rather than for elapsed time, so a slow page,
a retry, a block, or a proxy rotation costs you nothing. The bill matches the rows you got.

> **Keep `includeReviews` on when you use `agencyIntelligence`.** Every claim in the artifact
> must be grounded in a verbatim quote from something the actor actually scraped, and the review
> text is where nearly all of that evidence lives. With reviews switched off there is little for
> the model to ground in, so most agencies produce **no artifact at all** — free, under the
> fair-billing promise, but also empty. The actor logs a warning if you run this combination.

***

### How do I use Clutch.co Scraper?

No scraping experience needed. Five steps:

1. **Find your listing on Clutch.** Open [clutch.co](https://clutch.co), narrow to the agencies
   you want (service line, location, size — e.g.
   `https://clutch.co/agencies/digital-marketing?geo=us`) and copy the URL from the address bar.
2. **Click *Try for free*** on this page and paste that URL into
   **Category or search URLs**. To scrape agencies you already have, paste their profile links
   into **Profile URLs** instead — you can use both fields together.
3. **Set your limit and your contact email.** `maxAgencies` caps how many profiles the run
   fetches, so it also caps what you spend. It ships at **5** deliberately — a first run should
   cost about a cent and finish in a minute or two; raise it to whatever your real harvest needs,
   there is no upper limit. `contactEmail` goes into the scraper's `User-Agent`
   so Clutch can identify and reach the operator; it ships with a placeholder so the actor runs
   out of the box, and replacing it with your own address is strongly recommended.
4. **Optional: turn on the AI layer.** Switch on **Agency intelligence** and write an
   **ICP description** — the buyer you are. Every agency then comes back scored and ranked
   against it. Leave `icpDescription` empty and `icpFit` returns `null` rather than a guess.
5. **Click *Start* and export.** When the run finishes, open the **Storage → Dataset** tab and
   download JSON, CSV, or Excel, or push it straight to Google Sheets, Airtable, Make, or Zapier.

![The Clutch.co Scraper input form in the Apify Console, filled in for a real run: a digital-marketing category URL, a 100-agency cap, public reviews on, the AI agency-intelligence event switched on, and an ideal-customer-profile description — annotated field by field, with the run priced at $0.25 plus $0.035 per agency scored](https://raw.githubusercontent.com/dc83-lab/apify-actor-assets/main/clutch-b2b-intelligence/02-input-form.png)

***

### ⬇️ Input

**1. Expand a whole category into full profiles**

```json
{
  "categoryOrSearchUrls": ["https://clutch.co/agencies/digital-marketing"],
  "maxAgencies": 100,
  "includeReviews": true,
  "contactEmail": "you@example.com"
}
```

**2. Scrape specific agencies you already have, with reviews off**

```json
{
  "profileUrls": [
    "https://clutch.co/profile/acme-digital",
    "https://clutch.co/profile/example-studio"
  ],
  "includeReviews": false,
  "contactEmail": "you@example.com"
}
```

**3. Category expansion + the AI agency-intelligence artifact**

```json
{
  "categoryOrSearchUrls": ["https://clutch.co/agencies/software-developers?geo=us"],
  "maxAgencies": 50,
  "includeReviews": true,
  "agencyIntelligence": true,
  "icpDescription": "Series B SaaS, 50-200 staff, US/EU. Need a partner for paid media and analytics instrumentation. Budget $10-25k/mo.",
  "contactEmail": "you@example.com",
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}
```

Every input field is documented on the **Input** tab of this actor.

> `contactEmail` is sent in the scraper's `User-Agent` so the target site can identify and reach
> the operator — this actor is a polite, identifiable client. It ships with a placeholder default
> so the actor runs out of the box; **replace it with your own address** before running at volume.

> `icpDescription` is optional and only used by the AI event. Describe the buyer you are —
> industry, size, region, budget, the work you need — and every agency gets scored against it.
> Leave it out and `icpFit` comes back `null` rather than guessed; the rest of the artifact
> (pain signals, risk flags, outreach angle, evidence) works exactly the same.

> **Writing a good ICP** (the sharper your ICP, the more useful `icpFit` and the outreach angle).
> Name five things: **industry / niche**, **company size**, **region**, **budget or deal size**,
> and **the work you need done**. A ready-to-edit template:
>
> > *"\[Industry] company, \[N–M] employees, based in \[region]. Looking for a partner to \[the work].
> > Budget around \[$X]. We care most about \[proof point — e.g. measurable ROI, a specific vertical]."*
>
> Vague ICPs ("any marketing agency") still work but score everyone middling; specifics are what
> turn the artifact from a summary into a ranked action list.

***

### ⬆️ Output

![Sample output rows: agency name, resolved website, company size, hourly rate, minimum project budget, rating, reviews included versus total, company email and the AI ICP-fit score](https://raw.githubusercontent.com/dc83-lab/apify-actor-assets/main/clutch-b2b-intelligence/03-output.png)

```json
{
  "type": "agency_profile",
  "name": "Acme Digital",
  "tagline": "Award-winning web & mobile development for growth-stage SaaS.",
  "locations": [
    { "city": "San Francisco", "region": "CA", "country": "USA", "line": "San Francisco, CA, USA" },
    { "city": "Austin", "region": "TX", "country": "USA", "line": "Austin, TX, USA" }
  ],
  "size": "50 - 249",
  "hourlyRate": "$100 - $149 / hr",
  "minProjectBudget": "$10,000+",
  "services": ["Web Development", "Mobile App Development", "UX/UI Design"],
  "industries": ["Financial Services", "Healthcare", "E-commerce"],
  "resolvedWebsite": "https://acmedigital.com",
  "companyEmail": "",
  "companyPhone": "+1-415-555-0100",
  "socialLinks": [
    "https://www.linkedin.com/company/acme-digital",
    "https://twitter.com/acmedigital"
  ],
  "rating": 4.8,
  "reviewCount": 27,
  "reviewsIncluded": 5,
  "sourceUrl": "https://clutch.co/profile/acme-digital",
  "scrapedAt": "2026-07-19T08:14:52.117Z",
  "reviews": [
    {
      "reviewer": "Jane Cooper",
      "role": "VP Marketing, FinScale",
      "project": "SaaS marketing website rebuild",
      "rating": 5.0,
      "text": "Acme rebuilt our marketing site and scaled our paid media 3x in two quarters.",
      "date": "2025-11-02",
      "sourceUrl": "https://clutch.co/profile/acme-digital"
    }
  ]
}
```

*Illustrative example. Field names and shape are the exact contract the actor emits; the
`reviews` array is shown truncated to one of the five entries `reviewsIncluded` counts.*

***

### How does the AI ICP-fit score rank agencies?

Turn `agencyIntelligence` on and, for each agency, the actor produces a compact **decision
object** — not a review summary, but an answer to *"who do I act on first, and how?"*. This is
what makes it different from a plain Clutch.co data export:

| Field | Meaning |
|---|---|
| `icpFit` | How well the agency fits your ideal-customer profile (`0`–`1`) |
| `painSignals` | Buyer-relevant pain / opportunity signals found in the profile & reviews |
| `riskFlags` | Reasons to be cautious before acting |
| `outreachAngle` | The single concrete "lead with this" angle |
| `evidenceQuotes` | `{ quote, sourceUrl }` — the verbatim source text behind the claims above |
| `confidence` | The model's own confidence (`0`–`1`) |

![An AI ICP-fit artifact close up: the fit score, pain signals, risk flags and outreach angle for one agency, next to the verbatim evidence quotes and source URLs that back every claim](https://raw.githubusercontent.com/dc83-lab/apify-actor-assets/main/clutch-b2b-intelligence/04-ai-artifact.png)

Every artifact you are charged for carries **at least one evidence quote with its source URL**,
and every quote it carries is real. Grounding is enforced by the actor, not merely requested of
the model: a quote is kept only if its text appears **verbatim** (modulo case/punctuation) inside
a single field we actually scraped, **and** its `sourceUrl` is one of the pages we actually read.
Anything the model paraphrases, stitches together from two different fields, or hangs on an
invented link is dropped — and an artifact with no surviving quote is never emitted and never
charged.

The model is instructed to ground each pain signal, risk flag and the outreach angle in the
quotes it returns, but the actor enforces the **quotes** themselves, not a per-claim mapping: it
verifies that every quote is real, not that each individual signal is keyed to one. Treat
`evidenceQuotes` as the checkable audit trail for the artifact — every quote in it is text we
actually scraped, at the URL it names.

`sourceUrl` is the **agency profile URL** — Clutch renders no per-review permalink, so quotes
point at the profile the review lives on, not at the individual review.

If the model can't produce a valid grounded artifact (a `confidence` score, one actionable
signal, and at least one surviving evidence quote), **nothing is emitted and nothing is
charged**. `icpFit` is required too — but only when you supplied an ICP; leave `icpDescription`
empty and it comes back `null` rather than guessed.

The artifact is a **separate dataset row** with `type: "agency_intelligence"`, carrying
`sourceUrl` and `agencyName` so you can join it back to its `agency_profile` row:

```json
{
  "type": "agency_intelligence",
  "sourceUrl": "https://clutch.co/profile/acme-digital",
  "agencyName": "Acme Digital",
  "icpFit": 0.82,
  "painSignals": ["scaling paid media", "under-instrumented analytics"],
  "riskFlags": ["communication slows near deadlines"],
  "outreachAngle": "Lead with a paid-media + analytics audit tied to their SaaS growth reviews.",
  "evidenceQuotes": [
    { "quote": "scaled our paid media 3x in two quarters", "sourceUrl": "https://clutch.co/profile/acme-digital" }
  ],
  "confidence": 0.71
}
```

***

### How reliable is this Clutch.co scraper?

**98.1% of pages returned a complete record, and 0% of pages were lost to blocks** — measured,
not claimed. Numbers below come from live Clutch.co profiles across **15 unattended scheduled
runs, 2026-07-31 → 2026-08-04**: our own pre-release reliability gate, not estimates.

| Metric | Result |
|---|---|
| Proxy tier | Apify Proxy **residential**, US-pinned (the default) |
| Profiles tested | **215** across 15 unattended runs on 5 consecutive days |
| Success rate | **98.1%** (211 complete records; 4 transient blocks, **charged $0.00**) |
| Runs completed | **15 / 15** — no run failed, crashed, or needed a manual fix |
| Fields per record | **19** top-level, always present, plus 4-field location objects and 7-field review objects |
| Block rate | **0%** of pages lost. Clutch returned a 403 on 6 of the 15 runs; every one was recovered in-run by the block-aware backoff, and **no run lost data to a block** |
| Cost per 1,000 profiles | **$2.50 flat** — residential proxy and compute are included and are never billed to you |

*The 4 transient blocks are the honest part of this table: Clutch occasionally serves a page
that looks fine but contains nothing. The scraper detects it, skips the row, and — per the
fair-billing rule — charges you nothing for it.*

**How it stays reliable:** a declared contact `User-Agent`, token-bucket rate limiting, and a
block-aware retry ladder that backs off and rotates the exit IP instead of hammering the site.
Since v0.3.0 there is one more layer: when Clutch answers with a browser challenge instead of a
page, the scraper opens a real Chrome once per proxy session, passes the challenge, and hands the
resulting pass back to the fast HTTP path — so the challenge is solved once, not per page. If it
cannot be passed, the run reports the blockage honestly and **charges you nothing** for what it
could not deliver. The proxy defaults to **residential**, the tier our testing found clears
Clutch's anti-bot most consistently; datacenter is selectable but draws more blocks. Residential
is available on every Apify plan, Free included.

*Note on the table above: it was measured on v0.2.x, before the challenge solver existed.
Reliability under v0.3.0 is being re-measured; the browser step adds a few seconds and some memory
to the first request of each proxy session, and the per-run cost figures will be refreshed here
once the new measurement is complete.*

***

### What export formats and integrations are supported?

Results are stored in an Apify dataset and export **natively** to:

- **JSON, CSV, Excel (XLSX), XML, HTML table, RSS** — one-click download or API.
- **Google Sheets, Airtable, Make, Zapier, and Webhooks** — Apify-native for every run; plus
  this actor's own `webhookUrls` input to POST each result the moment it's produced.
- **API & scheduling** — pull the dataset over the Apify API, or schedule recurring runs.

***

### What can you use Clutch.co agency data for?

The directory is a buyer's shortlist and a seller's market map at the same time — which one it is
depends on which side of the table you sit on.

- **Lead generation for agency-services sellers.** Software, hosting, analytics, staffing and
  martech vendors sell *to* agencies. A category listing is a pre-qualified buyer list with size,
  budget band, service lines and a real website already attached.
- **Shortlisting an agency to hire.** Pull a whole category, sort by rating, size and minimum
  project budget, then read the reviews of the survivors — in a spreadsheet, in minutes, instead
  of opening 200 profiles by hand.
- **Competitive and market research.** Track how many agencies serve a niche, what they charge
  per hour, where they cluster geographically, and how their positioning changes over time by
  scheduling the same listing weekly.
- **Partner and reseller recruitment.** Filter by service line and location to find agencies whose
  offering complements yours rather than competes with it.
- **Enriching a CRM.** `resolvedWebsite` is the agency's real domain, so each record joins cleanly
  onto accounts you already have — no fuzzy name matching against a redirect URL.

***

### ❓ Frequently asked questions

#### Do I need to provide the profile URLs myself?

No. Give it a Clutch category or search URL and it expands the listing (with pagination) into
individual profiles. Direct profile URLs are also supported if you already have them.

#### Is there a Clutch.co API?

**Clutch.co publishes no public API** — the directory exists only as web pages, which is why
teams end up copying it by hand. This actor is the practical equivalent: it reads those public
pages and returns the same information as clean JSON, over the
[Apify API](https://docs.apify.com/api/v2), on a schedule if you want one. You get an API-shaped
interface to a site that never shipped one.

#### How many Clutch.co agencies can I scrape in one run?

There is **no fixed upper limit** — `maxAgencies` is capped only by your own budget, and because
billing is per stored result you always know what a number costs before you set it (the default 5
\= $0.0125, 25 = $0.0625, 1,000 = $2.50). Pagination follows up to **50 pages per listing URL** as a
runaway-pager safeguard; to go deeper, split the category into several narrower listing URLs and
pass them together.

One thing to know if you keep the run small: a run of **10 agencies or fewer** is treated as a
quick trial and winds down after 3 minutes, returning whatever it has rather than sitting on a
slow day. Any run larger than that has **no time limit at all** — it runs until your `maxAgencies`
is met. So if a tiny test run comes back short on a bad day, raise the number rather than retrying
the same small one.

#### Can I scrape Clutch.co agencies by city, country or service?

Yes — you do the filtering on Clutch itself and hand the result over. Narrow the directory with
Clutch's own filters (service line, location, company size, hourly rate), then copy the URL from
your address bar into **Category or search URLs**; e.g.
`https://clutch.co/agencies/digital-marketing?geo=us` scrapes US digital-marketing agencies only.
Whatever the listing shows is exactly what the run returns.

#### How much does it cost to scrape 1,000 Clutch.co agencies?

**$2.50** — $0.0025 per stored agency record, with residential proxy and compute included rather
than added to your bill. The AI ICP-fit score, if you switch it on, is $0.035 per agency scored.
The Apify Free plan's $5 monthly credit covers 2,000 agency profiles at no cost.

#### Will I be charged if an agency page is blocked or empty?

No. Both paid events are charged strictly *after* a real result is stored. Empty, not-found,
blocked, and failed results are free.

#### What does the AI agency-intelligence event cost, and when?

$0.035 per agency, and only when a valid, grounded artifact is produced. If the model can't
ground its output, nothing is emitted and nothing is charged.

#### How do I export Clutch.co data to CSV, Excel or Google Sheets?

Open the finished run's **Storage → Dataset** tab and download **CSV, Excel (XLSX), JSON, XML,
HTML or RSS** in one click — no code. For a standing pipeline, use the run's **Integrations** tab
to push every run straight into **Google Sheets**, Airtable, Slack, Make or Zapier, or pull the
dataset over the API in the format you name.

#### Can I use integrations with Clutch.co Scraper?

Yes. Every run can push straight to Google Sheets, Airtable, Slack, Make, Zapier, or any HTTP
endpoint via webhooks — set up on the run's **Integrations** tab, no code required. This actor
additionally accepts a `webhookUrls` input to POST each result the moment it is produced.

#### Can I use Clutch.co Scraper with the Apify API?

Yes. Start runs, poll status, and pull the dataset over the [Apify API](https://docs.apify.com/api/v2),
with official [Python and Node.js clients](https://docs.apify.com/api). Runs can also be
scheduled to repeat on a cron, so a shortlist refreshes itself.

#### Can I use Clutch.co Scraper through an MCP server?

Yes. Apify exposes its Store through the [Apify MCP server](https://docs.apify.com/integrations/mcp), so an AI
agent — Claude, ChatGPT, Cursor, or your own — can call this actor as a tool and get the ranked
agency data back directly. The AI ICP-fit artifact is designed for exactly that: it returns a
decision object, not prose an agent has to re-parse.

#### Do I have to set a contact email?

Not to get started — `contactEmail` ships with a placeholder default, so the actor runs out of
the box. It is sent in the scraper's `User-Agent` so the target site can identify and contact the
operator, so **replacing it with your own address is strongly recommended**: being an
identifiable, polite client is part of how this actor stays reliable.

#### Which proxy should I use?

The default is **Apify Proxy residential** — our reliability testing found it stays ahead of
Clutch's anti-bot where datacenter draws far more blocks (blocked pages are skipped and never
charged, so blocks just show up as fewer rows). Residential is available on every Apify plan,
Free included. You can switch to datacenter in `proxyConfiguration` if you prefer, but expect
more blocks on Clutch.

#### Is it legal to scrape Clutch.co?

This actor reads **only publicly available pages** — no logins, no gated or closed data — and
scraping public web data is broadly lawful in the EU and the US. What you then *do* with the
data is where the obligations sit: you are responsible for complying with Clutch.co's terms,
applicable data-protection law (GDPR/CCPA), and anti-spam rules. Use work contact data for
legitimate B2B outreach only. If you have a specific case in doubt, take legal advice.

#### Does it collect private or logged-in data?

No. It reads only publicly rendered content — no logins, no gated or closed data.

#### I passed 10 URLs but got fewer rows. Where did they go?

This actor scrapes **only clutch.co**, so any input URL on another host is dropped before it is
fetched — as is anything in `profileUrls` that is not a `https://clutch.co/profile/<slug>` link
(a category URL in that field, or a typo). Each drop is named in the run log with the reason.
Duplicates collapse too: `clutch.co/profile/acme`, `www.clutch.co/profile/acme` and
`…/profile/acme?utm=x` are one agency, fetched once and charged once. Dropped URLs are free.

#### Your feedback

We are constantly improving this scraper. If you hit a bug, want a field that isn't there, or
have an idea for a new feature, **[open an issue on the Issues tab](https://apify.com/dc83/clutch-b2b-intelligence/issues)**
— it goes straight to the developer, and you will get a reply there. And if the actor did the job,
**please leave a rating**; it is the single most useful thing you can do for it.

***

### Troubleshooting

- **Empty dataset / very few results** — check that your category/search URL is a valid public
  Clutch listing, raise `maxAgencies`, and confirm proxy is enabled. Blocked pages are skipped
  (and never charged), so a high block rate shows up as fewer rows plus a note in the run log.
- **A big listing stopped short of `maxAgencies`** — pagination follows at most **50 pages per
  listing URL** as a runaway-pager safeguard. To go deeper, split the category across several
  narrower listing URLs (by city, size, or service) and pass them together.
- **A small trial run came back with fewer rows than you asked for** — runs of **10 agencies or
  fewer** wind down after 3 minutes and return what they have, so a quick test never sits there on
  a slow day. The run log says so, and you are charged only for the rows you actually got. Runs
  above 10 have no time limit; raise `maxAgencies` and the cap disappears.
- **Run stopped charging mid-run** — by design. If the block rate crosses a safe threshold the
  actor stops charging and cleanly degrades rather than bill for degraded output; the run log
  records it. Retry with a different proxy tier.
- **Run ended before `maxAgencies`, and the log says the charge limit was reached** — the run hit
  the **maximum charge** you set on it, so nothing further could be billed and the actor stopped
  instead of scraping data you'd never be charged for. Everything already in your dataset is
  yours. Raise the run's max charge (or lower `maxAgencies`) and run again.
- **Missing fields on some records** — those fields simply aren't public on that profile; you
  still get a complete record with typed defaults, never a broken one.
- **No AI artifacts despite enabling the toggle** — the model didn't return grounded, valid
  output for those agencies (so you weren't charged). Rerun, or check the source profiles have
  enough public review content to ground a decision.
- **Webhook not firing** — webhook POSTs are best-effort and non-fatal; a failing endpoint is
  logged but never stops the run.

***

### Legal & responsible use

This actor collects **only publicly available data** from Clutch.co — no logins, no gated or
closed data. It is a polite, identifiable client (declared contact `User-Agent`, rate limiting,
retry/backoff).

You are responsible for how you use the extracted data, including any contact information, in
compliance with Clutch.co's terms, applicable data-protection law (e.g. GDPR/CCPA), and
anti-spam rules. Use work contact data for legitimate B2B outreach only.

***

### Changelog

This actor is actively maintained and every release is public — see the
**[full changelog](https://apify.com/dc83/clutch-b2b-intelligence/changelog)** for the complete
history, including what was measured and why each change was made.

| Date | What changed for you |
|---|---|
| 2026-08-08 | Clutch started answering with a browser challenge instead of a page, which no plain HTTP scraper can pass. The actor now opens a real browser once per proxy session, passes the challenge, and keeps scraping over the fast HTTP path with the pass it earned — so the slow step happens once, not per page. If the challenge cannot be passed, the run says so and charges you nothing. |
| 2026-08-08 | The automatic proxy-tier fallback now works on any Apify account, not just ours — it previously named a proxy group that most accounts do not have, so it could never actually fire. |
| 2026-08-06 | A first run is now 5 agencies (about a cent) instead of 25, so trying the actor costs nothing worth thinking about — and small trial runs now wind down after 3 minutes instead of sitting on a slow day. Real harvests are unaffected: above 10 agencies there is no time limit. |
| 2026-08-05 | Reviews get their own table view — one row per review, ready for a spreadsheet or sentiment analysis. Plus nine reliability and data-quality fixes from an external code review. |
| 2026-08-05 | A hard ceiling on retry patience per page, so one stubborn profile can no longer eat the run's time budget and starve the agencies queued behind it. |
| 2026-07-30 | Block-aware backoff — when the site throttles the scraper it waits and rotates the exit IP instead of giving up. Proven live: it triggered 6 times during the reliability probe and delivered all 6 times. |
| 2026-07-28 | Every skipped profile now states *why* it was skipped in the run report, instead of disappearing silently. |
| 2026-07-24 | Sticky US-pinned residential exit IPs and an automatic proxy-tier fallback. A fully blocked run now **fails loudly** instead of reporting a false success on an empty dataset. |
| 2026-07-19 | `scrapedAt` on every agency row, so you can tell fresh data from stale, and an accurate `reviewsIncluded` count next to the site-wide review total. |
| 2026-07-15 | Initial release: category/search + direct-URL input, guaranteed-complete agency schema, public reviews, optional AI agency-intelligence artifact, fair per-event billing, webhooks. |

# Actor input Schema

## `categoryOrSearchUrls` (type: `array`):

Clutch.co category or search listing URLs. Each is expanded (with pagination) into individual agency profile URLs. Use a specific category (e.g. https://clutch.co/agencies/digital-marketing) rather than the bare /agencies index — a category paginates into hundreds of profiles, while the index page surfaces only a short curated set and does not page.

## `profileUrls` (type: `array`):

Optional direct Clutch.co agency profile URLs to scrape in addition to (or instead of) the listing URLs.

## `maxAgencies` (type: `integer`):

Maximum number of agency profiles to scrape in a single run. The default of 5 is a deliberately tiny smoke-test run (seconds, $0.0125) so a first try costs almost nothing — raise it for a real harvest; there is no upper cap beyond your own run budget.

## `includeReviews` (type: `boolean`):

Scrape the publicly rendered review blocks for each agency. No logins, no closed data.

## `agencyIntelligence` (type: `boolean`):

Enable the premium AI scoring artifact ('who to act on first'). Billed as a separate paid event ONLY when a valid artifact is produced — never on an empty result. Off by default. Requires 'Include reviews': the artifact grounds every evidence quote in the scraped review text, so with reviews off most agencies yield no artifact (and are not charged).

## `icpDescription` (type: `string`):

Describe the buyer you are looking for — industry, company size, budget, region, the work you need done. Used ONLY by the AI agency-intelligence event to score 'icpFit'. Leave empty and icpFit is returned as null rather than guessed; the rest of the artifact still works.

## `contactEmail` (type: `string`):

Please put a real address here. It is sent in the scraper's User-Agent so the target site can reach whoever is running the scrape — this actor is a polite, identifiable client, and that is part of how it stays welcome. Left as the placeholder, the run still works, but nobody can be reached.

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

Proxy settings. Defaults to Apify Proxy RESIDENTIAL pinned to the US: our reliability testing found residential stays ahead of Clutch's anti-bot, while datacenter draws far more blocks (fewer results, no charge for the blocked ones), and Clutch is US-centric — non-US exit IPs get blocked site-wide, so the country is pinned to US. RESIDENTIAL is available on every Apify plan, including Free. You can change the tier or country here if you prefer.

## `webhookUrls` (type: `array`):

Optional URLs to POST each scraped result to as it is produced (best-effort, non-fatal).

## Actor input object example

```json
{
  "categoryOrSearchUrls": [
    "https://clutch.co/agencies/digital-marketing"
  ],
  "profileUrls": [],
  "maxAgencies": 10,
  "includeReviews": true,
  "agencyIntelligence": false,
  "contactEmail": "you@example.com",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  },
  "webhookUrls": []
}
```

# Actor output Schema

## `agencies` (type: `string`):

One record per agency: 19 always-present fields, the resolved real website, and the full public reviews when `includeReviews` is on. Rows from the optional AI agency-intelligence event land in the same dataset as `type: agency_intelligence`. Two ready-made table views split them — Agencies and AI ICP fit.

## `runReport` (type: `string`):

The receipt for the run: agencies delivered, empty results, block rate, and the charged event counts side by side with the emitted ones. This is how you verify the pricing promise yourself — an empty, blocked or failed result is never charged.

# 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 = {
    "categoryOrSearchUrls": [
        "https://clutch.co/agencies/digital-marketing"
    ],
    "maxAgencies": 10,
    "contactEmail": "you@example.com",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("dc83/clutch-b2b-intelligence").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 = {
    "categoryOrSearchUrls": ["https://clutch.co/agencies/digital-marketing"],
    "maxAgencies": 10,
    "contactEmail": "you@example.com",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("dc83/clutch-b2b-intelligence").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 '{
  "categoryOrSearchUrls": [
    "https://clutch.co/agencies/digital-marketing"
  ],
  "maxAgencies": 10,
  "contactEmail": "you@example.com",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call dc83/clutch-b2b-intelligence --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dc83/clutch-b2b-intelligence"
        }
    }
}

```

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/Wuye77Mx81gNgyvf2/builds/k6JObd7z5oR5LI9I0/openapi.json
