# Capterra Reviews Scraper - $0.85/1,000, No API Key (`dami_studio/capterra-reviews-scraper`) Actor

Scrape public Capterra software reviews by product URL or numeric id. Returns star rating, pros, cons, the ease-of-use, customer-service, features and value sub-scores, likelihood to recommend, plus reviewer job title, industry, company size and how long they used the product.

- **URL**: https://apify.com/dami\_studio/capterra-reviews-scraper.md
- **Developed by:** [Dami's Studio](https://apify.com/dami_studio) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

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

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

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

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

# README

## Capterra Reviews Scraper — Capterra review data as an API

Pulls public software reviews from Capterra for any product you point it at: star rating, the
pros/cons text, four sub-scores, likelihood to recommend, and who wrote it (job title, industry,
company size, how long they used the product).

Paste a Capterra URL, get rows. No login, no cookies, no API key.

**$0.85 per 1,000 reviews** ($0.00085 each), plus $0.001 each time a run starts. Nothing else — no
proxy surcharge, no monthly fee, no volume tiers to unlock. Of the Capterra review scrapers on the
Apify Store with an active user base, exactly one is cheaper than this; the rest run from $0.90 to
$10.00 per 1,000, and that is each one's *lowest* volume tier, not its headline rate.

### What you get per review

| Field | Example |
|---|---|
| `reviewId` | `Capterra___7189737` |
| `title` | `Slack: Essential for Desk Based Workforces` |
| `publishedAt` | `2026-07-25` |
| `overallRating` | `5` |
| `easeOfUse`, `customerService`, `features`, `valueForMoney` | `5`, `5`, `5`, `5` |
| `likelihoodToRecommend` | `10` (out of 10) |
| `pros` | `Slack is the best way for a desk based workforce to communicate...` |
| `cons` | `Occassionally there will be a bug or issue...` |
| `comments` | the reviewer's overall summary, separate from pros and cons |
| `reviewerName`, `reviewerJobTitle` | `Richard M.`, `Founder` |
| `reviewerIndustry`, `companySize`, `usedFor` | `Marketing and Advertising`, `Self-employed`, `2+ years` |
| `verifiedLinkedInUser`, `reviewerValidations` | `true`, `LinkedIn, ProofOfLink` |
| `incentivized`, `incentiveType`, `reviewerSource` | `false`, `NoIncentive`, `No Incentive Offered: This review was submitted organically.` |
| `reviewUrl`, `productId`, `productName` | direct link, `135003`, `Slack` |

Also emitted when the review has them: `alternativesConsidered` (`Microsoft Teams`), `switchedFrom`,
`reasonsForChoosing`, `reasonsForSwitching` — about 6-20% of reviews carry these. Every row also
carries `globalReviewId`, `sourceSite`, `sourceDomain` and, where the reviewer has one,
`reviewerAvatar`.

Measured field coverage on one real 2,500-review Slack run: `overallRating`, all four sub-scores,
`likelihoodToRecommend`, `publishedAt`, `usedFor` and `reviewerSource` were populated on 2,500 of
2,500. `pros` 2,497, `cons` 2,498, `reviewerJobTitle` 2,498, `reviewerIndustry` 2,470, `companySize`
2,469, `comments` 1,988. `reviewerName` on 2,054 of 2,500 — the other 446 reviews are anonymous on
Capterra, and the actor returns `null` rather than inventing a name.

With `includeProductSummary` on (the default) you get one extra free row per product carrying
`averageRating`, the four product-level sub-scores, `totalReviewsOnCapterra`, `reviewsCollected`,
the newest/oldest review date, and `stoppedBecause` — the reason the walk ended.

### Input

```json
{
  "productUrls": ["https://www.capterra.com/p/135003/Slack/reviews/"],
  "maxReviewsPerProduct": 100
}
```

`productUrls` accepts a capterra.com reviews URL, a Capterra country URL, or the bare numeric
product id (`135003`). Only the number matters. Capterra's URL slug is case-sensitive
(`/p/135003/Slack/` works, `/p/135003/slack/` returns an empty page at HTTP 200), so the actor
resolves the real slug itself before it starts paging.

### Which Capterra does it read, and is that allowed?

**`www.capterra.com`, and yes.** That host's `robots.txt` `User-agent: *` group lists 22 disallowed
paths. `/p/<id>/<Slug>/reviews/` is not one of them, and neither `page` nor any other parameter this
actor sends is disallowed. The one query parameter capterra.com does forbid on this path is
`sort_options=`, and this actor never sends it — which is also why there is no sort option in the
input.

Capterra also runs international mirrors (capterra.co.uk, .ca, .com.au, .ie, .co.nz, .in, .com.sg,
.co.za, .ae). They carry the same corpus, and an earlier version of this actor read them. It no
longer does: every one of those hosts ships `Disallow: /*?*` — a blanket ban on any URL with a query
string — and pagination needs one. You can still paste a mirror URL as input; the actor takes the
product id out of it and reads capterra.com.

### Depth: 2,500 reviews per product

Capterra's own pagination stops at page 100 and serves 25 reviews per page, so 2,500 reviews per
product is the ceiling — asking for page 101 returns a byte-for-byte copy of page 1 at HTTP 200.
The actor detects that and stops, reporting `stoppedBecause: "page-limit-reached"` on the summary
row rather than quietly returning duplicates. `page_size`, `per_page`, `limit` and `pageSize` are
all accepted by Capterra and all ignored; 25 is 25.

Most products are well inside that. Slack has 24,167 reviews on Capterra and you can reach 2,500 of
them; HubSpot CRM has 4,477; the large majority of Capterra products have fewer than 2,500 in total
and come back complete.

### Speed and scale

Measured on real Apify runs, August 2026:

| Run | Returned | Requests | Wall time |
|---|---|---|---|
| Slack, 5 reviews | 5 | 1 | 4.6 s |
| Slack, 250 reviews | 250 | 10 | 25 s |
| Slack, 2,500 reviews (the ceiling) | 2,500 | 100 | 222 s |
| Slack + Microsoft Teams + HubSpot CRM, 30 each | 90 | 8 | 14 s |

25 reviews per request, deduplicated by review id. Every one of those runs returned **zero**
duplicate rows — 2,500 rows, 2,500 distinct review ids. The 2,500-review Slack run reached reviews
published in March 2016.

### What this does not do

- **It does not log in.** Only reviews Capterra shows the public are returned.
- **No more than 2,500 reviews per product.** That is Capterra's pagination limit, not a throttle
  we added. See above.
- **No sort order.** Capterra's `sort_options` parameter is disallowed by its robots.txt, so reviews
  come back in Capterra's own default order, which is not chronological. Pull what you need and sort
  on `publishedAt` yourself.
- **No search by product name.** Capterra's `/search` path is disallowed by its robots.txt too, so
  you have to supply a URL or an id. The id is the number in any Capterra product URL.
- **No reviewer country.** capterra.com does not publish one on the review. It publishes a first
  name, a job title, an industry and a company size, and that is what you get.
- **It does not read GetApp, Software Advice or G2.** Those are separate sites with their own
  review sets.
- **No vendor pricing or feature matrices** — this is a reviews scraper.
- **Reviews are English-language**, as capterra.com displays them.

### Costs

Pay per review returned: **$0.00085 per review** ($0.85 per 1,000), plus **$0.001 per run**.

Product summary rows, the empty-input sample row and diagnostic rows are labelled `_charged: false`
and are never billed. A run that finds nothing, or that Capterra blocks, returns a diagnostic row
explaining why and charges you for zero reviews. There is no proxy surcharge: the actor brings its
own egress and uses no Apify Proxy and no residential bandwidth, so `PROXY_RESIDENTIAL_TRANSFER` on
your run is zero. Verified on every run above.

### FAQ

**Can I scrape Capterra reviews without an API key?**
Yes. This actor needs no Capterra account and no key. Give it a product URL and run it.

**Does Capterra have a public reviews API?**
No. Capterra does not offer a public reviews API, which is why a scraper is the normal route. This
actor reads the same pages a browser sees.

**Is scraping Capterra reviews allowed by their robots.txt?**
For the pages this actor reads, yes. `www.capterra.com/robots.txt` does not disallow
`/p/<id>/<Slug>/reviews/` or the `page` parameter for general crawlers. This actor avoids every path
and parameter that file does disallow, including `sort_options=` and `/search`.

**How many reviews can I get for one product?**
Up to 2,500, which is where Capterra's own pagination ends. Set `maxReviewsPerProduct` to what you
actually want — you pay per review.

**How do I find a product's Capterra id?**
It is the number in the URL. `https://www.capterra.com/p/135003/Slack/reviews/` → `135003`.

**Can I get only 1-star reviews?**
Not as a filter. Pull the reviews and filter on `overallRating` in your own pipeline.

**How fresh is it?**
Live. Every run fetches the pages at that moment; nothing is cached between runs.

**Can I monitor a product for new reviews?**
Yes — schedule it with a small `maxReviewsPerProduct` and diff on `reviewId`. Capterra's default
ordering puts recent reviews near the front, though it is not a strict chronological index.

**Why did I get fewer reviews than I asked for?**
Either the product has fewer than you asked for, or you hit the 2,500 page limit. The summary row's
`stoppedBecause` field says which: `all-reviews-collected`, `page-limit-reached`,
`reached-requested-count`, `past-last-page` or `no-reviews-page`.

**How does it get past Cloudflare without a browser?**
It presents a real browser TLS fingerprint over plain HTTP, so there is no headless browser to pay
for. Requests leave from a small pool of fixed addresses; if one is turned away the actor retries on
the next. That retry is invisible to you and costs you nothing — you are billed per review returned,
not per request.

# Actor input Schema

## `productUrls` (type: `array`):

One entry per product. Paste the Capterra reviews URL straight from your address bar (https://www.capterra.com/p/135003/Slack/reviews/), a Capterra country URL (https://www.capterra.co.uk/software/135003/slack), or just the numeric product id (135003). Only the number matters — the actor looks up the rest itself.

## `maxReviewsPerProduct` (type: `integer`):

Hard cap on billable review rows for each product. You are charged per review returned, so this is also your budget cap. Capterra itself stops paginating at 2,500 reviews per product, which is the ceiling here too.

## `includeProductSummary` (type: `boolean`):

On by default. Adds one extra, never-charged row per product with the product name, average rating and sub-scores, Capterra's total review count, how many were collected, and the newest/oldest review dates.

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

Leave empty. The actor picks its own egress and uses no residential bandwidth. Supply proxyUrls only if you need requests to leave from addresses you control.

## Actor input object example

```json
{
  "productUrls": [
    "https://www.capterra.com/p/135003/Slack/reviews/",
    "152373",
    "https://www.capterra.co.uk/software/168668/microsoft-teams"
  ],
  "maxReviewsPerProduct": 100,
  "includeProductSummary": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Results in the default dataset. Only genuine review rows are billable; \_summary, \_sample and \_diagnostic rows carry \_charged: false and are never charged.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "productUrls": [
        "https://www.capterra.com/p/135003/Slack/reviews/"
    ],
    "maxReviewsPerProduct": 100,
    "includeProductSummary": true,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("dami_studio/capterra-reviews-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 = {
    "productUrls": ["https://www.capterra.com/p/135003/Slack/reviews/"],
    "maxReviewsPerProduct": 100,
    "includeProductSummary": True,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("dami_studio/capterra-reviews-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 '{
  "productUrls": [
    "https://www.capterra.com/p/135003/Slack/reviews/"
  ],
  "maxReviewsPerProduct": 100,
  "includeProductSummary": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call dami_studio/capterra-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/capterra-reviews-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/tpVch1QDnokxn3Iex/builds/f2BbbLX5eoTLXCchx/openapi.json
