Trustpilot API & Scraper
The Trustpilot API returns company reviews, TrustScore and profile data as clean JSON.
🤖 Using an AI assistant? Copy this link into ChatGPT / Claude / Cursor — it reads every endpoint and parameter instantly and tells you if this API fits your use case.
The primary company/reviews endpoint returns a business's domain, name, TrustScore, star rating, total and last-12-months review counts and the full rating distribution — alongside the individual review text. You can also fetch company/details, browse a category, and list the top, newest or recently-reviewed companies in any category. It is the managed alternative to scraping Trustpilot for reputation monitoring, competitor benchmarking and review analysis — no login, no proxies, no captcha handling. One ReefAPI key, one shared credit pool, the standard envelope.
TrustScore, stars and the star distribution are three different numbers
A Trustpilot page shows one rating, but the payload carries three views of it and they do not agree by design. trust_score is Trustpilot's own weighted score, stars is that score rounded for display, and rating_distribution is the raw count of reviews per star, whose arithmetic mean is a fourth number again. Every figure below came from a measured company/details call.
| Field | What it is | Measured |
|---|---|---|
| trust_score | A float from 1 to 5 with one decimal. Trustpilot's own weighted score, which favors recent reviews. | gossby.com 4.2, amazon.com 1.6, ryanair.com 1.3 |
| stars | trust_score rounded to the nearest half. A display value, never more precise than the score. | 4.2 became 4.0, 1.6 became 1.5, and 1.3 also became 1.5 |
| mean of rating_distribution | Not returned, and not equal to trust_score. Compute it only if you want the unweighted average. | gossby averages 4.339 against a TrustScore of 4.2; amazon.com averages 2.020 against 1.6 |
| rating_distribution | Keys are the English words one, two, three, four and five, plus total. Not "1" through "5". | {one: 3924, two: 1110, three: 1516, four: 2829, five: 28283, total: 37662} |
| number_of_reviews vs number_of_reviews_last_12_months | A lifetime count and a trailing-year count, both on the company object. | 37662 lifetime against 1321 in the last twelve months |
| business_unit_id | 24 hex characters. review_id and reviewer_id use the same shape. | 5dc962f10fdaf000012b2f08 for gossby.com; a review came back as 6a8df0a36dc0d1236b16f7b0 |
| is_verified vs verification_level | A boolean and a string, carrying different information. | false with "not-verified", false with "invited", true with "verified" |
| source | How the review reached Trustpilot. | "Organic" and "BasicLink" both appeared on one company |
| published_date vs experience_date | ISO 8601 UTC. experience_date is date-only, so its time is always midnight. | published 2026-08-25T21:44:35.000Z about an experience dated 2026-08-24T00:00:00.000Z |
| page and maxReviews | The logged-out view holds 20 reviews per page across 10 pages, so 200 per view is the ceiling. | A capped call returned status "PARTIAL" with a notes field saying so |
The company actions and the category actions name their fields differently. company/details returns business_unit_id with categories as plain strings; category/companies returns businessUnitId with categories as objects of {categoryId, displayName, isPrimary, isPredicted}. Do not point one parser at both.
Real request and response JSON
Captured from the indexed primary action, company/reviews, on .
{
"method": "POST",
"url": "https://api.reefapi.com/trustpilot/v1/company/reviews",
"headers": {
"x-api-key": "$REEF_KEY",
"content-type": "application/json"
},
"body": {
"company": "amazon.com",
"maxReviews": 40
}
}{
"ok": true,
"meta": {
"api": "trustpilot",
"endpoint": "company/reviews",
"mode": "live",
"latency_ms": 7330.5,
"record_count": 40,
"bytes": 57414,
"cache_hit": false,
"summary": {
"companies": 1,
"succeeded": 1,
"not_found": 0,
"blocked": 0,
"failed": 0,
"success_rate_pct": 100,
"total_reviews": 40,
"avg_completeness_pct": 0.1,
"error_breakdown": {},
"retries_used": 0
}
},
"data": {
"results": [
{
"company": {
"domain": "www.amazon.com",
"business_unit_id": "46ad[redacted-phone]d0",
"name": "Amazon",
"trust_score": 1.6,
"stars": 1.5,
"number_of_reviews": 47606,
"number_of_reviews_last_12_months": 8645,
"rating_distribution": {
"one": "[trimmed-depth]",
"two": "[trimmed-depth]",
"three": "[trimmed-depth]",
"four": "[trimmed-depth]",
"five": "[trimmed-depth]",
"total": "[trimmed-depth]"
},
"categories": [
"[trimmed-depth]",
"[trimmed-depth]",
"[trimmed-depth]"
],
"is_claimed": true,
"is_closed": false,
"is_temporarily_closed": false,
"is_collecting_reviews": false,
"claimed_date": "[redacted-phone]T19:08:43.000Z",
"reply_behavior": {
"reply_percentage": "[trimmed-depth]",
"average_days_to_reply": "[trimmed-depth]",
"negative_reviews_with_replies": "[trimmed-depth]",
"total_negative_reviews": "[trimmed-depth]",
"last_reply_to_negative": "[trimmed-depth]"
},
"verification": {
"verified_payment_method": "[trimmed-depth]",
"verified_user_identity": "[trimmed-depth]",
"verified_by_google": "[trimmed-depth]"
},
"locations_count": 0,
"website_url": "https://www.amazon.com",
"website_title": "www.amazon.com",
"profile_image_url": "//s3-eu-west-1.amazonaws.com/tpd/screenshots/46ad[redacted-phone]d0/198x149.png",
"contact_email": null,
"contact_phone": null,
"contact_address": null,
"contact_city": null,
"contact_country": "GB",
"contact_zip": null,
"rankings": [],
"breadcrumb": [
"[trimmed-depth]",
"[trimmed-depth]",
"[trimmed-depth]"
],
"topics": [
"[trimmed-depth]",
"[trimmed-depth]",
"[trimmed-depth]"
],
"description": null,
"ai_summary": null
},
"reviews": [
{
"review_id": "[trimmed-depth]",
"review_url": "[trimmed-depth]",
"company_domain": "[trimmed-depth]",
"company_name": "[trimmed-depth]",
"rating": "[trimmed-depth]",
"title": "[trimmed-depth]",
"text": "[trimmed-depth]",
"language": "[trimmed-depth]",
"published_date": "[trimmed-depth]",
"experience_date": "[trimmed-depth]",
"updated_date": "[trimmed-depth]",
"is_verified": "[trimmed-depth]",
"verification_level": "[trimmed-depth]",
"likes": "[trimmed-depth]",
"source": "[trimmed-depth]",
"reviewer_name": "[trimmed-depth]",
"reviewer_country": "[trimmed-depth]",
"reviewer_id": "[trimmed-depth]",
"reviewer_review_count": "[trimmed-depth]",
"reply_text": "[trimmed-depth]",
"reply_published_date": "[trimmed-depth]",
"scraped_via_filter": "[trimmed-depth]",
"scraped_at_page": "[trimmed-depth]",
"is_pending": "[trimmed-depth]",
"is_flagged": "[trimmed-depth]",
"reviewer_local_review_count": "[trimmed-depth]"
},
{
"review_id": "[trimmed-depth]",
"review_url": "[trimmed-depth]",
"company_domain": "[trimmed-depth]",
"company_name": "[trimmed-depth]",
"rating": "[trimmed-depth]",
"title": "[trimmed-depth]",
"text": "[trimmed-depth]",
"language": "[trimmed-depth]",
"published_date": "[trimmed-depth]",
"experience_date": "[trimmed-depth]",
"updated_date": "[trimmed-depth]",
"is_verified": "[trimmed-depth]",
"verification_level": "[trimmed-depth]",
"likes": "[trimmed-depth]",
"source": "[trimmed-depth]",
"reviewer_name": "[trimmed-depth]",
"reviewer_country": "[trimmed-depth]",
"reviewer_id": "[trimmed-depth]",
"reviewer_review_count": "[trimmed-depth]",
"reply_text": "[trimmed-depth]",
"reply_published_date": "[trimmed-depth]",
"scraped_via_filter": "[trimmed-depth]",
"scraped_at_page": "[trimmed-depth]",
"is_pending": "[trimmed-depth]",
"is_flagged": "[trimmed-depth]",
"reviewer_local_review_count": "[trimmed-depth]"
},
{
"review_id": "[trimmed-depth]",
"review_url": "[trimmed-depth]",
"company_domain": "[trimmed-depth]",
"company_name": "[trimmed-depth]",
"rating": "[trimmed-depth]",
"title": "[trimmed-depth]",
"text": "[trimmed-depth]",
"language": "[trimmed-depth]",
"published_date": "[trimmed-depth]",
"experience_date": "[trimmed-depth]",
"updated_date": "[trimmed-depth]",
"is_verified": "[trimmed-depth]",
"verification_level": "[trimmed-depth]",
"likes": "[trimmed-depth]",
"source": "[trimmed-depth]",
"reviewer_name": "[trimmed-depth]",
"reviewer_country": "[trimmed-depth]",
"reviewer_id": "[trimmed-depth]",
"reviewer_review_count": "[trimmed-depth]",
"reply_text": "[trimmed-depth]",
"reply_published_date": "[trimmed-depth]",
"scraped_via_filter": "[trimmed-depth]",
"scraped_at_page": "[trimmed-depth]",
"is_pending": "[trimmed-depth]",
"is_flagged": "[trimmed-depth]",
"reviewer_local_review_count": "[trimmed-depth]"
}
],
"scraped_count": 40,
"total_reviews": 47606,
"completeness_pct": 0.1,
"status": "PARTIAL",
"attempts": 1,
"notes": "Limited by maxReviews=40; 47606 reviews exist. Raise maxReviews (up to 200) for more."
}
],
"summary": {
"companies": 1,
"succeeded": 1,
"not_found": 0,
"blocked": 0,
"failed": 0,
"success_rate_pct": 100,
"total_reviews": 40,
"avg_completeness_pct": 0.1,
"error_breakdown": {},
"retries_used": 0
}
}
}What the Trustpilot API does
| Action | Description | Concrete use case | Key params |
|---|---|---|---|
| company/reviews | Get a company's Trustpilot reviews and its full profile from trustpilot.com — TrustScore, star rating, total review count, 5-to-1-star rating distribution, business categories, and every review with rating, title, text, date, verified status, likes and the company's reply. Newest first; optionally filter by star rating. | Support teams call company/reviews to get a company's Trustpilot reviews and its full profile from trustpilot.com. | company, maxReviews, includeCompany, sort, date_posted, ... |
| company/details | The full Trustpilot company profile WITHOUT reviews (cheaper than company/reviews when you only need the listing) → TrustScore, star rating, total reviews (and last-12-months), 5-to-1-star distribution, category rankings (e.g. #2 of 26 in Bank), contact info (address, phone, website, email), how the business replies to reviews (reply rate + average days), business verification, claimed/closed status, what customers talk about most (AI topic summaries), the AI review summary and the company description. By company domain. | Reputation platforms call company/details to get the full Trustpilot company profile WITHOUT reviews (cheaper than company/reviews when you on…. | company, locale |
| category/browse | List the companies in a Trustpilot category (20/page) → each company's name, domain, TrustScore, review count and location. Filter by country, minimum TrustScore and claimed status, and sort by recently-reviewed. Also returns the category's size and subcategories, plus the newest companies and the recently-reviewed companies in that category — all in one call. | Market researchers call category/browse to list the companies in a Trustpilot category (20/page) → each company's name, domain, TrustSco…. | categoryId, page, cursor, locale, sort, ... |
| category/companies | List the companies in a Trustpilot category (20/page), ranked → each company's name, domain, TrustScore, review count, categories and location. Filter by country, minimum TrustScore and claimed status. Paginate with page. | B2B review analysts call category/companies to list the companies in a Trustpilot category (20/page), ranked → each company's name, domain,…. | categoryId, page, locale, sort, country, ... |
| category/recently-reviewed | The companies in a Trustpilot category that were reviewed most recently → name, domain, TrustScore, review count and location. | Support teams call category/recently-reviewed to get the companies in a Trustpilot category that were reviewed most recently → name, domain, Trust…. | categoryId, locale |
| category/newest | The newest companies added to a Trustpilot category → name, domain, TrustScore, review count and location. | Reputation platforms call category/newest to get the newest companies added to a Trustpilot category → name, domain, TrustScore, review count…. | categoryId, locale |
| category/details | Details of a Trustpilot category → its display name, the number of businesses in it, and its subcategories. | Market researchers call category/details to get details of a Trustpilot category → its display name, the number of businesses in it, and its…. | categoryId, locale |
| category/search | Search Trustpilot categories by keyword → matching categories with their id and display name (feed a categoryId into category/companies). | B2B review analysts call category/search to search Trustpilot categories by keyword → matching categories with their id and display name…. | query, locale |
| company/search | Search Trustpilot for companies by name (10 matches/page) → each match's name, domain, TrustScore, star rating, review count, categories and location. Filter by minimum TrustScore and minimum review count. Also returns matching categories. | Support teams call company/search to search Trustpilot for companies by name (10 matches/page) → each match's name, domain, TrustS…. | query, page, cursor, min_rating, min_review_count, ... |
| consumer/details | A Trustpilot consumer's public profile → display name, country, number of reviews written, and review statistics. By consumer id. | Reputation platforms call consumer/details to get a Trustpilot consumer's public profile → display name, country, number of reviews written, an…. | consumer_id, locale |
| consumer/reviews | Every review a Trustpilot consumer has written across all companies → each review's company, rating, title, text and date. Paginate with page. | Market researchers call consumer/reviews to get every review a Trustpilot consumer has written across all companies → each review's company,…. | consumer_id, page, cursor, locale |
| reviewer/profile | Alias of consumer/details + consumer/reviews: a reviewer's profile AND every review they have written. By consumer id. | B2B review analysts call reviewer/profile to get alias of consumer/details + consumer/reviews. | consumer_id, page, cursor, locale |
Call company/reviews from your stack
curl -X POST https://api.reefapi.com/trustpilot/v1/company/reviews \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"company":"amazon.com","maxReviews":40}'import requests
r = requests.post(
"https://api.reefapi.com/trustpilot/v1/company/reviews",
headers={"x-api-key": REEF_KEY},
json={
"company": "amazon.com",
"maxReviews": 40
},
)
print(r.json()["data"])const res = await fetch("https://api.reefapi.com/trustpilot/v1/company/reviews", {
method: "POST",
headers: {
"x-api-key": process.env.REEF_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"company": "amazon.com",
"maxReviews": 40
}),
});
const { ok, data, meta, error } = await res.json();Ask your MCP-connected assistant: call reefapi.trustpilot.company/reviews with {"company":"amazon.com","maxReviews":40}.Who uses this API and why
- Support and reputation teams call company/reviews to monitor new reviews and TrustScore changes for their own domain.
- Market researchers use category/companies to benchmark every competitor's rating in a category.
- Review-aggregation platforms pull company/details to show a live TrustScore without maintaining a scraper.
Questions developers ask before integrating
Why does trust_score not match the average of rating_distribution?
Because TrustScore is a weighted score rather than an arithmetic mean. It gives more weight to recent reviews and to a company's review volume, so it lags the raw average when a company's older reviews were better. Measured: gossby.com's distribution averages 4.339 but its TrustScore is 4.2, and amazon.com's distribution averages 2.020 against a TrustScore of 1.6. If you want the unweighted average, compute it from rating_distribution yourself, since both numbers arrive in the same response.
What is the difference between trust_score and stars?
stars is trust_score rounded to the nearest half, and that is all it is. Measured across three companies: 4.2 became 4.0, 1.6 became 1.5, and 1.3 also became 1.5. So stars carries strictly less information, and two companies half a point apart can end up sharing the same star value. Sort and threshold on trust_score, and use stars only when you are rendering a star graphic.
Why does rating_distribution use words as keys?
Because that is Trustpilot's own shape, and we pass it through rather than renaming keys you may later want to match against their site. The object is {one, two, three, four, five, total}, so distribution["5"] is undefined and distribution.five is 28283. total is included, and it equalled number_of_reviews on every company measured (37662 for gossby.com), which makes it a cheap integrity check on your own ingestion.
is_verified is false but verification_level says "invited". What does that mean?
They answer different questions. verification_level describes where the review came from, and the measured values are "verified", "invited" and "not-verified", while is_verified is true only for the first of those. So an invited review is a real review the company solicited, not a verified purchase. The separate source field names the mechanism: "Organic" for someone who found the page themselves, "BasicLink" for an invitation link. Filtering with verified=true does work, returning only rows where is_verified is true and verification_level is "verified".
I asked for reviews and got fewer than the company has. Why?
The logged-out Trustpilot view serves 20 reviews per page across at most 10 pages, so 200 per view is the ceiling and a larger maxReviews will not break it. The response says so plainly: a measured call returned scraped_count 5 against total_reviews 37662, status "PARTIAL", completeness_pct 0.0 and a notes field reading "Limited by maxReviews=5; 37662 reviews exist. Raise maxReviews (up to 200) for more." Read status and notes instead of assuming the array you received is everything.
What is the difference between published_date and experience_date?
published_date is when the review was posted and carries a real time; experience_date is when the customer says the purchase or interaction happened and is date-only, so its time component is always 00:00:00. A measured review was published 2026-08-25T21:44:35.000Z about an experience dated 2026-08-24T00:00:00.000Z. Use published_date for recency and monitoring, and experience_date if you are correlating reviews against your own order dates. updated_date stays null unless the reviewer edited it.
Several profile fields came back null or empty. Which ones should I not count on?
On the three companies measured, rankings[] was empty on all of them, amazon.com and ryanair.com included, and description, ai_summary and every topics[].summary and topics[].sentiment came back null. topics[] itself was populated with 15 topic labels such as "Order" and "Delivery service", just without their summaries. Treat those fields as opportunistic: render them when they exist, and do not build a page section that breaks when they are null.
What does reply_behavior actually tell me?
How responsive the business is, with the negative-review case broken out separately, which is the number worth watching. A measured company returned reply_percentage 99.5495, average_days_to_reply 0.24, and negative_reviews_with_replies 221 out of total_negative_reviews 222, plus last_reply_to_negative as a "YYYY-MM-DD HH:MM:SS UTC" string. reply_percentage is an unrounded float, so round it at display time. It sits alongside verification{verified_payment_method, verified_user_identity, verified_by_google}, which are three independent booleans rather than one trust flag.
What is the Trustpilot API?
Trustpilot API is a ReefAPI endpoint group for company reviews, ratings and profiles. It returns live JSON through POST requests under /trustpilot/v1.
Is the Trustpilot API free to try?
Yes. ReefAPI starts with 1,000 free credits, no card required. Trustpilot calls use the same shared credit balance as every other ReefAPI engine.
Do I need a Trustpilot login or account?
No login to Trustpilot is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the Trustpilot data?
The page example is captured from a live company/reviews call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the Trustpilot API use?
Trustpilot actions currently cost 1 credit per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.
Can I call Trustpilot from an AI assistant or MCP client?
Yes. Connect ReefAPI once through MCP and your assistant can call trustpilot actions with the same key, credit pool and JSON envelope used by normal REST requests.