Clutch.co Scraper - Agency Ratings, Hourly Rates & Reviews avatar

Clutch.co Scraper - Agency Ratings, Hourly Rates & Reviews

Pricing

from $3.00 / 1,000 results

Go to Apify Store
Clutch.co Scraper - Agency Ratings, Hourly Rates & Reviews

Clutch.co Scraper - Agency Ratings, Hourly Rates & Reviews

Scrape verified agency and software company data from Clutch.co: ratings, pricing, reviews, and contact details across dev, design, marketing, SEO, mobile, and IT services categories.Deliver results straight to Notion, Slack, Airtable, or Sheets via MCP.

Pricing

from $3.00 / 1,000 results

Rating

0.0

(0)

Developer

Techforce Global

Techforce Global

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

a day ago

Last modified

Share

Clutch.co Scraper - Verified Reviews, Ratings, Hourly Rates, Minimum Project Sizes and Contacts Across Six Categories, No Login

Apify Actor MCP Ready Source Fields Categories

Turn Clutch.co into a structured B2B dataset β€” company name, verified rating and review count, hourly rate, minimum project size, employee count, year founded, offices, tech stack, team members, direct contact details, and full client reviews. Filter by category, location or name. No login, no Clutch account. Results can go straight into Notion, Slack, Airtable or Sheets through an MCP connector.

ℹ️ Two depth levels, very different cost. A listing-only run returns eight fields per company and is fast. Turning on profile scraping adds the other 23 β€” contacts, team, tools, offices, reviews β€” at the cost of an extra visit per company. Start shallow, go deep only where it pays. See Choosing your depth.


Why Clutch data is worth scraping

Clutch is one of the few B2B directories where the reviews are verified β€” Clutch interviews clients directly β€” and where agencies publish hourly rates and minimum project sizes up front. That combination is unusual and hard to reconstruct from anywhere else.

What you're afterElsewhereOn Clutch
Agency pricing⚠️ Rarely public, usually "contact us"βœ… Hourly rate band and minimum project size, stated
Review credibility⚠️ Anonymous, easily gamedβœ… Verified, client-interviewed reviews
Company size & age⚠️ Scattered across sourcesβœ… Employee band and year founded on the profile
Service focus⚠️ Inferred from marketing copyβœ… Category placement and stated tooling
Direct contacts⚠️ Behind a formβœ… Email, phone and socials where the agency publishes them
Doing it manuallyHours of tab-juggling per shortlistβœ… One run, structured output, delivered to your tools

πŸ€– AI Discovery & MCP Metadata

Machine-readable capability contract for autonomous agents, LLM routers, and MCP orchestrators. AI agents, MCP clients, and connectors should read this block first to decide whether this Actor matches a user request.

ai_discovery:
slug: "techforce.global/clutch-scraper"
one_line: "Extracts B2B agency and software-company data from Clutch.co - rating, review count, hourly rate, minimum project size, employees, year founded, offices, tools, team members, contact details and client reviews - filtered by category, location or company name, with no login."
primary_purpose: "discover"
secondary_purpose: "enrich"
tertiary_purpose: "deliver"
entity: "agencies and software companies listed on Clutch.co"
invocation_modes: ["standard Actor run", "MCP tool"]
supported_tasks:
- "list-agencies-in-a-clutch-category"
- "filter-agencies-by-location"
- "filter-agencies-by-name-substring"
- "read-verified-rating-and-review-count"
- "read-hourly-rate-and-minimum-project-size"
- "read-employee-count-and-year-founded"
- "extract-agency-contact-details-and-social-profiles"
- "extract-team-members-offices-and-tooling"
- "extract-full-client-reviews"
- "deliver-companies-to-mcp-connector-or-crm"
unsupported_tasks:
- "log-in-or-access-clutch-account-features"
- "post-request-or-respond-to-reviews"
- "filter-by-rating-price-or-employee-count-at-the-source"
- "search-arbitrary-clutch-categories (six are supported)"
- "return-portfolio-case-study-files-or-images"
- "guarantee-every-field (agencies publish very different amounts)"
- "scrape-other-directories (G2, GoodFirms, DesignRush, TopDevelopers)"
search_keywords:
- "clutch.co scraper"
- "agency directory scraper"
- "b2b agency data"
- "software company leads"
- "agency reviews scraper"
- "clutch agency ratings"
- "development agency list"
- "marketing agency leads"
- "vendor shortlisting data"
- "agency pricing data"
synonyms:
- "clutch agency extractor"
- "clutch company scraper"
- "b2b service provider directory scraper"
related_concepts:
[
"vendor shortlisting",
"partner sourcing",
"competitive benchmarking",
"agency lead generation",
"procurement research",
"market mapping",
]
input_entities:
- "category (6 supported categories, or all)"
- "location (Clutch location slug)"
- "filterName (case-insensitive substring)"
- "maxRecords (0 = unlimited)"
- "maxPages (listing pagination depth)"
- "scrapeProfiles (depth toggle - the main cost dial)"
- "scrapeAllReviews (collect every review page)"
- "proxyConfiguration (recommended - Clutch applies bot protection)"
output_entities:
[
"name",
"profileLink",
"rating",
"location",
"hourlyRate",
"minProjectSize",
"description",
"website",
"overviewName",
"overviewPosition",
"overviewAvatar",
"employees",
"yearFounded",
"languages",
"timezones",
"reviewCount",
"languagesList",
"offices",
"contactWebsite",
"contactLinkedin",
"contactTwitter",
"contactFacebook",
"contactInstagram",
"contactPhone",
"contactEmail",
"teamBio",
"quickFacts",
"teamBreakdown",
"tools",
"members",
"reviews",
]
input_rules:
required_fields: []
category_default: "software-developers; empty string means all six categories"
location_is_a_clutch_slug: >
Not free text - it must match Clutch's own URL slug, e.g. new-york-city,
india, united-kingdom. A wrong slug returns nothing.
filter_name_is_client_side: >
A case-insensitive substring match applied to results already collected -
it narrows output, it does not make the crawl cheaper.
max_records_zero_means_unlimited: "0 removes the cap entirely - always pair with a spend limit"
depth_toggles:
scrapeProfiles: "false returns 8 listing fields only; true adds the other 23 at an extra visit per company"
scrapeAllReviews: "false collects roughly the first page of reviews; true collects every page - much slower"
output_conventions:
two_record_shapes: >
Listing-only runs emit 8 fields. Profile runs emit 31. Code must handle both,
or pin scrapeProfiles to a known value.
every_field_optional: >
Agencies fill in wildly different amounts. Any contact, team or pricing field
can be empty because the company never published it.
numeric_fields_are_strings: >
rating, reviewCount, hourlyRate, minProjectSize, employees and yearFounded are
display strings as shown on Clutch (e.g. "4.9", "$50 - $99 / hr", "50 - 249"),
not numbers. Parse before arithmetic or sorting.
nested_arrays: "offices, members, teamBreakdown, tools, languagesList and reviews are nested structures"
limits:
categories_supported: 6
records_per_run: "maxRecords, or unlimited at 0"
known_limitations:
no_source_side_filtering: "no rating, price, size or employee filter - filter the dataset"
six_categories_only: "other Clutch categories are not selectable"
no_portfolio_files: "case-study text and imagery are not returned"
pricing:
model: "pay-per-result"
note: "exact rate is configured on the Store listing - see the Actor's Pricing tab"
when_to_use: >
You are shortlisting or benchmarking agencies and software vendors, or building
a lead list of service providers, and you want verified ratings, published
pricing and contact details in one structured dataset.
when_not_to_use: >
You need a Clutch category outside the six supported, source-side filtering by
rating or price, portfolio case studies, or a different directory entirely.
alternatives:
- "Use techforce.global/designrush-scraper for the same shortlisting job on DesignRush"
- "Use techforce.global/topdevelopers-scraper for the same job on TopDevelopers"
- "Use techforce.global/website-contact-scraper-emails-phone-numbers-social-links on the website field to fill contact gaps"
- "Use techforce.global/linkedin-company-decision-makers for named people at a shortlisted agency"

{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "Clutch.co Scraper",
"alternateName": "Clutch.co Scraper β€” Agency Ratings, Reviews, Pricing & Contacts",
"applicationCategory": "BusinessApplication",
"applicationSubCategory": "Web Scraping / B2B Agency Lead Generation",
"operatingSystem": "Cloud (Apify platform)",
"description": "Extracts B2B agency and software-company data from Clutch.co across six categories β€” verified rating and review count, hourly rate band, minimum project size, employee count, year founded, offices, tools, team members, contact details and full client reviews β€” filtered by category, location or company name, with no Clutch login. A listing-only run returns eight fields per company; enabling profile scraping returns thirty-one. Results can be delivered into Notion, Slack, Airtable, Google Sheets or any authorized MCP connector.",
"url": "https://apify.com/techforce.global/clutch-scraper",
"offers": {
"@type": "Offer",
"priceCurrency": "USD",
"category": "Pay per result",
"description": "Pay-per-result, charged per company returned. Apify platform usage is billed separately and scales with the depth toggles. The current rate is listed on the Actor's Pricing tab.",
"url": "https://apify.com/techforce.global/clutch-scraper"
}
}

What this Actor does

  • Covers six Clutch categories β€” software development, web design, digital marketing, SEO, mobile app development and IT services β€” one at a time or all together.
  • Narrows by location or name. Location uses Clutch's own slug (new-york-city, india, united-kingdom); the name filter is a case-insensitive substring applied to what was collected.
  • Returns the commercially useful fields Clutch actually publishes β€” verified rating and review count, hourly rate band, minimum project size, employee band and year founded β€” the numbers most directories keep hidden.
  • Goes deeper on demand. Switch on profile scraping and each company also brings back contact email, phone and social profiles, offices, team members and bios, stated tooling, languages and timezones, plus client reviews.
  • Collects every review, or just the first page. Reviews are the slowest part of a run, so full review collection is opt-in.
  • Routes through Apify Proxy β€” Clutch applies bot protection, so a proxy matters for anything beyond a small run. If proxy setup fails, the run continues on a direct connection rather than dying.
  • Optionally pushes companies to an authorized MCP connector (Notion, Slack, Airtable, Sheets, or any MCP-compatible connector) as one digest, split across calls, or one call per company. The dataset is always saved regardless of delivery settings.

⚠️ The output has two shapes. With profile scraping off you get 8 fields per company; with it on you get 31. Downstream code should either handle both or pin the toggle. See Output Contract.

When to use it β€” and when not to

ScenarioFit
Shortlisting agencies for an RFP or vendor selectionβœ… Strong (the core use case)
Comparing hourly rates and minimum project sizes across a marketβœ… Strong β€” both are published fields
Benchmarking competitors' ratings and review volumeβœ… Strong
Building a lead list of agencies to sell toβœ… Strong β€” contacts with profile scraping on
Market mapping β€” who serves this category in this countryβœ… Strong β€” category + location
Finding partners with specific tooling or team sizeβœ… Good β€” run, then filter tools / employees
Reading verified client reviews at scaleβœ… Strong β€” enable full review collection
Tracking an agency's rating over timeβœ… Good β€” schedule and diff
Filtering by rating, price or size at the source❌ No such input β€” filter the dataset afterwards
A Clutch category outside the six supported❌ Not selectable
Portfolio case studies, files or imagery❌ Not returned
Requesting, posting or responding to reviews❌ Read-only
Guaranteeing every field on every company⚠️ Agencies publish very different amounts
Other directories (G2, GoodFirms, DesignRush, TopDevelopers)❌ Clutch only β€” see Related Actors

⚑ Execution Rules (Avoid Common Agent Failures)

  1. scrapeProfiles decides the output shape. Off β†’ 8 fields. On β†’ 31. Handle both, or pin the toggle so your consumer knows what it's getting.
  2. location is a Clutch URL slug, not free text. new-york-city, india, united-kingdom β€” a wrong or invented slug returns nothing, with no error to tell you why.
  3. filterName is applied after collection, not at the source. It narrows the output; it does not reduce how much gets crawled or how long the run takes.
  4. maxRecords: 0 means unlimited. It removes the cap entirely β€” always pair it with a spend limit.
  5. maxPages and maxRecords interact. A high maxRecords with maxPages: 1 stops at whatever one listing page holds. Raise both together.
  6. Only six categories are supported. Leaving category empty scrapes all six; there is no way to target a different Clutch category.
  7. Every field is optional. Agencies fill in very different amounts β€” missing contact details, no stated hourly rate, no team bios are all normal. That's absence of published data, not a scrape failure.
  8. All the numbers are display strings. rating is "4.9", hourlyRate is a band like "$50 - $99 / hr", employees is "50 - 249", minProjectSize is "$10,000+". Parse before comparing or sorting β€” none of them are numeric.
  9. Several fields are nested structures β€” offices, members, teamBreakdown, tools, languagesList and reviews. Flatten before writing a CSV.
  10. scrapeAllReviews is the most expensive switch in the Actor. Off, you get roughly the first page of reviews per company; on, it walks every review page. Only enable it when reviews are the point of the run.
  11. There is no source-side filtering by rating, price, size or employee count. Run, then filter the dataset.
  12. Use a proxy for anything beyond a small run. Clutch applies bot protection; the input defaults to Apify Proxy with the RESIDENTIAL group, which needs a paid Apify plan. If proxy setup fails the run continues directly and is more likely to be blocked.
  13. Runs are slow at depth β€” a real browser, plus an extra visit per company with profile scraping, plus more again with full reviews. Budget minutes and use the async endpoint.
  14. deliveryMode defaults to summary β€” one connector call per run. perCompany on a 200-company run makes 200 calls.
dependencies:
- rule: "scrapeProfiles changes the record from 8 fields to 31"
on_violation: "consumers built against one shape break silently on the other"
- rule: "location must be a real Clutch URL slug"
on_violation: "an empty result with no error explaining why"
- rule: "filterName filters after collection, not at the source"
on_violation: "expecting a narrow filter to make the run cheaper or faster"
- rule: "maxRecords 0 removes the cap entirely"
on_violation: "an unbounded run - always pair with maxTotalChargeUsd"
- rule: "maxPages caps pagination independently of maxRecords"
on_violation: "a high maxRecords silently truncated by a low maxPages"
- rule: "rating, hourlyRate, minProjectSize, employees and yearFounded are display strings"
on_violation: "numeric comparison throws, or sorts a price band alphabetically"
- rule: "offices, members, teamBreakdown, tools, languagesList and reviews are nested"
on_violation: "flat-list assumptions break CSV export"
- rule: "no source-side filtering by rating, price or size exists"
on_violation: "agents construct filter arguments that are silently ignored"
- rule: "Clutch applies bot protection; a proxy is recommended"
on_violation: "thin or empty results on larger runs"
- rule: "delivery requires mcpConnector AND mcpTool"
on_violation: "delivery step is skipped with a warning; the dataset is still written in full"
- rule: "mcpArguments must reference {message} for the rendered template to appear anywhere"
on_violation: "message body is empty; the tool is still called"
- rule: "mcpConnector only resolves when the Actor runs on the Apify platform"
on_violation: "local runs log 'APIFY_MCP_PROXY_URL is not set' and skip delivery; the dataset is unaffected"
authentication:
actor_input: none
platform: "Apify API token required for API / SDK / MCP invocation; paid plan required for residential proxy groups"
target_site: "no Clutch account, login or cookie required - and none is accepted"

πŸ“₯ Input Contract

.actor/input_schema.json is authoritative β€” if any table on this page disagrees with the schema files, the schema files win.

Parameters

FieldTypeRequiredDefaultAllowed Values / FormatExample
categoryenum⬜ No"software-developers"Six categories, or "" for all β€” see below"seo-companies"
locationstring⬜ Noβ€”A Clutch location slug"united-kingdom"
filterNamestring⬜ Noβ€”Case-insensitive substring, applied after collection"digital"
maxRecordsinteger⬜ No100 = unlimited100
maxPagesinteger⬜ No1Listing pages to paginate5
scrapeProfilesboolean⬜ NotrueThe depth dial β€” off gives 8 fields, on gives 31false
scrapeAllReviewsboolean⬜ NofalseCollect every review page per companytrue
proxyConfigurationobject⬜ NoApify Proxy + RESIDENTIALApify proxy editor objectsee below

Categories

ValueCovers
software-developers (default)Custom software and development firms
web-designersWeb design and UX agencies
digital-marketingDigital marketing agencies
seo-companiesSEO and search agencies
mobile-app-developersiOS / Android / cross-platform app builders
it-servicesManaged IT and infrastructure providers
"" (empty)All six, one after another

Location

This is Clutch's own URL slug, not free text. Use the form Clutch uses in its own URLs β€” lowercase, hyphenated:

new-york-city Β· london Β· india Β· united-kingdom Β· united-states Β· canada Β· australia Β· germany Β· poland Β· ukraine

ℹ️ These illustrate the slug format, not a fixed list. Clutch’s supported location slugs change over time, so copy the exact slug out of a Clutch URL before relying on it in an automated pipeline. A slug Clutch does not recognise returns nothing.

Proxy

{
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": ["RESIDENTIAL"]
}
}

This is the schema default. Clutch applies bot protection, so a proxy is strongly recommended for anything beyond a small validation run. RESIDENTIAL is the most reliable group and requires a paid Apify plan. If Apify Proxy cannot be set up, the run continues on a direct connection with a warning rather than failing.

Choosing your depth

GoalConfigurationRelative cost
Quick market scan β€” who's out there, how are they ratedscrapeProfiles: falseπŸ’š Lowest
Shortlist with contactsscrapeProfiles: true, scrapeAllReviews: false🟠 Moderate
Full vendor due diligencescrapeProfiles: true, scrapeAllReviews: trueπŸ”΄ Highest

Examples

Quick market scan β€” fast and cheap

{
"category": "software-developers",
"location": "india",
"maxRecords": 100,
"maxPages": 5,
"scrapeProfiles": false,
"deliveryMode": "none"
}

Shortlist with contact details

{
"category": "digital-marketing",
"location": "united-kingdom",
"maxRecords": 50,
"maxPages": 3,
"scrapeProfiles": true,
"scrapeAllReviews": false,
"deliveryMode": "none"
}

Full due diligence on a small set

{
"category": "web-designers",
"filterName": "studio",
"maxRecords": 10,
"maxPages": 3,
"scrapeProfiles": true,
"scrapeAllReviews": true,
"deliveryMode": "none"
}

Every category, one run

{
"category": "",
"location": "new-york-city",
"maxRecords": 200,
"maxPages": 5,
"scrapeProfiles": true,
"deliveryMode": "none"
}

Cheap validation run before committing

{
"category": "seo-companies",
"maxRecords": 3,
"maxPages": 1,
"scrapeProfiles": false,
"deliveryMode": "none"
}

MCP Delivery Configuration (Optional)

Delivery pushes company data into your own tools. It never contacts an agency.

ParameterTypeDefaultDescription
mcpConnectorstring""Authorized MCP connector on your Apify account (Notion, Slack, Airtable, Sheets, …). Leave empty for dataset-only runs.
deliveryModeenumsummarysummary (one call with everything) Β· chunked (split across calls) Β· perCompany (one call per company) Β· none.
mcpToolstring""Tool name on the connector: create_page, send_message, append_row, create_record. Run once with a connector selected β€” the log lists the connector's available tools.
mcpArgumentsobject{}Arguments passed to the tool. String leaves support {placeholders}.
mcpMessageTemplatestring""Template rendered and exposed to mcpArguments as {message}.

Summary / chunked placeholders: {companyCount}, {companies}, {message} β€” plus {part}/{partCount} in chunked mode.

Per-company placeholders: any field from that company's output record (e.g. {name}, {rating}, {hourlyRate}, {contactEmail}, {profileLink}), plus {message}.

One Airtable record per agency β€” a shortlist you can score:

{
"category": "digital-marketing",
"location": "united-kingdom",
"maxRecords": 50,
"scrapeProfiles": true,
"mcpConnector": "<your-authorized-airtable-connector>",
"deliveryMode": "perCompany",
"mcpTool": "create_record",
"mcpArguments": {
"fields": {
"Agency": "{name}",
"Rating": "{rating}",
"Reviews": "{reviewCount}",
"Hourly rate": "{hourlyRate}",
"Min project": "{minProjectSize}",
"Employees": "{employees}",
"Location": "{location}",
"Email": "{contactEmail}",
"Website": "{website}",
"Clutch": "{profileLink}"
}
}
}

A Slack digest per run:

{
"category": "seo-companies",
"maxRecords": 30,
"mcpConnector": "<your-authorized-slack-connector>",
"deliveryMode": "summary",
"mcpTool": "send_message",
"mcpArguments": { "channel": "#vendor-research", "text": "{message}" },
"mcpMessageTemplate": "πŸ”Ž {companyCount} agencies shortlisted from Clutch:\n\n{companies}"
}

A long list split across Notion sub-pages:

{
"category": "",
"maxRecords": 200,
"mcpConnector": "<your-authorized-notion-connector>",
"deliveryMode": "chunked",
"mcpTool": "notion-create-pages",
"mcpArguments": {
"parent": { "page_id": "<your-page-id>" },
"pages": [
{
"properties": {
"title": "Clutch shortlist β€” part {part}/{partCount}"
},
"content": "{companies}"
}
]
}
}

πŸ“€ Output Contract & Data Structure

Storage: Apify Dataset β€” one row per company. Pagination: limit & offset on the dataset items endpoint. Duplicates: one record per company per run. Across runs, dedupe on profileLink.

Two record shapes

Listing-only (scrapeProfiles: false) β€” 8 fields:

FieldTypeEmpty whenMeaning
namestringrarelyCompany name
profileLinkstringneverClutch profile URL β€” the dedupe key
ratingstringno reviewsVerified rating as displayed, e.g. "4.9"
locationstringnot statedHeadquarters as displayed
hourlyRatestringnot publishedRate band, e.g. "$50 - $99 / hr"
minProjectSizestringnot publishedMinimum engagement, e.g. "$10,000+"
descriptionstringnot publishedShort summary
websitestringnot publishedCompany website

Profile run (scrapeProfiles: true) β€” the 8 above plus 23 more:

FieldTypeMeaning
reviewCountstringNumber of verified reviews, as displayed
employeesstringHeadcount band, e.g. "50 - 249"
yearFoundedstringYear founded, as displayed
languagesstringLanguages served, as displayed
languagesListarrayLanguages as a list
timezonesstringTimezones covered
officesarray of object{ address, phone, employees, verified } per office
contactEmailstringContact email where published
contactPhonestringContact phone where published
contactWebsitestringWebsite from the contact section
contactLinkedinstringLinkedIn profile
contactTwitterstringTwitter/X profile
contactFacebookstringFacebook profile
contactInstagramstringInstagram profile
overviewNamestringNamed contact on the profile
overviewPositionstringThat person's role
overviewAvatarstringTheir avatar image URL
teamBiostringTeam description
teamBreakdownarrayTeam composition as published
membersarray of object{ name, position, bio, photo } per member
toolsarrayTechnologies and tools the company states it uses
quickFactsarray/objectAssorted profile facts
reviewsarray of objectClient reviews β€” more with scrapeAllReviews: true

⚠️ Two things to handle in code.

1. Every "number" is a string. rating ("4.9"), hourlyRate ("$50 - $99 / hr"), minProjectSize ("$10,000+"), employees ("50 - 249"), reviewCount and yearFounded are all captured as displayed. Sorting them naively sorts alphabetically β€” "$100 - $149" lands before "$50 - $99".

2. Any field can be empty. Agencies fill in very different amounts of their Clutch profile. A missing contactEmail means that agency didn't publish one.

Example β€” profile run

{
"name": "Example Digital Studio",
"profileLink": "https://clutch.co/profile/example-digital-studio",
"rating": "4.9",
"location": "London, United Kingdom",
"hourlyRate": "$50 - $99 / hr",
"minProjectSize": "$10,000+",
"description": "Full-service digital product studio for scale-ups.",
"website": "https://exampledigital.co.uk",
"reviewCount": "37",
"employees": "50 - 249",
"yearFounded": "2014",
"languages": "English, French",
"languagesList": ["English", "French"],
"timezones": "GMT",
"offices": [
{
"address": "12 Example St, London EC1",
"phone": "+44 20 7946 0000",
"employees": "50 - 249",
"verified": true
}
],
"contactEmail": "hello@exampledigital.co.uk",
"contactPhone": "+44 20 7946 0000",
"contactWebsite": "https://exampledigital.co.uk",
"contactLinkedin": "https://www.linkedin.com/company/example-digital-studio",
"contactTwitter": "https://x.com/exampledigital",
"contactFacebook": "",
"contactInstagram": "",
"overviewName": "Alex Morgan",
"overviewPosition": "Managing Director",
"overviewAvatar": "https://clutch.co/…/avatar.jpg",
"teamBio": "A 60-person team of designers, engineers and strategists.",
"teamBreakdown": ["Engineering 60%", "Design 25%", "Strategy 15%"],
"members": [
{
"name": "Alex Morgan",
"position": "Managing Director",
"bio": "15 years in digital product.",
"photo": "https://…"
}
],
"tools": ["React", "Node.js", "AWS", "Figma"],
"quickFacts": [],
"reviews": []
}

Example β€” listing-only run

{
"name": "Example Digital Studio",
"profileLink": "https://clutch.co/profile/example-digital-studio",
"rating": "4.9",
"location": "London, United Kingdom",
"hourlyRate": "$50 - $99 / hr",
"minProjectSize": "$10,000+",
"description": "Full-service digital product studio for scale-ups.",
"website": "https://exampledigital.co.uk"
}

Making the output usable

import re
def rating_value(company):
try:
return float(company.get("rating") or "")
except ValueError:
return None
def rate_floor(company):
"""Lowest number in an hourly-rate band, so bands sort numerically."""
digits = re.findall(r"[\d,]+", company.get("hourlyRate") or "")
return int(digits[0].replace(",", "")) if digits else None
def headcount_floor(company):
digits = re.findall(r"[\d,]+", company.get("employees") or "")
return int(digits[0].replace(",", "")) if digits else None
# Handle both record shapes: `reviewCount` only exists on profile runs.
is_profile_run = any("reviewCount" in c for c in items)
shortlist = [
c for c in items
if (rating_value(c) or 0) >= 4.5 and (rate_floor(c) or 0) <= 99
]
shortlist.sort(key=lambda c: (-(rating_value(c) or 0), rate_floor(c) or 9999))
contactable = [c for c in items if c.get("contactEmail") or c.get("contactPhone")]
print(f"{len(items)} companies Β· {len(shortlist)} shortlisted Β· {len(contactable)} contactable")

What a successful run looks like

{
"status": "SUCCEEDED",
"defaultDatasetId": "<datasetId>",
"stats": { "itemCount": 47 }
}

itemCount below maxRecords is normal β€” the category and location combination held fewer companies, maxPages capped pagination before the record limit was reached, or filterName removed some after collection.

itemCount: 0 is a valid empty result. The usual causes, in order of likelihood: an unrecognised location slug, a filterName that matched nothing, or maxPages: 1 on a thin listing.


▢️ Invocation & Integration

Lifecycle: Discover β†’ Understand β†’ Configure β†’ Execute β†’ Retrieve β†’ Validate. Authenticate every call with Authorization: Bearer <APIFY_TOKEN>.

Apify Console

Open the Actor β†’ Input tab β†’ pick a Category (or leave blank for all) β†’ optionally set a Location Filter (Clutch slug) β†’ set Max Records and Max Pages β†’ choose whether to Scrape Profile Pages β†’ leave Proxy configuration on Apify Proxy β†’ (optional) pick an MCP connector, tool and template β†’ Start β†’ export from the Dataset tab. The Contacts only view is CRM-ready; Team & capabilities and Reviews hold the deeper profile data.

Model Context Protocol (MCP)

claude mcp add --transport http apify \
"https://mcp.apify.com?tools=techforce.global/clutch-scraper"

Python (apify-client)

import os, re
from apify_client import ApifyClient
client = ApifyClient(os.getenv("APIFY_TOKEN"))
ACTOR = "techforce.global/clutch-scraper"
run = client.actor(ACTOR).call(run_input={
"category": "digital-marketing",
"location": "united-kingdom", # a Clutch URL slug, not free text
"maxRecords": 50,
"maxPages": 3,
"scrapeProfiles": True, # 31 fields instead of 8
"scrapeAllReviews": False, # the most expensive switch
"deliveryMode": "none",
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(f"{len(items)} companies")
def first_number(value):
digits = re.findall(r"[\d,]+", value or "")
return int(digits[0].replace(",", "")) if digits else None
# Every "number" is a display string β€” parse before sorting.
for company in sorted(items, key=lambda c: -(float(c.get("rating") or 0)))[:10]:
rate = company.get("hourlyRate") or "rate not published"
email = company.get("contactEmail") or "no email published"
print(f'{company["name"]} Β· {company.get("rating") or "β€”"}β˜… ({company.get("reviewCount") or "0"} reviews)')
print(f' {rate} Β· {company.get("employees") or "?"} staff Β· {email}')

Two-pass pattern β€” scan cheaply, then deepen only the shortlist:

# Pass 1: listing only, wide and cheap.
scan = client.actor(ACTOR).call(run_input={
"category": "software-developers", "location": "india",
"maxRecords": 200, "maxPages": 10,
"scrapeProfiles": False, "deliveryMode": "none",
})
rows = client.dataset(scan["defaultDatasetId"]).list_items().items
# Pass 2: deep-scrape only the names worth pursuing.
top = [c["name"] for c in rows if (float(c.get("rating") or 0)) >= 4.8][:10]
for name in top:
deep = client.actor(ACTOR).call(run_input={
"category": "software-developers", "filterName": name,
"maxRecords": 1, "maxPages": 2,
"scrapeProfiles": True, "scrapeAllReviews": True, "deliveryMode": "none",
})

JavaScript / TypeScript (apify-client)

import { ApifyClient } from "apify-client";
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const ACTOR = "techforce.global/clutch-scraper";
const run = await client.actor(ACTOR).call({
category: "web-designers",
location: "new-york-city",
maxRecords: 50,
maxPages: 3,
scrapeProfiles: true,
deliveryMode: "none",
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
// Bands are strings β€” take the first number so they sort numerically.
const firstNumber = (v?: string) => {
const m = (v ?? "").match(/[\d,]+/);
return m ? Number(m[0].replace(/,/g, "")) : undefined;
};
const affordable = items
.filter((c) => (firstNumber(c.hourlyRate) ?? Infinity) <= 99)
.sort((a, b) => Number(b.rating ?? 0) - Number(a.rating ?? 0));
console.log(
`${items.length} companies Β· ${affordable.length} at or under $99/hr`,
);

Profile runs open an extra page per company, so prefer async over the 300s synchronous endpoint.

# 1. Start execution with a hard spend limit
curl -X POST -H 'Content-Type: application/json' \
-H 'Authorization: Bearer <YOUR_APIFY_TOKEN>' \
-d '{"category":"software-developers","location":"india","maxRecords":100,"maxPages":5,"scrapeProfiles":true,"deliveryMode":"none"}' \
'https://api.apify.com/v2/acts/techforce.global~clutch-scraper/runs?maxTotalChargeUsd=3.00'
# 2. Poll
curl -H 'Authorization: Bearer <YOUR_APIFY_TOKEN>' \
'https://api.apify.com/v2/actor-runs/<runId>'
# 3. Retrieve when SUCCEEDED
curl -H 'Authorization: Bearer <YOUR_APIFY_TOKEN>' \
'https://api.apify.com/v2/datasets/<DATASET_ID>/items?clean=true&format=json'

cURL β€” synchronous (small, listing-only runs)

curl -X POST \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <YOUR_APIFY_TOKEN>' \
-d '{"category":"seo-companies","maxRecords":5,"maxPages":1,"scrapeProfiles":false,"deliveryMode":"none"}' \
'https://api.apify.com/v2/acts/techforce.global~clutch-scraper/run-sync-get-dataset-items'

⚠️ Autonomous Agent Error Handling & Resolution Matrix

Error CodeDetection ConditionUnderlying CauseDeterministic Agent Action
AUTH_INVALIDHTTP 401 from ApifyMissing or malformed APIFY_TOKENAbort & Prompt User: request a valid Apify API token.
RATE_LIMITEDHTTP 429 from ApifyApify API rate / concurrency limitsRetry: exponential backoff (2s, 4s, 8s).
SYNC_TIMEOUTHTTP 408 on the sync endpointProfile runs exceed the 300s synchronous ceilingReconfigure: async POST /runs + polling.
BAD_LOCATION_SLUGSUCCEEDED, 0 items, a location was setlocation must be a Clutch URL slugModify Input: copy the slug from a Clutch URL, or clear the field.
FILTER_MATCHED_NOTHINGSUCCEEDED, 0 items, filterName setThe substring matched nothing in what was collectedModify Input: broaden or remove filterName.
PAGES_TOO_SHALLOWFar fewer records than maxRecordsmaxPages capped pagination firstModify Input: raise maxPages.
UNLIMITED_RUNAWAYVery large run, high spendmaxRecords: 0 removes the capReconfigure: set a real limit and maxTotalChargeUsd.
WRONG_RECORD_SHAPEExpected fields missingscrapeProfiles: false returns only 8 fieldsModify Input: enable profile scraping.
EMPTY_FIELDScontactEmail/hourlyRate empty on some rowsThose agencies didn't publish themNot an error. Enrich from website elsewhere.
NUMBERS_ARE_STRINGSSorting or arithmetic misbehavesrating, hourlyRate, employees etc. are display stringsFix Code: extract the leading number before comparing.
PRICE_BAND_SORTS_WRONG$100 - $149 ranks below $50 - $99Alphabetical sort on a band stringFix Code: sort on the parsed lower bound.
NESTED_FIELDSCSV export mangles rowsoffices, members, tools, reviews are nestedFix Code: flatten before exporting.
NO_REVIEWS_RETURNEDreviews thin or emptyscrapeAllReviews: false collects roughly the first page onlyModify Input: enable it if reviews matter.
FILTER_UNSUPPORTEDAgent passes minRating, maxRate, minEmployeesNo source-side filters existFix Approach: run unfiltered, filter the dataset.
CATEGORY_UNSUPPORTEDUser wants a Clutch category outside the sixNot selectableAbort & Prompt User or use the closest supported category.
BLOCKED_OR_THINSharply fewer results than an earlier identical runClutch bot protection on the exit IPReconfigure: enable Apify Proxy with RESIDENTIAL, then retry.
PROXY_UNAVAILABLELog Could not set up Apify Proxy (…). Continuing without a proxyThe plan lacks access to the requested groupPrompt User: upgrade, or accept a higher block rate.
NO_PORTFOLIOUser wants case studies or imageryNot returnedFix Expectation: open profileLink.
DELIVERY_SKIPPEDLog no tool name was providedmcpConnector set but mcpTool emptyModify Input: set mcpTool; the dataset is already saved.
DELIVERY_TOOL_UNKNOWNLog Tool 'x' is not available on this connectorWrong tool name for that connectorModify Input: pick a name from the Available tools: list in the same log line.
DELIVERY_EMPTYConnector called, body emptymcpArguments omitted the {message} placeholderModify Input: map {message} inside mcpArguments.
DELIVERY_FLOODHundreds of connector callsdeliveryMode: "perCompany" on a large runReconfigure: use summary or chunked.
MCP_PROXY_MISSINGLog APIFY_MCP_PROXY_URL is not setRunning locally instead of on the platformReconfigure: apify push and run on the platform.
CHARGE_LIMITRun aborted mid-sweepmaxTotalChargeUsd spend threshold reachedPrompt User: confirm a higher spend cap.

Reading run status: an empty dataset with a SUCCEEDED status is a valid outcome here β€” an unrecognised location slug, an over-narrow filterName or a blocked first page all produce it, and the log says which. Only a FAILED status is a platform-level failure. Every field-level and input-level row above comes from this Actor’s own contract; the 401/408/429 rows are standard Apify API responses.


πŸ—£οΈ Natural Language β†’ Actor Mapping

User saysIntentConstructed Actor input
"Find me web design agencies in New York"Shortlisting{"category":"web-designers","location":"new-york-city","maxRecords":50}
"Which dev shops in India are top rated?"Market scan{"category":"software-developers","location":"india","scrapeProfiles":false,"maxRecords":200} then sort rating
"Agencies under $100/hr with 4.5+ ratings"Filtered shortlistrun, then filter parsed hourlyRate and rating β€” no source-side filter
"Get contact details for these agencies"Enrichment{"scrapeProfiles":true} then read the contact* fields
"What do clients say about them?"Reviews{"scrapeProfiles":true,"scrapeAllReviews":true,"maxRecords":10}
"Compare SEO agency pricing in the UK"Pricing research{"category":"seo-companies","location":"united-kingdom"} then parse hourlyRate
"Find agencies that work with React"Capability match{"scrapeProfiles":true} then filter tools
"How big is this agency?"Company size{"filterName":"<name>","scrapeProfiles":true} then read employees, yearFounded
"Build a lead list of IT services firms"Lead gen{"category":"it-services","scrapeProfiles":true,"maxRecords":100}
"Everything Clutch has for this city"Full sweep{"category":"","location":"<slug>","maxRecords":200,"maxPages":5}
"Push the shortlist into Airtable"CRM delivery{"mcpConnector":"airtable","deliveryMode":"perCompany","mcpTool":"create_record"}
"Why did my location filter return nothing?"DiagnosisThe slug must match Clutch's URL form β€” copy it from a Clutch URL
"Only agencies rated above 4.8"Source filter⚠️ No such input β€” filter the dataset on parsed rating
"Show me their case studies"Portfolio❌ Not returned β€” open profileLink
"Do the same on G2"Other directory❌ Clutch only β€” see Related Actors
"Request a quote from them"Outreach❌ Read-only β€” this Actor never contacts anyone

Should NOT route here: source-side filtering by rating, price, size or employee count Β· Clutch categories outside the six supported Β· portfolio case studies, files or imagery Β· requesting quotes or contacting agencies Β· posting or responding to reviews Β· other directories such as G2, GoodFirms, DesignRush or TopDevelopers.


🧭 Agent Execution & Routing Logic

[Input User Query]
β”‚
β–Ό
1. Is the user shortlisting or researching AGENCIES / software vendors? NO β†’ Route elsewhere
β”‚ YES
β–Ό
2. Which directory?
β”œβ”€β”€ Clutch β†’ stay here
β”œβ”€β”€ DesignRush β†’ Route: DesignRush Agency Scraper
β”œβ”€β”€ TopDevelopers β†’ Route: TopDevelopers Scraper
└── G2 / GoodFirms β†’ Abort: not covered
β–Ό
3. Does the user want to CONTACT agencies or request quotes? YES β†’ Abort. Read-only
β”‚ NO
β–Ό
4. Does the user need filtering by rating / price / size?
β”‚ YES β†’ those inputs DO NOT EXIST. Run unfiltered, filter the dataset afterwards
β–Ό
5. Pick the category (six supported; empty = all six)
β–Ό
6. Location? It must be a CLUTCH URL SLUG (new-york-city, india, united-kingdom).
A wrong slug returns NOTHING with no error. Copy it from a Clutch URL
β–Ό
7. ── THE COST DECISION ── how deep?
β”œβ”€β”€ scrapeProfiles false β†’ 8 fields, fast, cheap (market scan)
β”œβ”€β”€ scrapeProfiles true β†’ 31 fields, extra visit each (shortlist + contacts)
└── + scrapeAllReviews β†’ every review page (due diligence, slowest)
β–Ό
8. Set maxRecords AND maxPages together β€” a low maxPages truncates a high maxRecords.
maxRecords 0 = UNLIMITED: only with maxTotalChargeUsd set
β–Ό
9. Keep the proxy on (Clutch applies bot protection). RESIDENTIAL needs a paid plan
β–Ό
10. Deliver to a connector? YES β†’ mcpConnector + mcpTool + {message}
β”‚ summary (1 call) / chunked / perCompany (1 each!)
β”‚ NO β†’ set deliveryMode "none" (it defaults to summary)
β–Ό
11. Use the ASYNC endpoint for any profile run
β–Ό
[Execute]
β”‚
β”œβ”€β”€β–Ί SUCCEEDED, items > 0 ──► handle the data contract:
β”‚ which SHAPE did you get? 8 fields or 31 β€” branch on scrapeProfiles
β”‚ rating / hourlyRate / minProjectSize / employees are DISPLAY STRINGS
β”‚ β†’ extract the leading number before sorting, or "$100-$149"
β”‚ will rank below "$50-$99"
β”‚ offices / members / tools / reviews are NESTED β†’ flatten for CSV
β”‚ empty contact fields = the agency published none, not a failure
β”‚ dedupe on profileLink
β”‚
└──► SUCCEEDED, items == 0 ──► most likely, in order:
a location slug Clutch does not recognise
a filterName that matched nothing
maxPages too low for the listing

πŸ’° Cost Control & Pricing Transparency

Pay-per-result: you are charged per company returned, with no monthly subscription. The exact rate is on the Actor's Pricing tab in the Apify Store.

Autonomous spend caps: pass maxTotalChargeUsd as a query parameter on the run endpoint for a hard per-execution ceiling.

ℹ️ Always confirm the live rate on the Actor’s Pricing tab before committing to a large run. The Store listing is what bills you, and Apify platform usage is charged on top of the per-result rate β€” see the depth table below for what drives it.

Depth is the cost dial

The per-result charge is the same either way, but platform usage is not β€” depth decides how much browser time and proxy traffic each company costs:

ConfigurationWork per companyUse for
scrapeProfiles: falseπŸ’š Lowest β€” listing onlyMarket scans, rating comparisons
scrapeProfiles: true🟠 An extra visit per companyShortlists with contacts β€” the common case
+ scrapeAllReviews: trueπŸ”΄ Highest β€” walks every review pageDue diligence on a handful of finalists

maxRecords: 0 deserves its own warning. It removes the cap completely. On an all-categories run with profile scraping on, that is an open-ended job β€” always pair it with maxTotalChargeUsd.

Cost levers:

  • Scan shallow, then deepen. The two-pass pattern above β€” a wide listing-only pass, then profile scraping on only the names worth pursuing β€” is by far the biggest saving.
  • Leave scrapeAllReviews off unless review content is the actual deliverable.
  • Validate at maxRecords: 3 before committing to a large run, especially when trying a new location slug.
  • Remember filterName doesn't save anything β€” it filters after collection. Narrow with category and location instead.
  • Prefer summary/chunked delivery over perCompany β€” one call instead of hundreds.
  • Cap the spend with maxTotalChargeUsd on any agent-driven run.

πŸ” Companion machine-readable files

FilePurpose
.actor/actor.jsonIdentity, title, description, version, build tag, and the input / output / dataset schema references
.actor/input_schema.jsonAuthoritative typed input contract β€” category enum, location, name filter, limits, the two depth toggles, proxy, and the 5 delivery fields
.actor/dataset_schema.jsonFour Console Output views β€” Overview, a CRM-ready Contacts only, Team & capabilities, and Reviews
.actor/output_schema.jsonDeclares where results are stored

If any table on this page disagrees with the schema files, the schema files win.


πŸ› οΈ Troubleshooting

#Symptom you seeMost likely causeFix
10 items with a location setThe slug isn't one Clutch recognisesCopy the slug from a real Clutch URL, or clear the field.
20 items with filterName setThe substring matched nothingBroaden or remove it β€” it filters after collection.
3Far fewer records than maxRecordsmaxPages capped pagination firstRaise maxPages alongside maxRecords.
4Only 8 fields per companyscrapeProfiles: falseTurn it on for the full 31-field record.
5contactEmail / hourlyRate empty on some rowsThose agencies didn't publish themNormal. Enrich from website with a contact scraper.
6Sorting by hourlyRate gives nonsenseIt's a band string β€” "$100 - $149" sorts before "$50 - $99"Sort on the parsed lower bound.
7Arithmetic on rating or employees failsBoth are display stringsExtract the leading number first.
8CSV export mangles rowsoffices, members, tools, reviews are nestedFlatten before exporting.
9reviews is thin or emptyscrapeAllReviews: false collects roughly the first pageEnable it if reviews are the point.
10Rating/price filter appears ignoredNo source-side filters existFilter the dataset afterwards.
11A category you want isn't listedSix categories are supportedUse the closest, or open a request.
12Sharply fewer results than an earlier runClutch bot protection on the exit IPEnable Apify Proxy with RESIDENTIAL and retry.
13Log Could not set up Apify ProxyThe plan lacks access to that proxy groupUpgrade, or accept a higher block rate.
14Run takes many minutesProfile scraping opens an extra page per companyExpected; use the async endpoint.
15Run seems unboundedmaxRecords: 0 means unlimitedSet a real limit and a spend cap.
16No case studies or portfolio imagesNot returnedOpen profileLink.
17HTTP 408 on run-sync-get-dataset-itemsThe synchronous endpoint has a hard 300-second ceilingUse async POST /runs β†’ poll β†’ fetch.
18Hundreds of connector callsdeliveryMode: "perCompany"Switch to summary or chunked.
19Notion / Airtable timed outOne call carrying every company is too largeUse deliveryMode: "chunked".
20Slack / Notion received nothingDelivery needs both mcpConnector and mcpToolSet both. The dataset is still written in full.
21Connector fired but the body is emptymcpArguments did not reference {message}Map {message} and populate mcpMessageTemplate.
22Log APIFY_MCP_PROXY_URL is not setYou ran locally; connectors only resolve on the platformDeploy with apify push and run on the platform.
23HTTP 401 / 403 from ApifyMissing, expired or malformed APIFY_TOKENRegenerate in Apify Console β†’ Settings β†’ API & Integrations.
24HTTP 429 from ApifyApify account concurrency / rate limitsRetry with exponential backoff (2s β†’ 4s β†’ 8s).

Known limitations

  • No source-side filtering by rating, price, employee count or project size β€” filter the dataset.
  • Six categories only.
  • location must be a Clutch slug, and a wrong one fails silently with zero results.
  • All the numbers are display strings, including price bands and headcount bands.
  • Field availability varies a lot β€” agencies fill in very different amounts of their profile.
  • No portfolio case studies, files or imagery.

Diagnostic checklist before opening an issue

  1. Baseline run. {"category":"software-developers","maxRecords":3,"maxPages":1,"scrapeProfiles":false} β€” no location, no name filter. Cheapest proof the pipeline works.
  2. Records returned? If yes, the Actor is fine and one of your filters was the problem.
  3. Suspect the location slug first. It's the most common cause of a silent empty result β€” it must match Clutch's own URL form exactly.
  4. Then suspect maxPages. A high maxRecords with maxPages: 1 stops at one page.
  5. Check field expectations against the shape. Missing contacts on a scrapeProfiles: false run is by design, not a bug.

If the issue survives all five steps, open an Issues ticket on the Actor page (or email support) with the run ID, the exact input JSON, and a profileLink where a field you expected was empty.

❓ FAQ

Setup & scope

Do I need a Clutch account?

No β€” and none is accepted. Only public directory and profile pages are read.

Which categories are supported?

Six: software developers, web designers, digital marketing, SEO companies, mobile app developers and IT services. Leaving the category blank scrapes all six.

Can I plug it into Claude, Cursor, or a LangChain agent?

Yes β€” it is a native MCP tool:

claude mcp add --transport http apify "https://mcp.apify.com?tools=techforce.global/clutch-scraper"

Do I need a proxy?

For anything beyond a small validation run, yes. Clutch applies bot protection, and the input defaults to Apify Proxy with the RESIDENTIAL group, which needs a paid plan. If proxy setup fails, the run continues directly rather than failing β€” but expect thinner results.

Inputs

Why did my location filter return nothing?

Because location is Clutch's own URL slug, not free text. united-kingdom works; UK or England won't. Copy the slug straight from a Clutch URL.

Does filterName make the run faster?

No β€” it filters what has already been collected. To reduce the actual work, narrow category and location instead.

What's the difference between maxRecords and maxPages?

maxRecords caps how many companies you keep; maxPages caps how many listing pages get walked. A high maxRecords with a low maxPages stops early β€” raise them together.

How do I make a run cheap?

Turn scrapeProfiles off. That's the single biggest lever: 8 fields instead of 31, and no extra visit per company. Then deepen only the shortlist.

Output

Why do I only get 8 fields?

scrapeProfiles was off. Turning it on adds contacts, team, tools, offices and reviews β€” 31 fields in total.

Why is rating a string?

Everything numeric is captured as displayed β€” rating, reviewCount, hourlyRate, minProjectSize, employees, yearFounded. Parse before comparing, and be careful sorting price bands: "$100 - $149" sorts before "$50 - $99" alphabetically.

Why are some contact fields empty?

Because that agency didn't publish them. Clutch profiles vary enormously in completeness. Take the website field and run a contact scraper over it if you need more.

Why are my reviews thin?

scrapeAllReviews defaults to off, which collects roughly the first page per company. Enable it for the full set β€” it's the slowest option in the Actor.

Can I get their portfolio or case studies?

No β€” open profileLink for those.

Pricing

How is this billed?

Pay-per-result β€” charged per company returned, with no monthly subscription. The current rate is on the Actor's Pricing tab. Apify platform usage is billed separately and depends heavily on your depth toggles.

Does profile scraping cost more?

The per-result charge is the same, but platform usage is higher because each company costs an extra page visit β€” and full review collection more again.

How do I guarantee an agent never overspends?

Pass maxTotalChargeUsd as a query parameter on the run endpoint β€” and never use maxRecords: 0 without it.


Agency directories β€” same job, different source

ActorDirectoryWhy pick it over this one
This ActorClutch.coVerified reviews, published hourly rates and minimum project sizes β€” the richest commercial detail of the three
DesignRush Agency ScraperDesignRushDifferent agency pool, strong on creative and branding firms
TopDevelopers ScraperTopDevelopersDifferent pool again, development-heavy

ℹ️ Run all three for a serious shortlist. The three directories overlap far less than you'd expect β€” an agency ranked highly on one is often absent from another. Dedupe on company name or website.

Enrichment & downstream pipeline

ActorUse it for
Website Contact ScraperFill contact gaps β€” feed it the website field where Clutch showed no email
LinkedIn Company Decision MakersThe named partner or director to actually approach
LinkedIn Company EmployeesVerify claimed team size and skill mix against LinkedIn
GOV.UK Business ScraperConfirm a UK agency is a real, active company before signing
Google Maps Business Leads & Sales IntelligenceLocal presence and contact data for the same firms

Suggested pipeline patterns

🎯 Shortlist β†’ contacts β†’ named buyer This Actor with profile scraping β†’ Website Contact Scraper for the gaps β†’ LinkedIn Decision Makers for the person to approach.

πŸ›‘οΈ Vendor due diligence Deep-scrape your finalists with full reviews β†’ LinkedIn Employees to sanity-check claimed team size β†’ GOV.UK Business Scraper to confirm the legal entity.

πŸ’° Pricing benchmark One category across several countries β†’ parse hourlyRate and minProjectSize β†’ a defensible view of what the market actually charges.

πŸ—ΊοΈ Three-directory market map This Actor + DesignRush + TopDevelopers β†’ dedupe on website β†’ the fullest picture of who serves a category.

πŸ“ˆ Reputation tracking Schedule a listing-only run monthly β†’ diff rating and reviewCount β†’ watch competitors' reputations move.

Browse all Actors by Techforce Global at scraper.techforce.global.


πŸ” Compliance & Data Privacy

This Actor is an independent tool. It is not affiliated with, endorsed by, or sponsored by Clutch.co or Clutch Co. All trademarks are the property of their respective owners.

It reads publicly available directory and profile pages on Clutch.co. It does not log in, does not accept credentials, and never requests quotes, posts reviews or contacts an agency.

Most of the output is straightforward business data β€” company names, ratings, published pricing, service categories. Four points deserve care:

  • Named individuals appear in the output. overviewName, members[].name, their positions, bios and photos, and review authors are identifiable people. That is personal data under GDPR, UK GDPR and CCPA/CPRA. Have a lawful basis for storing it, set a retention period, and be ready to honour access and erasure requests. If you only need company-level data, don't retain the member records.
  • Review content belongs to the clients who wrote it. Reviews are the reason Clutch matters, and they are also third-party copyrighted text about identifiable companies. Quoting them at length in your own materials, or republishing them as if you had gathered them, raises both copyright and attribution issues β€” summarise and attribute.
  • A published contact is not consent to be marketed to. An agency listing an email so prospective clients can reach it has not agreed to receive your outreach. Before any campaign, satisfy the applicable rules (GDPR Art. 6/21, ePrivacy/PECR, CAN-SPAM, CASL).
  • Ratings and pricing go stale. Republishing them as current β€” in a comparison page or a report β€” commits you to a refresh cadence, and a wrong rating attached to a named company is commercially damaging to them and risky for you. Attribute the source and link through to profileLink.

Use of automated collection is governed by Clutch's terms of service, which you are responsible for reviewing. You remain responsible for complying with those terms, Apify's proxy terms, and all applicable data-protection and marketing law in the markets you operate in.


πŸ†˜ Support & Custom Pipeline Engineering

Need additional Clutch categories, scheduled reputation tracking with change detection, review sentiment analysis, multi-directory deduplication, or a full vendor-sourcing pipeline feeding your CRM?


Made with ❀️ by Techforce Global Specialists in High-Performance B2B Contact Data Extraction and AI Automation.


🏷️ Structured data for search & AI discovery

SoftwareApplication describes the Actor; FAQPage wraps the FAQ above so those answers are eligible for rich results, matching it question-for-question.

{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "Clutch.co Scraper",
"alternateName": "Clutch.co Scraper β€” Agency Ratings, Reviews, Pricing & Contacts",
"applicationCategory": "BusinessApplication",
"applicationSubCategory": "Web Scraping / B2B Agency Lead Generation",
"operatingSystem": "Cloud (Apify platform)",
"description": "Extracts B2B agency and software-company data from Clutch.co across six categories β€” verified rating and review count, hourly rate band, minimum project size, employee count, year founded, offices, tools, team members, contact details and full client reviews β€” filtered by category, location or company name, with no Clutch login. A listing-only run returns eight fields per company; enabling profile scraping returns thirty-one. Results can be delivered into Notion, Slack, Airtable, Google Sheets or any authorized MCP connector.",
"url": "https://apify.com/techforce.global/clutch-scraper",
"author": {
"@type": "Organization",
"name": "Techforce Global",
"url": "https://www.techforceglobal.com"
},
"provider": {
"@type": "Organization",
"name": "Apify",
"url": "https://apify.com"
},
"offers": {
"@type": "Offer",
"priceCurrency": "USD",
"category": "Pay per result",
"description": "Pay-per-result, charged per company returned. Apify platform usage is billed separately and scales with the depth toggles. The current rate is listed on the Actor's Pricing tab.",
"url": "https://apify.com/techforce.global/clutch-scraper"
},
"featureList": [
"No Clutch account, login or API key required or accepted",
"Six Clutch categories, or all six in one run when the category is left blank",
"Location filtering via Clutch's own URL slug, so any place Clutch supports works",
"Case-insensitive company-name filter for pulling a known shortlist out of a category",
"Two depth modes: eight listing fields, or thirty-one with profile scraping on",
"Verified rating and review count as Clutch displays them",
"Hourly rate band, minimum project size, employee count and year founded",
"Office locations, tools and team members from the profile page",
"Contact details published on the profile, with the website for further enrichment",
"Client reviews, optionally paginated across every review page",
"Apify Proxy on by default with the RESIDENTIAL group, the reliable choice against Clutch's bot protection",
"A failed proxy setup degrades to a direct connection instead of failing the run",
"Companies pushed to the dataset as each one completes, so a partial run keeps its results",
"Optional MCP delivery to Notion, Slack, Airtable, Google Sheets and more",
"Chunked delivery mode keeps long company lists under connector size and timeout caps"
],
"isAccessibleForFree": false,
"softwareRequirements": "Apify account and API token",
"softwareHelp": {
"@type": "CreativeWork",
"url": "https://apify.com/techforce.global/clutch-scraper"
},
"keywords": "Clutch.co scraper, agency directory scraper, B2B lead generation, software development companies, agency ratings and reviews, hourly rate data, vendor shortlisting, outsourcing partner research, MCP connector"
}
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "Do I need a Clutch account?",
"acceptedAnswer": {
"@type": "Answer",
"text": "No - and none is accepted. Only public directory and profile pages are read."
}
},
{
"@type": "Question",
"name": "Which categories are supported?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Six: software developers, web designers, digital marketing, SEO companies, mobile app developers and IT services. Leaving the category blank scrapes all six."
}
},
{
"@type": "Question",
"name": "Can I plug it into Claude, Cursor, or a LangChain agent?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes - it is a native MCP tool. Add it with: claude mcp add --transport http apify \"https://mcp.apify.com?tools=techforce.global/clutch-scraper\""
}
},
{
"@type": "Question",
"name": "Do I need a proxy?",
"acceptedAnswer": {
"@type": "Answer",
"text": "For anything beyond a small validation run, yes. Clutch applies bot protection, and the input defaults to Apify Proxy with the RESIDENTIAL group, which needs a paid plan. If proxy setup fails, the run continues directly rather than failing - but expect thinner results."
}
},
{
"@type": "Question",
"name": "Why did my location filter return nothing?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Because location is Clutch's own URL slug, not free text. united-kingdom works; UK or England will not. Copy the slug straight from a Clutch URL."
}
},
{
"@type": "Question",
"name": "Does filterName make the run faster?",
"acceptedAnswer": {
"@type": "Answer",
"text": "No - it filters what has already been collected. To reduce the actual work, narrow category and location instead."
}
},
{
"@type": "Question",
"name": "What's the difference between maxRecords and maxPages?",
"acceptedAnswer": {
"@type": "Answer",
"text": "maxRecords caps how many companies you keep; maxPages caps how many listing pages get walked. A high maxRecords with a low maxPages stops early - raise them together."
}
},
{
"@type": "Question",
"name": "How do I make a run cheap?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Turn scrapeProfiles off. That is the single biggest lever: 8 fields instead of 31, and no extra visit per company. Then deepen only the shortlist."
}
},
{
"@type": "Question",
"name": "Why do I only get 8 fields?",
"acceptedAnswer": {
"@type": "Answer",
"text": "scrapeProfiles was off. Turning it on adds contacts, team, tools, offices and reviews - 31 fields in total."
}
},
{
"@type": "Question",
"name": "Why is rating a string?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Everything numeric is captured as displayed - rating, reviewCount, hourlyRate, minProjectSize, employees and yearFounded. Parse before comparing, and be careful sorting price bands: \"$100 - $149\" sorts before \"$50 - $99\" alphabetically."
}
},
{
"@type": "Question",
"name": "Why are some contact fields empty?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Because that agency did not publish them. Clutch profiles vary enormously in completeness. Take the website field and run a contact scraper over it if you need more."
}
},
{
"@type": "Question",
"name": "Why are my reviews thin?",
"acceptedAnswer": {
"@type": "Answer",
"text": "scrapeAllReviews defaults to off, which collects roughly the first page per company. Enable it for the full set - it is the slowest option in the Actor."
}
},
{
"@type": "Question",
"name": "Can I get their portfolio or case studies?",
"acceptedAnswer": {
"@type": "Answer",
"text": "No - open profileLink for those."
}
},
{
"@type": "Question",
"name": "How is this billed?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Pay-per-result - charged per company returned, with no monthly subscription. The current rate is on the Actor's Pricing tab. Apify platform usage is billed separately and depends heavily on your depth toggles."
}
},
{
"@type": "Question",
"name": "Does profile scraping cost more?",
"acceptedAnswer": {
"@type": "Answer",
"text": "The per-result charge is the same, but platform usage is higher because each company costs an extra page visit - and full review collection more again."
}
},
{
"@type": "Question",
"name": "How do I guarantee an agent never overspends?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Pass maxTotalChargeUsd as a query parameter on the run endpoint - and never use maxRecords 0 without it."
}
}
]
}