RESTful API for accessing Trustpilot product review data
API Secret: All public endpoints require {api-secret} in the URL path.
Access: Endpoints are publicly reachable from any whitelisted CORS origin.
Pick an endpoint to view its full reference. Only one section is shown at a time.
Method: POST
Purpose: Batch SKU - review summary lookups
Best for: Product pages, catalog sync, bulk widgets
Rate limit: 30 requests/minute
Method: GET
Purpose: Company-level TrustScore and total review count
Best for: Trustpilot badge, homepage trust signals, footers
Rate limit: 60 requests/minute (cached 5 min)
Affected: v1 GET, v2 POST product-reviews endpoints
Status: Still reachable, but emit RFC 8594 deprecation headers
Action: Migrate to v3 before sunset
{api-secret} is accepted; otherwise the endpoint returns 403.allowed_origins list.POST /api/v3/trustpilot/product-reviews/{api-secret}/batch-summaries/
Batch endpoint that maps a list of products (each with one or more SKUs) to a review summary (average_stars, total_reviews) per product. A single upstream Trustpilot call services the whole batch, with deduplication and per-product rollup performed server-side.
Content-Type: application/json
Validation rules:
id (non-empty string) and skus (array){
"products": [
{
"id": "426547893629",
"skus": ["42397086548162", "42397086580930", "42397086613698"]
},
{
"id": "246547893623",
"skus": ["42397086548163"]
}
]
}
Array format (default), with performance metrics:
{
"reviews": [
{ "product_id": "426547893629", "average_stars": 4.8, "total_reviews": 153 },
{ "product_id": "246547893623", "average_stars": 4.2, "total_reviews": 45 }
],
"performance": {
"api_calls_made": 1,
"processing_time_ms": 120,
"total_skus_processed": 4,
"skus_per_second": 33.33,
"average_skus_per_api_call": 4.0
}
}
Hash format (?format=hash):
{
"reviews": {
"426547893629": { "average_stars": 4.8, "total_reviews": 153 },
"246547893623": { "average_stars": 4.2, "total_reviews": 45 }
}
}
200 Success - Reviews retrieved successfully
400 Bad Request - Invalid or missing JSON payload, validation errors
403 Forbidden - Invalid {api-secret}
401 Unauthorized - Authentication error (private API)
500 Internal Server Error
curl -X POST "https://your-domain/api/v3/trustpilot/product-reviews/{api-secret}/batch-summaries/" \
-H "Content-Type: application/json" \
-d '{
"products": [
{ "id": "426547893629", "skus": ["42397086548162", "42397086580930"] }
]
}'
{"error": "Missing 'products' field in payload"}
{"error": "'products' array cannot be empty"}
{"error": "'products' array cannot contain more than 100 items"}
{"error": "Product at index 0 missing required 'skus' field"}
{"error": "Product at index 0 'skus' cannot contain more than 50 SKUs"}
{"error": "Product at index 0, SKU at index 1 contains invalid characters"}
GET /api/v3/trustpilot/business-unit/{api-secret}/
Returns the company-level TrustScore, star rating, and total review count for a single business unit. Designed for embeddable "Trustpilot badge" widgets, homepage trust signals, and footer ratings - anything that needs the headline company score rather than per-product reviews.
Auth: {api-secret} in the URL path.
Rate limit: 60 requests / minute / IP.
Caching: Successful responses are cached server-side for 5 minutes (configurable via TRUSTPILOT_BU_CACHE_TTL), keyed on the full query string. Errors and 403 responses are not cached.
example.com
507f1f77bcf86cd799439011
{
"id": "507f1f77bcf86cd799439011",
"displayName": "Example Co.",
"websiteUrl": "https://example.com",
"trustScore": 4.6,
"stars": 5,
"numberOfReviews": 12345
}
Field reference:
id (string) - Trustpilot business unit ID. Cache client-side for faster ID-based lookups later.displayName (string) - Human-readable company name as shown on Trustpilot.websiteUrl (string | null) - Canonical company URL registered on Trustpilot.trustScore (number | null) - TrustScore on a 0.0–5.0 scale (e.g. 4.6).stars (integer | null) - Rounded star rating, 1–5.numberOfReviews (integer | null) - Total number of reviews aggregated by Trustpilot.200 Success - Summary retrieved successfully
400 Bad Request - Missing/invalid domain and business_unit_id, or both supplied at once
401 Unauthorized - Trustpilot rejected our API key (server-side misconfiguration)
403 Forbidden - {api-secret} does not match the configured value
502 Bad Gateway - Network/transport error talking to Trustpilot. Safe to retry with exponential backoff
500 Internal Server Error - Unexpected server error
By domain:
curl "https://your-domain/api/v3/trustpilot/business-unit/{api-secret}/?domain=example.com"
By business unit ID:
curl "https://your-domain/api/v3/trustpilot/business-unit/{api-secret}/?business_unit_id=507f1f77bcf86cd799439011"
Drop-in fetch() example for rendering a Trustpilot badge. The endpoint is already cached server-side, so you do not need to add client-side caching unless you want to survive network drops.
const API_BASE = "https://your-domain/api/v3/trustpilot/business-unit";
const API_SECRET = "<your-api-secret>";
const DOMAIN = "example.com";
async function loadTrustpilotSummary() {
const url = `${API_BASE}/${API_SECRET}/?domain=${encodeURIComponent(DOMAIN)}`;
const res = await fetch(url, { headers: { "Accept": "application/json" } });
if (!res.ok) {
throw new Error(`Trustpilot summary failed: HTTP ${res.status}`);
}
return res.json();
// returns { id, displayName, websiteUrl, trustScore, stars, numberOfReviews }
}
loadTrustpilotSummary()
.then(({ trustScore, stars, numberOfReviews, displayName }) => {
document.querySelector("#tp-score").textContent = trustScore?.toFixed(1) ?? "-";
document.querySelector("#tp-stars").dataset.stars = stars ?? 0;
document.querySelector("#tp-count").textContent =
new Intl.NumberFormat().format(numberOfReviews ?? 0);
document.querySelector("#tp-name").textContent = displayName;
})
.catch(err => {
console.error(err);
document.querySelector("#tp-badge")?.setAttribute("hidden", "");
});
domain for the common case; cache the returned id in your CMS or build artifact and switch to business_unit_id later for slightly faster upstream lookups.null fields. trustScore, stars, and numberOfReviews may be null for a brand-new business unit with no reviews yet.The legacy v1 and v2 endpoints remain reachable but are deprecated. New integrations must use v3. Existing integrations should migrate before the sunset date.
Every response from the legacy endpoints carries the following standard headers (RFC 8594):
Deprecation: true
Sunset: Fri, 23 Oct 2026 23:59:59 GMT
Link: </api/v3/trustpilot/product-reviews/{api-secret}/batch-summaries/>; rel="successor-version"
GET /api/v1/trustpilot/product-reviews/{api-secret}/?sku=SKU1,SKU2
Use v3 with a single product wrapping your SKU list:
{ "products": [ { "id": "your-product-id", "skus": ["SKU1", "SKU2"] } ] }
POST it to /api/v3/trustpilot/product-reviews/{api-secret}/batch-summaries/ and read the first entry of reviews[].
POST /api/v2/trustpilot/product-reviews/{api-secret}/batch-summaries/
v3 is a drop-in replacement: identical request body, identical response shape (with an extra performance block). Only the URL changes:
- POST /api/v2/trustpilot/product-reviews/{api-secret}/batch-summaries/
+ POST /api/v3/trustpilot/product-reviews/{api-secret}/batch-summaries/