# Clutch Scraper (`juanoox/clutch-scraper`) Actor

Scrape B2B service providers from Clutch: agency name, rating, review count, hourly rate, minimum project size, team size, location, phone and service breakdown, with sponsored placements flagged.

- **URL**: https://apify.com/juanoox/clutch-scraper.md
- **Developed by:** [Juan ignacio Veltri](https://apify.com/juanoox) (community)
- **Categories:** Business, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

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/actors/running/actors-in-store.md#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

## Clutch Scraper — B2B agencies with rates, team size and sponsored placements flagged

Scrape service providers from any Clutch directory: agency name, rating, review count, **hourly
rate**, **minimum project size**, team size, city, phone, and the percentage breakdown of what each
agency actually does.

### The field nobody else returns

**Half the providers at the top of a Clutch page are paid placements.** Every row here carries
`isSponsored`, so you can tell a ranking from an advert. On the page used to build this Actor, 25 of
49 listings were sponsored.

Without that flag, a Clutch export reads like a merit ranking when the top of it is inventory.

***

### Quick start

```json
{ "startUrls": ["https://clutch.co/agencies/digital-marketing"] }
```

Only agencies that earned their spot:

```json
{
  "startUrls": ["https://clutch.co/agencies/digital-marketing"],
  "excludeSponsored": true,
  "minRating": "4.5",
  "minReviews": 25,
  "maxPagesPerListing": 10
}
```

Find specialists, not generalists — Clutch publishes each agency's split of expertise:

```json
{
  "startUrls": ["https://clutch.co/developers"],
  "serviceKeywords": ["Mobile App Development"],
  "minReviews": 10
}
```

Filter on Clutch first (by location, budget, service) and paste the resulting URL — the Actor
follows that exact list.

***

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `startUrls` | array | digital marketing agencies | Any Clutch directory listing |
| `maxPagesPerListing` | integer | `3` | ~49 providers per page |
| `minRating` | string | — | e.g. `4.5` |
| `minReviews` | integer | — | Past agencies with a single glowing review |
| `excludeSponsored` | boolean | `false` | Drop paid placements |
| `onlyWithPhone` | boolean | `false` | Drop providers with no phone |
| `locationKeywords` | array | — | Match against city or state |
| `serviceKeywords` | array | — | Match against the service breakdown |
| `maxItems` | integer | `200` | Total cap. `0` = no cap |
| `includeSeen` | boolean | `true` | Off = only providers not seen in previous runs |

***

### Output

```json
{
  "id": "clutch:25800",
  "url": "https://clutch.co/profile/ignite-visibility",
  "legalName": "Ignite Visibility",
  "rating": 4.8,
  "reviewsCount": 175,
  "hourlyRate": "$100 - $149 / hr",
  "minProjectSize": "$1,000+",
  "employeesRange": "250 - 999",
  "isSponsored": true,
  "rank": 1,
  "location": { "city": "San Diego", "state": "CA", "country": "US" },
  "contact": { "name": "Ignite Visibility", "phones": ["6197521955"] },
  "services": [
    { "name": "Search Engine Optimization", "share": 40 },
    { "name": "Advertising", "share": 10 },
    { "name": "Email Marketing", "share": 10 },
    { "name": "Pay Per Click", "share": 10 }
  ],
  "website": null,
  "taxId": null
}
```

`services` shares always add up to 100 — that is Clutch's own allocation of expertise, and it is the
quickest way to tell an agency that *does* SEO from one that merely *lists* it.

***

### Why this one holds up

Clutch marks its listings with **schema.org microdata** — `itemprop="ratingValue"`, `priceRange`,
`telephone`, the full postal address. That exists so search engines can read the page, which means
Clutch cannot change it without damaging its own traffic. The core of every row comes from there.

Only three things live outside it, because schema.org has no equivalent: team size, the service
breakdown, and whether the placement is paid.

***

### Notes and limits

- **Provider websites are not on listing pages.** They live on each provider's own profile, which is
  a separate request per provider. `website` is therefore `null` — that is what the page publishes,
  not a gap in the extraction.
- **The fiscal fields are `null`** (`taxId`, `activityCode`, `foundedAt`). They belong to the same
  company schema this Actor shares with tax-registry sources, and a services directory does not
  publish them.
- **Clutch is behind Cloudflare.** This Actor runs through Apify's unblocking proxy, so you do not
  configure anything — but it is why runs are slower than a plain HTTP scraper, and why the default
  rate is conservative.
- Providers with no rating are dropped by `minRating`, because claiming they pass a threshold they
  never published would misreport the filter you asked for.

***

### Pricing

Pay per result. You are charged for providers that actually land in your dataset — filtered out and
duplicate rows cost nothing.

# Actor input Schema

## `startUrls` (type: `array`):

Directory listings to scrape, e.g. https://clutch.co/agencies/digital-marketing or https://clutch.co/developers. Filter on Clutch first and the Actor follows that exact list.

## `maxPagesPerListing` (type: `integer`):

Each page holds about 49 providers.

## `minRating` (type: `string`):

e.g. 4.5. Providers with no rating are dropped, since it cannot be claimed they pass.

## `minReviews` (type: `integer`):

Drop providers with fewer reviews than this. The fastest way past agencies with a single glowing review.

## `excludeSponsored` (type: `boolean`):

Drop providers whose position is paid. On a typical Clutch page half the top listings are ads.

## `onlyWithPhone` (type: `boolean`):

Drop providers with no phone number.

## `onlyWithWebsite` (type: `boolean`):

Note: listing pages do not publish provider websites, so this filter drops everything. Kept for parity with the other directory Actors.

## `locationKeywords` (type: `array`):

Only providers whose city or state mentions any of these.

## `serviceKeywords` (type: `array`):

Only providers whose service breakdown mentions any of these, e.g. SEO, Pay Per Click.

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

Total cap for the run. 0 = no cap.

## `includeSeen` (type: `boolean`):

Turn it off to skip providers returned by previous runs.

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

Parallel requests.

## `maxRequestsPerMinute` (type: `integer`):

Rate ceiling.

## `maxRequestRetries` (type: `integer`):

How many times to retry a failed request before dropping it.

## Actor input object example

```json
{
  "startUrls": [
    "https://clutch.co/agencies/digital-marketing"
  ],
  "maxPagesPerListing": 3,
  "excludeSponsored": false,
  "onlyWithPhone": false,
  "onlyWithWebsite": false,
  "maxItems": 200,
  "includeSeen": true,
  "maxConcurrency": 2,
  "maxRequestsPerMinute": 20,
  "maxRequestRetries": 3
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `runSummary` (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 = {
    "startUrls": [
        "https://clutch.co/agencies/digital-marketing"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("juanoox/clutch-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 = { "startUrls": ["https://clutch.co/agencies/digital-marketing"] }

# Run the Actor and wait for it to finish
run = client.actor("juanoox/clutch-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 '{
  "startUrls": [
    "https://clutch.co/agencies/digital-marketing"
  ]
}' |
apify call juanoox/clutch-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,juanoox/clutch-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/AJBczmaofBcV60Cu6/builds/VHMU1qG3p31LhPIDQ/openapi.json
