Trustpilot Scraper: Reviews, Star Breakdown & Company Stats
Pricing
from $1.20 / 1,000 results
Trustpilot Scraper: Reviews, Star Breakdown & Company Stats
Scrape Trustpilot business profiles and reviews on any country domain: TrustScore, the exact 1-5 star distribution in counts and percentages, reply rate, claim and verification status, contact block, plus reviews with verification badge and company reply. Keyword, category sweep or pasted links.
Pricing
from $1.20 / 1,000 results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Scrape Trustpilot business profiles and their reviews, on any Trustpilot country domain.
Most Trustpilot scrapers give you a list of review rows. This one also gives you the numbers that make those reviews mean something: the exact 1-5 star distribution, the negative and positive share, how often the company actually replies and how fast, whether the profile is claimed, and the full public contact block. Point it at one company, a whole category, or a keyword search.
What you get
Two row types in one dataset, told apart by kind.
kind: "business" - the company profile
| Field | What it is |
|---|---|
identifyingName, displayName, profileUrl, websiteUrl, logoUrl | identity |
trustScore, stars | the headline score (0-5) and the rounded star rating |
numberOfReviews, numberOfReviewsLast12Months | volume, all time and recent |
ratingDistribution | exact counts per star: {oneStar, twoStar, threeStar, fourStar, fiveStar} |
ratingDistributionPercent | the same split as percentages |
negativeReviewShare, positiveReviewShare | 1-2 star and 4-5 star share of all reviews |
replyPercentage, averageDaysToReply | how often, and how fast, the company answers |
negativeReviewsWithRepliesCount, totalNegativeReviewsCount | how many complaints got an answer |
isClaimed, claimedDate, isClosed, isTemporarilyClosed, isCollectingReviews | profile status |
verifiedByGoogle, verifiedPaymentMethod, verifiedUserIdentity, hasCollectedIncentivisedReviews | trust signals |
contactEmail, contactPhone, contactAddress, contactCity, contactZipCode, countryCode | the public contact block |
primaryCategoryName, categories, breadcrumbTopLevel/MidLevel/BottomLevel | classification |
reviewLanguages | how many reviews exist per language |
reviewsScraped, verifiedReviewsScraped, verifiedShareOfScraped, repliedShareOfScraped | stats over the reviews this run actually read (a sample, and labelled as one) |
kind: "review" - one row per review
reviewId, reviewUrl, rating, title, text, language, likes, source,
isVerified, verificationLevel, verificationSource, experiencedDate, publishedDate,
updatedDate, hasReply, replyText, replyPublishedDate,
consumerDisplayName, consumerCountryCode, consumerNumberOfReviews,
plus all available business enrichment columns, including TrustScore, star distribution,
reply statistics, profile status, categories, public contact details and review-sample statistics.
These fields repeat on every review row so a review export stands on its own. Review IDs,
ratings, text and reviewer fields remain specific to that review. Missing source values stay empty.
Only what the public profile page itself shows is collected. No account, no login, nothing behind a sign-in wall.
Modes
Search mode finds businesses for you.
searchType: "keyword"plusquery- Trustpilot's own business search, walked forward.searchType: "category"pluscategory- sweeps every business in a Trustpilot category (the id from the category URL, e.g.book_store).
URL mode reads exactly what you paste, one entry per line, mixed freely:
https://www.trustpilot.com/review/bookshop.orgbookshop.orghttps://www.trustpilot.com/categories/book_storehttps://www.trustpilot.com/search?query=nikehttps://de.trustpilot.com/review/www.example-shop.de
A bare company domain works: it is the same thing Trustpilot uses in its own profile URL.
Review filters (applied by Trustpilot, not by throwing rows away)
Every filter below is pushed into Trustpilot's own review URL, so a narrowed run reads fewer pages instead of downloading everything and discarding most of it.
| Input | Effect |
|---|---|
reviewStars | keep only 1/2/3/4/5-star reviews (multi-select) |
reviewLanguage | all by default - see the note below |
reviewSort | recency or relevance |
verifiedOnly | only reviews Trustpilot marks verified |
reviewsSince | last30days / last3months / last6months / last12months |
reviewKeyword | only reviews whose text matches a keyword, e.g. refund |
Why
reviewLanguagedefaults toall. Trustpilot itself defaults to the visitor's language and hides the rest. On one profile checked while building this actor, the company had 45,986 reviews but a default English visitor was shown only 30,234 of them. This actor asks for every language unless you narrow it, sonumberOfReviewsand the review rows agree.
Limits and cost controls
maxItems- the run cap, counting business rows and review rows together. Default 50,0= no limit.maxReviewsPerBusiness- a per-business budget (20 reviews per page). Default 20,0= every review.maxPages- upper bound per category / search / review list. Default0= as deep as Trustpilot serves.minTrustScore- skip businesses below a TrustScore.fetchDetails- Search mode only. Off, businesses ship with just what the listing card carries.
Resume and recurring updates
resumeFromRunIdcontinues ONE interrupted run. Paste the previous run or dataset id; rows it already collected are not returned and not billed again.incrementalModeis for a schedule. The first run marks everythingNEW; later runs return onlyNEW,UPDATEDandREAPPEARED, withchangedFields,firstSeenAtandlastSeenAt.emitUnchangedandemitExpiredaddUNCHANGED/EXPIREDrows (and bill them), both off by default.EXPIREDis only produced after a run that fully scanned the tracked scope: never whenmaxItemscapped it, never when a page could not be read, and never on a resumed run.
State is kept separately per search and per review-filter setup, so a 5-star campaign never mixes
its baseline with an all-stars one. stateKey lets you name a campaign or deliberately share one.
Send results into your apps (MCP connectors)
Set mcpConnectors to pipe every returned row into the tools you already use over Model Context
Protocol. Authorize a connector under Apify → Settings → API & Integrations, then select it here.
Notion gets a page per item (set notionParentPageUrl); other connectors get a best-effort write or
digest. maxNotifyListings caps how many rows go to each connector. None of this changes the dataset.
Connection
Trustpilot refuses ordinary connections on every route. The actor tries the connection you configure
in proxyConfiguration first and, only once that one has been refused on this run, switches to Apify
Proxy's enhanced connection tier and stays there for the rest of the run, so the wasted first probe is
paid once per run rather than once per page. Keep Apify Proxy enabled. If your plan cannot open that
tier, the run fails with a clear message instead of quietly returning zero rows.
Pricing
You are charged for:
- Result - each row returned, business profile or review.
- Business profile enrichment - once per business returned in Search mode whose own profile page
was read (that is, when
fetchDetailsorscrapeReviewsis on). Never charged for a pasted profile link, never charged for a row incremental mode suppressed. - Actor Start - once per run.
Sample output (illustrative, not a real business or reviewer)
{"kind": "business","recordId": "business:example-shop.test","identifyingName": "example-shop.test","displayName": "Example Shop","profileUrl": "https://www.trustpilot.com/review/example-shop.test","trustScore": 4.3,"stars": 4,"numberOfReviews": 1000,"ratingDistribution": { "oneStar": 100, "twoStar": 50, "threeStar": 50, "fourStar": 200, "fiveStar": 600 },"ratingDistributionPercent": { "oneStar": 10.0, "twoStar": 5.0, "threeStar": 5.0, "fourStar": 20.0, "fiveStar": 60.0 },"negativeReviewShare": 15.0,"positiveReviewShare": 80.0,"replyPercentage": 62,"averageDaysToReply": 2,"isClaimed": true,"primaryCategoryName": "Book Store","contactEmail": "support@example-shop.test","contactPhone": "(555) 010-0100","reviewsScraped": 20,"verifiedShareOfScraped": 85.0,"changeType": "NEW"}
{"kind": "review","recordId": "review:00000000000000000000000","reviewId": "00000000000000000000000","reviewUrl": "https://www.trustpilot.com/reviews/00000000000000000000000","businessIdentifyingName": "example-shop.test","rating": 5,"title": "Sample review title","text": "Sample review body. This is not a real customer review.","language": "en","isVerified": true,"verificationLevel": "verified","experiencedDate": "2026-01-01T00:00:00.000Z","publishedDate": "2026-01-02T00:00:00.000Z","hasReply": true,"replyText": "Sample company reply.","consumerDisplayName": "Sample Reviewer","consumerCountryCode": "US","changeType": "NEW"}
Notes
- Reviews are public content. Reviewer rows carry only what Trustpilot itself publishes on the page: a display name, a country, a public review counter and the review text. Nothing is collected that needs an account, and nothing is inferred beyond the page.
verifiedShareOfScrapedandrepliedShareOfScrapeddescribe the reviews this run read, not the whole review base.ratingDistributionis exact, straight from Trustpilot.- Country domains (
uk.,de.,fr.,nl.,dk.,it.,es., ...) share one grammar. Setsite, or just paste a link on that domain.
Local development
python3.12 -m venv .venv && .venv/bin/pip install -r requirements.txtPATH=.venv/bin:$PATH apify run --purge.venv/bin/python -m pytest tests/ -q