# Clutch Agency Directory (`danthedataman/clutch-agency-directory`) Actor

Scrape B2B agency and company listings from any Clutch.co directory: name, profile, website, rating, review count, minimum project size, hourly rate, employee count, location and service mix. Filterable, proxy-aware, no API key.

- **URL**: https://apify.com/danthedataman/clutch-agency-directory.md
- **Developed by:** [Eli J](https://apify.com/danthedataman) (community)
- **Categories:** Lead generation, Business, Marketing
- **Stats:** 5 total users, 4 monthly users, 66.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.25 / 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/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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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 Agency Directory

Turn any **Clutch.co** directory into a clean spreadsheet of B2B agencies and
software companies — name, website, rating, review count, budget, hourly rate,
headcount, location and service mix. No API key, no browser, no scraping code.

Point it at a category (digital marketing, SEO, web design, software development,
IT services, …), narrow it with the same filters Clutch itself offers, and export
to JSON, CSV or Excel.

### What you get

One flat row per company:

| Field | What it is |
| --- | --- |
| `name` | Company name as listed |
| `profileUrl` | Its Clutch profile |
| `website` | The company's own site, unwrapped from Clutch's click-tracking redirect |
| `rating` / `ratingScale` | Clutch's aggregate score, on a 0–5 scale |
| `reviewCount` | Number of Clutch reviews behind that score |
| `minProjectSize` / `minProjectSizeUsd` | Smallest project taken, as text and as a number |
| `hourlyRate` / `hourlyRateMinUsd` / `hourlyRateMaxUsd` | Rate band, as text and as bounds |
| `employees` / `employeesMin` / `employeesMax` | Headcount band, as text and as bounds |
| `location` | The location Clutch prints on the listing |
| `addressCity`, `addressState`, `addressCountry`, `addressPostalCode`, `addressStreet`, `phone` | The postal address published in the listing's structured data |
| `services` | Service mix, e.g. `[{"service": "Search Engine Optimization", "percent": 40}, …]` |
| `listingType` / `isSponsored` | Whether the row is a paid placement or a ranked directory listing |
| `verificationBadge` | `Premier Verified`, `Verified`, or empty |
| `summary` | Clutch's review-derived summary of the company |
| `clutchId`, `listingPage`, `sourceUrl`, `scrapedAt` | Provenance: which listing, which page, and when (ISO-8601 UTC) |

### Why this Actor

Clutch does not publish an API, and it does not answer ordinary HTTP clients —
the connection completes and the server then returns `403` based on the client's
TLS/HTTP2 fingerprint, so swapping in a browser `User-Agent` changes nothing.
This Actor is built around that, and around the directory's quirks:

- **Browser-grade transport.** Sessions are established the way a real browser
  establishes one, so pages come back instead of refusals.
- **Automatic identity rotation.** Each proxy identity is retired *before* the
  site throttles it, and a refused page rotates onto a fresh Apify Proxy session
  and retries rather than ending the run.
- **De-duplicated results.** Rows are keyed on the Clutch company id within each
  directory walk, so a repeated page can never become a repeated — or repeatedly
  billed — row. Across *different* directories you asked for, a company that is
  listed in both is returned for each, because that is what you requested.
- **Sponsored placements are labelled, not hidden.** Paid listings sit at the top
  of most directories and do not always honour the filters you set. Every row
  carries `isSponsored`, so you can keep them, drop them, or count them.
- **Partial failures never kill the run.** An unreadable page is reported in the
  run's `ERRORS` record; the rest of the walk still lands.
- **Failed requests are never written to your dataset**, so an error can never
  appear on your bill as a result row.
- **An empty result is an answer.** Filters that match nothing finish cleanly
  with guidance instead of a red run and a stack trace.

### Input

Nothing is required. With empty input the Actor scrapes the digital marketing
directory and stops at 100 companies.

```json
{
  "category": "agencies/digital-marketing",
  "location": "United Kingdom",
  "sortBy": "ReviewRating",
  "minReviews": "10",
  "maxItems": 100,
  "proxyConfiguration": { "useApifyProxy": true }
}
````

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `category` | string | `agencies/digital-marketing` | The Clutch directory path. Pick from the list or type another, e.g. `seo-firms`, `web-designers`, `developers`, `it-services`. |
| `startUrls` | array | — | Paste Clutch directory URLs instead. Filters already in the URL are kept and `?page=` sets where the walk starts. Overrides `category`. |
| `location` | string | — | Country, state or city (`United Kingdom`, `New York`, `Berlin`). Resolved through Clutch's own location lookup; an unmatched name warns and continues unfiltered. |
| `sortBy` | string | `Sponsorship` | `Sponsorship` (Clutch's default), `ClutchRank`, `ReviewRating`, `NumberOfReviews`, `Verification`, `CompanyName`. |
| `minReviews` | string | `0` | Keep companies with at least 1 / 3 / 5 / 10 / 15 / 20 reviews. |
| `maxBudget` | string | `0` | Keep companies taking projects under $5k … $250k. |
| `hourlyRate` | array | all | One or more rate bands, from `0-25` to `300`. |
| `companySize` | array | all | One or more headcount bands, `Freelancer` through `10,000+`. |
| `serviceLines` | array | all | Clutch service slugs, e.g. `field_pp_sl_seo`. Free-form — see below. |
| `industries` | array | all | Clutch industry slugs, e.g. `field_pp_if_ecommerce`. Free-form — see below. |
| `verifiedOnly` | boolean | `false` | Keep only Clutch-verified companies. |
| `maxItems` | integer | `100` | Hard cap on result rows. `0` means no limit. |
| `maxRunSeconds` | integer | `900` | Stop requesting new pages after this long. `0` disables. |
| `maxRetriesPerRequest` | integer | `8` | How hard to retry a refused page. |
| `rotateAfterRequests` | integer | `24` | Retire each proxy identity after N requests. `0` disables. |
| `proxyConfiguration` | object | Apify Proxy on | Recommended to leave enabled. |

#### Finding service and industry slugs

`serviceLines` and `industries` take Clutch's own slugs, and each directory
publishes its own list — a slug that exists under *digital marketing* may not
exist under *developers*. Rather than ship a fixed dropdown that would block
valid values, these fields are free text. The quickest way to get one: tick the
filter on Clutch in your browser and read it out of the resulting URL, for
example `?related_services=field_pp_sl_seo`.

The same escape hatch works for any filter this Actor does not expose as a
field. Filter the directory in your browser, paste the resulting URL into
`startUrls`, and those parameters are sent as-is.

### Output

```json
{
  "name": "Ignite Visibility",
  "profileUrl": "https://clutch.co/profile/ignite-visibility",
  "website": "https://ignitevisibility.com/?utm_source=clutch.co&utm_medium=referral",
  "rating": 4.8,
  "ratingScale": "0_to_5",
  "reviewCount": 173,
  "minProjectSize": "$1,000+",
  "minProjectSizeUsd": 1000,
  "hourlyRate": "$100 - $149 / hr",
  "hourlyRateMinUsd": 100,
  "hourlyRateMaxUsd": 149,
  "employees": "250 - 999",
  "employeesMin": 250,
  "employeesMax": 999,
  "location": "San Diego, CA",
  "addressCity": "San Diego",
  "addressState": "CA",
  "addressCountry": "US",
  "addressPostalCode": "92037",
  "addressStreet": "4250 Executive Square Suite #100",
  "phone": "6197521955",
  "services": [
    { "service": "Search Engine Optimization", "percent": 40 },
    { "service": "Advertising", "percent": 10 }
  ],
  "listingType": "Sponsor",
  "isSponsored": true,
  "verificationBadge": "Premier Verified",
  "summary": "Ignite Visibility is a digital marketing agency specializing in …",
  "clutchId": "25800",
  "listingPage": 1,
  "sourceUrl": "https://clutch.co/agencies/digital-marketing",
  "scrapedAt": "2026-07-26T19:48:12+00:00"
}
```

### What you can build with it

- **Agency shortlists** — pull every vetted agency in a category and budget band,
  ranked by rating, into a spreadsheet in one run.
- **Lead lists** — company, website, phone and service mix for outbound.
- **Competitive and market research** — rate bands, headcount and service mix
  across a category or a country.
- **Partner sourcing** — filter by service line and industry focus, then sort by
  review volume.
- **Monitoring** — schedule a run and watch ratings, review counts and rankings
  move over time.

### Notes and limits

Things worth knowing before you rely on a column:

- **Sponsored rows come first and can ignore your filters.** Clutch places paid
  listings above the ranked ones; on a location-filtered run a sponsor from
  another country can still appear. Filter on `isSponsored` if you only want
  ranked results, or sort by something other than `Sponsorship`.
- **`location` and the `address*` fields can disagree, on purpose.** `location`
  is what Clutch prints on the card and follows your location filter to the
  matching branch office; the `address*` fields come from the listing's
  structured data and are the company's registered address. A London listing
  whose structured address is New York is a multi-office company, not an error.
  Use `location` for "where this listing is", `address*` for "where the company
  is registered".
- **`addressCountry` is Clutch's code, not always ISO 3166.** The UK's
  constituent countries come back as `SQ` (Scotland), `WL` (Wales) and `ND`
  (Northern Ireland) rather than `GB`. Normalise before joining on it.
- **`website` is only present when Clutch shows a "Visit Website" button**, which
  is not every listing. The URL is the company's own, unwrapped from Clutch's
  redirect, and keeps the UTM parameters Clutch appends.
- **`rating` is Clutch's aggregate on a 0–5 scale** (`ratingScale` says so on
  every row) and moves as reviews land. `minProjectSize` and `hourlyRate` are the
  bands Clutch publishes in USD; where Clutch says *Undisclosed*, the field is
  empty rather than guessed.
- **Per-page counts in the log can be under 50.** The final page of a filtered
  result set is usually partial, and sponsored placements share page one with
  ranked listings, so a page can legitimately report fewer new companies than it
  listed.
- **Directories are deep.** A large category runs to tens of thousands of
  listings, which is why `maxItems` defaults to 100 and a run time budget is on
  by default. Raise both deliberately.
- This Actor collects **public business listing information** only.

### Pricing

Pay per result row, with Apify platform usage included — you are not billed
twice. Tightening the filters or lowering `maxItems` reduces cost directly, and
pages that fail are never billed as rows.

### Integrations

Works with everything on the Apify platform: scheduled runs, webhooks, the REST
API, the MCP server, Zapier, Make, n8n, Slack, Google Sheets, Airbyte, and
LangChain / LlamaIndex.

### Support

Found a bug or need a field that isn't here? Open an issue on the Actor's
**Issues** tab and I'll take a look.

# Actor input Schema

## `category` (type: `string`):

The Clutch directory to scrape, written as the path after <code>clutch.co/</code>. Pick one from the list or type any other Clutch directory path, for example <code>agencies/ecommerce-marketing</code>. Ignored when <b>Clutch directory URLs</b> is filled in.

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

Optional. Paste Clutch directory URLs straight from your browser. Any filters already in the URL are kept, and <code>?page=</code> sets where the walk starts. Overrides <b>Clutch directory</b> when set.

## `location` (type: `string`):

Country, state or city to filter on, for example <code>United Kingdom</code>, <code>New York</code> or <code>Berlin</code>. Clutch's own location lookup resolves the name; if it matches nothing the run continues unfiltered and says so in the log. Leave empty for worldwide.

## `sortBy` (type: `string`):

Ordering of the listing. <b>Sponsored</b> is Clutch's own default and puts paid placements first. Leave as the Clutch default to avoid sending a sort parameter at all.

## `minReviews` (type: `string`):

Keep only companies with at least this many Clutch reviews.

## `maxBudget` (type: `string`):

Keep only companies that take projects under this size.

## `hourlyRate` (type: `array`):

Keep only companies in these hourly-rate bands. Leave empty for all rates.

## `companySize` (type: `array`):

Keep only companies with this many employees. Leave empty for all sizes.

## `serviceLines` (type: `array`):

Keep only companies offering these services, as Clutch's own slugs — for example <code>field\_pp\_sl\_seo</code>, <code>field\_pp\_sl\_smm</code>, <code>field\_pp\_sl\_web\_design</code>. Each directory publishes its own list; the quickest way to find a slug is to tick the filter on Clutch and read it out of the resulting URL. Left free-form on purpose so no valid slug is blocked.

## `industries` (type: `array`):

Keep only companies serving these industries, as Clutch's own slugs — for example <code>field\_pp\_if\_ecommerce</code>, <code>field\_pp\_if\_healthcare</code>, <code>field\_pp\_if\_finservices</code>. Tick the filter on Clutch and read the slug out of the URL. Left free-form on purpose so no valid slug is blocked.

## `verifiedOnly` (type: `boolean`):

Keep only companies that have passed Clutch's verification process. This is a small fraction of any directory.

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

Stop after this many companies. Clutch directories run to tens of thousands of listings, so this is capped by default — set 0 for no limit and rely on the run time budget instead.

## `maxRunSeconds` (type: `integer`):

Stop requesting new pages after this many seconds, so a Clutch-side outage cannot burn a long run. 0 disables the budget.

## `maxRetriesPerRequest` (type: `integer`):

How hard to retry a blocked page. Clutch refuses a large share of residential exits, so each retry rotates onto a fresh IP. Measured 2026-07-26: 8 retries succeeded 2/4 runs, 20 retries with per-request rotation succeeded 3/3.

## `rotateAfterRequests` (type: `integer`):

Retire a proxy identity after this many requests. Clutch blocks a large fraction of residential exits outright, so rotating every request materially raises the success rate. 0 disables.

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

Clutch answers 403 to Apify's datacenter proxy IPs, so this defaults to the RESIDENTIAL group. Measured 2026-07-26: datacenter fails every request; residential returns 50 companies in 10s. Switching groups will break the run.

## Actor input object example

```json
{
  "category": "agencies/digital-marketing",
  "startUrls": [
    "https://clutch.co/agencies/digital-marketing?hourly_rate=100-149"
  ],
  "location": "United Kingdom",
  "sortBy": "",
  "minReviews": "0",
  "maxBudget": "0",
  "hourlyRate": [],
  "companySize": [],
  "serviceLines": [
    "field_pp_sl_seo"
  ],
  "industries": [
    "field_pp_if_ecommerce"
  ],
  "verifiedOnly": false,
  "maxItems": 100,
  "maxRunSeconds": 900,
  "maxRetriesPerRequest": 20,
  "rotateAfterRequests": 1,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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": [],
    "serviceLines": [],
    "industries": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("danthedataman/clutch-agency-directory").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": [],
    "serviceLines": [],
    "industries": [],
}

# Run the Actor and wait for it to finish
run = client.actor("danthedataman/clutch-agency-directory").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": [],
  "serviceLines": [],
  "industries": []
}' |
apify call danthedataman/clutch-agency-directory --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=danthedataman/clutch-agency-directory",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Clutch Agency Directory",
        "description": "Scrape B2B agency and company listings from any Clutch.co directory: name, profile, website, rating, review count, minimum project size, hourly rate, employee count, location and service mix. Filterable, proxy-aware, no API key.",
        "version": "0.4",
        "x-build-id": "5H6HxHlr8SNq8kHOv"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/danthedataman~clutch-agency-directory/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-danthedataman-clutch-agency-directory",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/danthedataman~clutch-agency-directory/runs": {
            "post": {
                "operationId": "runs-sync-danthedataman-clutch-agency-directory",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/danthedataman~clutch-agency-directory/run-sync": {
            "post": {
                "operationId": "run-sync-danthedataman-clutch-agency-directory",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "category": {
                        "title": "Clutch directory",
                        "type": "string",
                        "description": "The Clutch directory to scrape, written as the path after <code>clutch.co/</code>. Pick one from the list or type any other Clutch directory path, for example <code>agencies/ecommerce-marketing</code>. Ignored when <b>Clutch directory URLs</b> is filled in.",
                        "default": "agencies/digital-marketing"
                    },
                    "startUrls": {
                        "title": "Clutch directory URLs",
                        "type": "array",
                        "description": "Optional. Paste Clutch directory URLs straight from your browser. Any filters already in the URL are kept, and <code>?page=</code> sets where the walk starts. Overrides <b>Clutch directory</b> when set.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "location": {
                        "title": "Location",
                        "type": "string",
                        "description": "Country, state or city to filter on, for example <code>United Kingdom</code>, <code>New York</code> or <code>Berlin</code>. Clutch's own location lookup resolves the name; if it matches nothing the run continues unfiltered and says so in the log. Leave empty for worldwide.",
                        "default": ""
                    },
                    "sortBy": {
                        "title": "Sort by",
                        "enum": [
                            "",
                            "Sponsorship",
                            "ClutchRank",
                            "ReviewRating",
                            "NumberOfReviews",
                            "Verification",
                            "CompanyName"
                        ],
                        "type": "string",
                        "description": "Ordering of the listing. <b>Sponsored</b> is Clutch's own default and puts paid placements first. Leave as the Clutch default to avoid sending a sort parameter at all.",
                        "default": ""
                    },
                    "minReviews": {
                        "title": "Minimum reviews",
                        "enum": [
                            "0",
                            "1",
                            "3",
                            "5",
                            "10",
                            "15",
                            "20"
                        ],
                        "type": "string",
                        "description": "Keep only companies with at least this many Clutch reviews.",
                        "default": "0"
                    },
                    "maxBudget": {
                        "title": "Project budget",
                        "enum": [
                            "0",
                            "5000",
                            "10000",
                            "25000",
                            "50000",
                            "75000",
                            "100000",
                            "250000"
                        ],
                        "type": "string",
                        "description": "Keep only companies that take projects under this size.",
                        "default": "0"
                    },
                    "hourlyRate": {
                        "title": "Hourly rate",
                        "type": "array",
                        "description": "Keep only companies in these hourly-rate bands. Leave empty for all rates.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "0-25",
                                "25-49",
                                "50-99",
                                "100-149",
                                "150-199",
                                "200-300",
                                "300"
                            ],
                            "enumTitles": [
                                "Under $25 / hr",
                                "$25 - $49 / hr",
                                "$50 - $99 / hr",
                                "$100 - $149 / hr",
                                "$150 - $199 / hr",
                                "$200 - $300 / hr",
                                "$300+ / hr"
                            ]
                        },
                        "default": []
                    },
                    "companySize": {
                        "title": "Company size",
                        "type": "array",
                        "description": "Keep only companies with this many employees. Leave empty for all sizes.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "Freelancer",
                                "2 - 9",
                                "10 - 49",
                                "50 - 249",
                                "250 - 999",
                                "1,000 - 9,999",
                                "10,000+"
                            ],
                            "enumTitles": [
                                "Freelance",
                                "2 - 9",
                                "10 - 49",
                                "50 - 249",
                                "250 - 999",
                                "1,000 - 9,999",
                                "10,000+"
                            ]
                        },
                        "default": []
                    },
                    "serviceLines": {
                        "title": "Service lines",
                        "type": "array",
                        "description": "Keep only companies offering these services, as Clutch's own slugs — for example <code>field_pp_sl_seo</code>, <code>field_pp_sl_smm</code>, <code>field_pp_sl_web_design</code>. Each directory publishes its own list; the quickest way to find a slug is to tick the filter on Clutch and read it out of the resulting URL. Left free-form on purpose so no valid slug is blocked.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "industries": {
                        "title": "Industry focus",
                        "type": "array",
                        "description": "Keep only companies serving these industries, as Clutch's own slugs — for example <code>field_pp_if_ecommerce</code>, <code>field_pp_if_healthcare</code>, <code>field_pp_if_finservices</code>. Tick the filter on Clutch and read the slug out of the URL. Left free-form on purpose so no valid slug is blocked.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "verifiedOnly": {
                        "title": "Clutch-verified companies only",
                        "type": "boolean",
                        "description": "Keep only companies that have passed Clutch's verification process. This is a small fraction of any directory.",
                        "default": false
                    },
                    "maxItems": {
                        "title": "Maximum companies",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Stop after this many companies. Clutch directories run to tens of thousands of listings, so this is capped by default — set 0 for no limit and rely on the run time budget instead.",
                        "default": 100
                    },
                    "maxRunSeconds": {
                        "title": "Run time budget (seconds)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Stop requesting new pages after this many seconds, so a Clutch-side outage cannot burn a long run. 0 disables the budget.",
                        "default": 900
                    },
                    "maxRetriesPerRequest": {
                        "title": "Max retries per request",
                        "minimum": 1,
                        "maximum": 20,
                        "type": "integer",
                        "description": "How hard to retry a blocked page. Clutch refuses a large share of residential exits, so each retry rotates onto a fresh IP. Measured 2026-07-26: 8 retries succeeded 2/4 runs, 20 retries with per-request rotation succeeded 3/3.",
                        "default": 20
                    },
                    "rotateAfterRequests": {
                        "title": "Rotate proxy IP every N requests",
                        "minimum": 0,
                        "maximum": 200,
                        "type": "integer",
                        "description": "Retire a proxy identity after this many requests. Clutch blocks a large fraction of residential exits outright, so rotating every request materially raises the success rate. 0 disables.",
                        "default": 1
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Clutch answers 403 to Apify's datacenter proxy IPs, so this defaults to the RESIDENTIAL group. Measured 2026-07-26: datacenter fails every request; residential returns 50 companies in 10s. Switching groups will break the run.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ]
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
