# Clutch Agency List — Every Agency & Directory URL (`thenetaji/clutch-agency-list-scraper`) Actor

The full map of Clutch before a single agency is scraped: every agency profile URL with its key, or every ranked directory path, straight from the index Clutch publishes. Either list resumes where a run stopped, and both feed the Clutch Scraper directly.

- **URL**: https://apify.com/thenetaji/clutch-agency-list-scraper.md
- **Developed by:** [The Netaji](https://apify.com/thenetaji) (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 $0.04 / 1,000 index rows

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

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

## What's an Apify Actor?

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

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

## How to integrate an Actor?

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

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

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

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

# README

## Clutch Agency List — Every Agency & Directory URL

This Actor returns the map of Clutch: every agency profile URL the site publishes, each with the key that
identifies it, or every ranked directory path, each ready to be pasted into
[Clutch Scraper](https://apify.com/thenetaji/clutch-directory-scraper). It is a list of addresses rather than
a dataset of ratings, and it is where a whole-market study starts instead of a keyword guess.

Two questions it answers before anything expensive is run. How large is the market on Clutch, in agencies
rather than in impressions. And which directories exist at all — including the ones nobody thinks to search
for, because a directory is only discoverable from Clutch's navigation if somebody clicks toward it.

### Accepted input

`listing` chooses which of the two lists to walk and defaults to `agencies`.

| Value | What comes back |
| --- | --- |
| `agencies` | Agency profile URLs, each row carrying the agency's `slug`. |
| `directories` | Ranked directory pages, each row carrying the `directory` path. |

`maxItems` caps how many rows the run saves and defaults to `1000`; `0` walks to the end of the list.
`startList` defaults to `1` and is a resume point rather than a filter: Clutch publishes its index as
numbered lists, a run moves into the next one by itself, and the log prints the list to continue from when
the run stops.

```json
{
  "listing": "agencies",
  "maxItems": 1000,
  "startList": 1
}
```

### Response fields

An agency row and a directory row, both real:

```json
{
  "listing": "agencies",
  "list_index": 1,
  "position": 3,
  "clutch_url": "https://clutch.co/profile/eyemagine",
  "slug": "eyemagine",
  "directory": null
}
```

```json
{
  "listing": "directories",
  "list_index": 1,
  "position": 4,
  "clutch_url": "https://clutch.co/se/it-services/msp/stockholm",
  "slug": null,
  "directory": "se/it-services/msp/stockholm"
}
```

| Field | What it says |
| --- | --- |
| `listing` | Which of the two lists the row came from. |
| `clutch_url` | The URL as Clutch publishes it. |
| `slug` | The agency's key, on agency rows. Empty on directory rows. |
| `directory` | The directory path with no leading slash, on directory rows. Empty on agency rows. |
| `list_index` | Which numbered list the URL was published in. |
| `position` | Where the URL sits inside that list, counting from 1. |

Both key columns exist on every row so that a mixed export stays readable: an agency row carries a `slug` and
an empty `directory`, a directory row the reverse. `list_index` and `position` together are a stable address
in a list of hundreds of thousands, and they are what a later run resumes from.

### Questions

**How many rows are there in each list?**
Enough that `maxItems: 0` is a scheduling decision rather than a checkbox — the agency list runs to six
figures. The exact totals are read from Clutch as the run goes rather than quoted from a fixed number here,
because a published count measured on one day is not a promise about the next. The log prints how many rows
each numbered list held as it is walked.

**How does a run know where the index ends?**
By walking past it. The run asks for the list after the last one, gets nothing back, and stops, logging that
the index is finished. That is the only claim about the size of this index that cannot go stale, which is why
no hard-coded total is used in its place.

**Can the directory paths be fed straight into the Clutch Scraper?**
Some of them. Most of what Clutch publishes is a deeper, country- or city-scoped variant of a directory —
`de/it-services/msp/berlin` — while [Clutch Scraper](https://apify.com/thenetaji/clutch-directory-scraper)
walks one- and two-segment paths such as `it-services` or `agencies/digital-marketing`. A directory-mode run
prints how many of its rows are the shallow, walkable shape, so the split is visible before anything is fed
anywhere. Deeper paths passed to the Scraper anyway are skipped by name rather than failing that run.

**A run stopped at `maxItems` — how is the next one continued?**
The log ends with the list to continue from. Passing that as `startList` on the next run restarts at the
beginning of that list, so a small overlap is re-read rather than a gap being left. Rows carry `list_index`
and `position`, which is enough to drop the overlap after the fact.

**Why is this so much cheaper per row than the other Clutch Actor?**
Because a row here is a URL read from an index Clutch publishes about itself, thousands to a request, while a
row from the Scraper is an agency read off a ranked listing page roughly fifty at a time. The work behind the
two rows is not comparable, and the pricing follows the work.

**Does a row carry the agency's rating or services?**
No. This Actor returns addresses only — the URL, the key, and where it sits in the index. Ratings, rates,
project minimums, headcount and the service mix come from
[Clutch Scraper](https://apify.com/thenetaji/clutch-directory-scraper).

### Related

- [Clutch Scraper — Agency Rates, Size & Services](https://apify.com/thenetaji/clutch-directory-scraper) —
  the ranked agencies in a directory, with rates, project minimums, headcount and the percentage service mix.

# Actor input Schema

## `listing` (type: `string`):

Agency profile URLs lists every agency Clutch publishes. Directory pages lists every category page Clutch publishes — feed those into the Clutch Directory Scraper to get the agencies ranked inside each one.

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

Maximum rows to save. Set 0 to keep going to the end of the index. The run log prints the list it stopped in so the next run can continue from there.

## `startList` (type: `integer`):

Which of Clutch's numbered lists to start from. A run continues into the next list on its own, so this is a resume point rather than a filter; the run log prints where it stopped.

## Actor input object example

```json
{
  "listing": "agencies",
  "maxItems": 100,
  "startList": 1
}
```

# Actor output Schema

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

All records scraped by this run

# 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 = {
    "listing": "agencies",
    "maxItems": 100,
    "startList": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("thenetaji/clutch-agency-list-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 = {
    "listing": "agencies",
    "maxItems": 100,
    "startList": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("thenetaji/clutch-agency-list-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 '{
  "listing": "agencies",
  "maxItems": 100,
  "startList": 1
}' |
apify call thenetaji/clutch-agency-list-scraper --silent --output-dataset

```

## MCP server setup

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