How to use Capterra Products Scraper
Step by step: in the Apify Store, over the API, from JavaScript or Python, in n8n, and from AI agents through MCP or LangChain.
$6.21 per 1,000 products on the Free plan, down to $3.51 on higher plans (live Apify price on 2026-10-31).
1. In the Apify Store (no code)
- Open arcadium/capterra-products and sign in to Apify (a free account works).
- Fill in the input form. The fields below are the ones the example uses.
- Set a maximum cost per run in the run options if you want a hard cap.
- Start the run. Rows appear in the Output tab as they arrive.
- Export the dataset as JSON, CSV or Excel, or connect an integration.
| Input field | Type | Description |
|---|---|---|
startUrls | array | Capterra category pages (https://www.capterra.com/project-management-software/) list every product in the category. Product pages (https://www.capterra.com/p/184581/Asana-PM/) return that one product. Both kinds can be mixed. Give at least one. Other Capterra actors' field urls (plain list of links) is accepted too. |
maxResultsPerCategory | integer | Maximum number of products to collect from each category page list (up to 1,000). A product URL always counts as one. Also accepted as maxItems, or as maxPages (25 products a page). Default 50. |
Example input:
{
"startUrls": [
{
"url": "https://www.capterra.com/project-management-software/"
}
],
"maxResultsPerCategory": 50
}
2. Over the Apify API
The synchronous endpoint runs the actor and returns its rows in one call (for runs up to about five minutes; use the asynchronous run endpoint for longer ones).
curl -X POST "https://api.apify.com/v2/acts/arcadium~capterra-products/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"startUrls":[{"url":"https://www.capterra.com/project-management-software/"}],"maxResultsPerCategory":50}'
3. From JavaScript
// npm install apify-client
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('arcadium/capterra-products').call({
"startUrls": [
{
"url": "https://www.capterra.com/project-management-software/"
}
],
"maxResultsPerCategory": 50
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
4. From Python
# pip install apify-client
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("arcadium/capterra-products").call(run_input={
"startUrls": [{
"url": "https://www.capterra.com/project-management-software/",
}],
"maxResultsPerCategory": 50,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
5. In n8n
Paste this node into a workflow (it is a plain HTTP Request node). Create a Header Auth credential with name Authorization and value Bearer <APIFY_TOKEN>; each returned row becomes one item for the next node.
{
"nodes": [
{
"name": "Run arcadium/capterra-products",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
0,
0
],
"parameters": {
"method": "POST",
"url": "https://api.apify.com/v2/acts/arcadium~capterra-products/run-sync-get-dataset-items",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "{\"startUrls\":[{\"url\":\"https://www.capterra.com/project-management-software/\"}],\"maxResultsPerCategory\":50}",
"options": {
"timeout": 300000
}
}
}
],
"connections": {}
}
6. From an AI assistant (MCP)
Add Apify’s MCP server to Claude Desktop, Cursor, VS Code or any MCP client, limited to this actor:
{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com/?tools=arcadium/capterra-products",
"headers": {
"Authorization": "Bearer <APIFY_TOKEN>"
}
}
}
}
More on the MCP page.
7. From LangChain
# pip install langchain-apify (reads APIFY_API_TOKEN from the environment)
from langchain_apify import ApifyActorsTool
tool = ApifyActorsTool("arcadium/capterra-products")
rows = tool.invoke({"run_input": {
"startUrls": [{
"url": "https://www.capterra.com/project-management-software/",
}],
"maxResultsPerCategory": 50,
}})
# or give `tool` to an agent: create_react_agent(llm, [tool])
Sample output
One row, from the example in the actor’s README. Long text is shortened and lists are cut to two items.
{
"rowType": "product",
"platform": "capterra",
"seoId": "184581",
"name": "Asana",
"vendor": "Asana",
"rating": 4.49,
"reviewCount": 13770,
"category": "Project Management",
"pricing": {
"startingPrice": 10.99,
"currency": "USD",
"model": "Per User",
"frequency": "Per Month",
"hasFreeTrial": true,
"hasFreeVersion": true,
"summary": "From $10.99 (Per User, Per Month)"
},
"topFeatures": [
"Task Management",
"Collaboration Tools"
],
"rank": 18,
"sponsored": false
}
| Field | What it holds |
|---|---|
rowType | Kind of row. Filter on this first. Values: 'product': one product (charged). 'error': an input could not be read; see code and message (free). |
platform | Source site, e.g. 'capterra'. |
seoId | Capterra product id, the number in the product URL. |
name | Product name. |
url | Product page URL. |
vendor | Vendor company name. |
rating | Overall rating, 1 to 5. |
reviewCount | Number of reviews the site shows. |
category | Category the product was listed under. |
description | Short product description. |
pricing | Pricing summary: startingPrice, currency, model (e.g. Per User), frequency (e.g. Per Month), hasFreeTrial, hasFreeVersion, summary text and plans [{ name, startingPrice }]. Fields the site does not publish are null. |
topFeatures | Most mentioned features listed by the site. |
rank | 1-based position in the category list, null for direct product URLs. |
sponsored | True when the listing is a paid placement, null when the site does not say. |
page | Number of the list page the product was found on. |
categoryUrl | Category URL the product was listed under, null for direct product URLs. |
scrapedAt | ISO timestamp of when the row was collected. |
input | Error and coverage rows: the input (URL, id or search text) the row is about. Example: 'https://www.example.com/page'. |
code | Error rows: machine-readable reason. One of invalid_input (fix the input), not_found (page does not exist), blocked (site refused, retry later), unavailable (temporary error, retry later), filter_unsupported (the filter cannot be applied on this site), no_match (name search found nothing). |
message | Error rows: short human-readable explanation. Do not parse it, use code. |
Schedule it
In Apify Console, create a Task from your input and add a Schedule (for example daily). Each run writes a new dataset; integrations can push the rows to Google Sheets, Slack, a webhook or your database.