WEBCOMPANYAI API MCP READY

TrustRadius Reviews API

B2B software reviews as structured JSON, carrying the field most review data leaves out: which alternatives the buyer weighed, and why they picked the one they picked. Alongside it come per-feature numeric scores rather than one overall star, usability and support and implementation ratings, return-on-investment notes, pros and cons as discrete points, a replaced-an-incumbent flag, and the reviewer's job title, company size and industry. Two modes: point it at a product page and it discovers that product's reviews, or hand it individual review URLs. Billed per review returned, MCP ready.

MEDIAN LAGon demand
FIELDS52

Input parameters

PARAMETERTYPEREQDEFAULTDESCRIPTION
mode enum yes review product discovers every review on a product's review page. review collects individual review URLs, one review each. Both modes return the same fields and are billed the same way; product is the easier starting point.
productUrls string[] no Product review pages or bare product slugs, for example https://www.trustradius.com/products/asana/reviews or just asana. Up to 50 per run. Required when mode is product, ignored otherwise.
reviewUrls string[] no Individual review URLs, which follow the pattern /reviews/-. Up to 500 per run. Required when mode is review, ignored otherwise. The easiest way to build a list is to keep reviewUrl from an earlier product-mode run.
maxReviewsPerProduct integer no 50 How many reviews to return per product in product mode, from 1 to 2000. You are charged once per review returned, so this is the ceiling on what a run can cost. — drives your bill
pages integer no How many pages of a product's review list to walk in product mode, from 1 to 25. Higher values reach older reviews. It does not raise the cap; maxReviewsPerProduct still stops the run.

Output schema

FIELDTYPEDESCRIPTIONNULLABLE
result_type string review or error. Error rows share the dataset with review rows, so split on this before you aggregate anything. no
reviewId string Stable identifier for the review, the same slug that ends its URL. no
productId string Stable identifier for the reviewed product. This is the canonical slug, which is not always the slug you asked for. yes
productName string Display name of the reviewed product. no
productUrl string The product review page this review belongs to. yes
reviewUrl string Direct link to the individual review. Keep it; it is the input for a later review-mode re-pull, and the natural upsert key. no
reviewTitle string Headline the reviewer gave the review. yes
reviewRating number The reviewer's overall score on a 1 to 10 scale, not 1 to 5. Rescale before mixing it with a five-star source. yes
reviewDate string ISO timestamp for when the review was posted. yes
startDate string ISO timestamp for when the reviewer says they started using the product. The source's value is self-reported and sometimes sits after the review date, so treat it as soft. yes
updatedDate string ISO timestamp for the last time the review record changed upstream. yes
pros string[] What the reviewer liked, as discrete points rather than a paragraph. yes
cons string[] What the reviewer disliked, as discrete points. yes
prosAndCons string The same points as one newline-separated blob. Redundant with pros and cons; useful only if you want the raw text. yes
useCasesAndScope string How and where the reviewer deploys the product. Long free text, and it can carry HTML fragments from the source's editor. yes
likelihoodToRecommend string Who the reviewer thinks the product suits, in their own words. Also long free text that can carry HTML. yes
returnOnInvestment string Business outcomes the reviewer attributes to the product. yes
efficienciesGained string Time or effort savings reported. Frequently absent. yes
alternativesConsidered string What the buyer weighed this product against, and why they chose it. The reason this source exists. It is free text under the source's prompt, so most values name rivals but some just describe the product. yes
keyDifferentiators string[] Short labels for what the reviewer says sets the product apart, for example Scalability or Ease of Use. Present on maybe half of rows. yes
productsReplaced boolean Whether the purchase displaced an incumbent tool. Filter on true to find switching stories. yes
otherSoftwareUsed object[] Tools the reviewer runs alongside this one, as objects with two keys: name and link. Not a flat string array. yes
businessProcessesSupported string Which internal processes the product supports. Newline-separated text. yes
innovativeUses string Unusual applications. Arrives as a stringified Python-style dict rather than parsed JSON, and as the literal "{}" when empty. yes
futurePlannedUses string What the reviewer intends to use it for next. Frequently absent. yes
likelihoodToRenew string Renewal intent. Often just a number as a string rather than a sentence. yes
usabilityPros string What is easy about using the product, newline-separated. yes
usabilityCons string What is awkward about using it. Sparse; absent on both rows sampled while writing this page. yes
easyTasks string Tasks the reviewer finds straightforward. yes
difficultTasks string Tasks the reviewer finds hard. Useful as a product-gap signal. yes
supportPros string What is good about vendor support. yes
supportCons string What is poor about vendor support. yes
supportHeadcountRequired string Internal headcount needed to run the product. Usually a bare number as a string. yes
implementationPartner string Who implemented it. Often the source's own placeholder, such as "Don't know". yes
implementationIssues string Problems encountered during rollout. Often "N/A" rather than empty. yes
usersAndRoles string Who uses the product internally and how many. Another stringified Python-style dict, "{}" when empty. yes
keyInsights string The source's yes and no verdicts on value, features, implementation and buying again. Stringified dicts, one per line. yes
featureRatings object[] Per-feature numeric scores from this reviewer, as objects with two keys: feature and rating. Nineteen entries on one sampled row. This is what makes a feature-level comparison possible. yes
ratings object Usability, support and implementation scores in one object. Any of the three can be missing; one sampled row carried usability only. yes
reviewAuthor string Display name the reviewer publishes under. Often a real name, so treat it as personal data. yes
authorPosition string The reviewer's job title. This is what lets you weight an opinion. yes
authorCompanyName string Company the reviewer works for. yes
authorCompanyIndustry string Industry of the reviewer's company. yes
authorCompanySize string Employee band as a string, for example "1001-5000 employees". Parse it if you want to sort. yes
authorExperienceYears integer Years the reviewer has used the product, as a plain number. yes
authorLabels string[] Badges the source applies, such as Vetted Review or Verified User. yes
authorIncentivized boolean Whether the reviewer got something for writing it. Discount these when you weight sentiment. yes
summary string One-line plain-language digest of the row, including the rating and the reviewer's role, so an agent can read a record without post-processing. no
sourceUrl string Error rows only. The input URL this error relates to. yes
error_message string Error rows only. Plain-language reason the input returned nothing. yes
error_type string Error rows only. Machine-readable category, for example CollectionError. yes
fetched_at string UTC timestamp for when the row was collected. no

Worked examples

Basic — one product, discovered from its review page
{
  "mode": "product",
  "productUrls": ["https://www.trustradius.com/products/asana/reviews"],
  "maxReviewsPerProduct": 25
}
Shortlist comparison — three vendors in one run, the exact input behind the published comparison task
{
  "mode": "product",
  "productUrls": [
    "https://www.trustradius.com/products/asana/reviews",
    "https://www.trustradius.com/products/hubspot-crm/reviews",
    "https://www.trustradius.com/products/slack/reviews"
  ],
  "maxReviewsPerProduct": 1,
  "pages": 1
}
Win loss depth — walk one product deep enough that alternativesConsidered is worth counting
{
  "mode": "product",
  "productUrls": ["gtm-workspace"],
  "maxReviewsPerProduct": 300,
  "pages": 15
}
Weekly watchlist — newest review per competitor, bare slugs, cheap enough to schedule
{
  "mode": "product",
  "productUrls": ["asana", "hubspot-crm", "slack", "gtm-workspace"],
  "maxReviewsPerProduct": 1,
  "pages": 1
}
Review mode — re-pull specific reviews whose URLs you already hold
{
  "mode": "review",
  "reviewUrls": [
    "https://www.trustradius.com/reviews/asana-2025-12-01-09-11-31",
    "https://www.trustradius.com/reviews/zoominfo-sales-2025-04-15-13-25-48"
  ]
}
POWER-USER TIP
maxReviewsPerProduct is the whole bill — You are charged once per review pushed to the dataset, so the cap is your budget and nothing else is. pages only decides how deep the list walk goes before the cap stops it; raising pages without raising the cap changes which reviews you get, not how many. A four-product watchlist at one review each lands around two cents.
POWER-USER TIP
Product slugs do not follow redirects — A product that has been renamed or merged returns an error row rather than the page it now redirects to. zoominfo-sales is the live example, since that product now sits at gtm-workspace; product mode on the old slug returns result_type error while the same product's individual review URLs still resolve in review mode. Open the product page in a browser and copy the slug from the address bar.
POWER-USER TIP
alternativesConsidered is free text, and not always about alternatives — The field carries whatever the reviewer typed under the source's prompt. Most values name rival products and say why one won, which is the point of this source, but some reviewers use the box to praise the product instead. Match the text against your own competitor list rather than assuming every non-empty value is a comparison.
POWER-USER TIP
Three fields arrive as stringified dicts — innovativeUses, usersAndRoles and keyInsights come back as Python-style dict strings, for example {'question': 'valueprice', 'answer': 'yes'}, not as parsed JSON, and as the literal {} when the reviewer left them blank. Read them as text, or parse with ast.literal_eval. Everything else in the schema is properly typed.
POWER-USER TIP
Split on result_type before you aggregate — An input that returns nothing produces a row with result_type error and a plain-language error_message instead of vanishing, which is the behaviour you want, but it will drag a mean rating down if you forget to filter. No review-scraped event is charged for those rows, confirmed on a run that produced one.
POWER-USER TIP
Long text fields can carry HTML — useCasesAndScope and likelihoodToRecommend sometimes include div and br fragments from the source's own editor. Strip tags before the text goes into a spreadsheet or a model prompt.

Coverage

49
fields on a review row — competitive · scored · reviewer context
52
fields in the full schema — 49 review fields plus 3 that appear only on error rows
50
products per run — product mode
500
review URLs per run — review mode
2,000
reviews per product, ceiling — cap it lower, you pay per review
25
list pages walked per product — higher values reach older reviews
10
rating scale — 1 to 10, not 1 to 5
2
dataset views — reviews overview · competitive comparisons
9
published task pages — ready-made configurations on the platform listing

Tasks

Saved runs with the inputs already filled in — each one a standalone page and a working configuration example.

Request a task →

Code

curl

curl -X POST "https://api.apify.com/v2/acts/johnvc~trustradius-reviews-api/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode":"product","productUrls":["asana"],"maxReviewsPerProduct":25}'

Python

from apify_client import ApifyClient

client = ApifyClient("APIFY_TOKEN")
run = client.actor("johnvc/trustradius-reviews-api").call(
    run_input={
        "mode": "product",
        "productUrls": ["https://www.trustradius.com/products/asana/reviews"],
        "maxReviewsPerProduct": 25,
    }
)

for row in client.dataset(run.default_dataset_id).iterate_items():
    if row.get("result_type") != "review":
        print("skipped:", row.get("error_message"))
        continue
    print(row["reviewRating"], row.get("authorPosition"), row.get("authorCompanySize"))
    print("  weighed against:", row.get("alternativesConsidered"))
    for fr in row.get("featureRatings") or []:
        print("   ", fr["feature"], fr["rating"])

Competitive comparisons view

# the alternatives, differentiators, replacement flag and feature scores as one table
curl "https://api.apify.com/v2/datasets/$DATASET_ID/items?view=competitive&format=csv" \
  -H "Authorization: Bearer $APIFY_TOKEN"

Changelog

2026-08-08 Published on the Store. Product-mode discovery re-verified against live product pages.
2026-08-05 Pay-per-review pricing applied, with volume tiers stepping down below the base rate.

What people use it for

Alternatives