Trustpilot API Documentation

RESTful API for accessing Trustpilot product review data

Authentication

API Secret: All public endpoints require {api-secret} in the URL path.

Access: Endpoints are publicly reachable from any whitelisted CORS origin.

Endpoints

Pick an endpoint to view its full reference. Only one section is shown at a time.

Notes

  • API Secret: Only the configured {api-secret} is accepted; otherwise the endpoint returns 403.
  • Rate limiting: Per-IP. v3 batch: 30/min. Business Unit: 60/min.
  • Data freshness: v3 fetches in real time. Business Unit responses are cached server-side for 5 minutes.
  • CORS: Your frontend origin must be in the server's allowed_origins list.
← Back to overview
POST

Product Reviews

v3 - Stable

Endpoint URL

POST /api/v3/trustpilot/product-reviews/{api-secret}/batch-summaries/

Description

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.

Performance

  • Single API call per batch (vs N for legacy v2)
  • 1000+ SKUs/second processing rate
  • Sub-second response times for typical batches
  • Automatic SKU deduplication across products

Request Body

Content-Type: application/json

Validation rules:

  • Maximum 100 products per request
  • Each product must have an id (non-empty string) and skus (array)
  • Maximum 50 SKUs per product
  • SKUs must be non-empty strings of alphanumerics, hyphens, underscores, dots
{
  "products": [
    {
      "id": "426547893629",
      "skus": ["42397086548162", "42397086580930", "42397086613698"]
    },
    {
      "id": "246547893623",
      "skus": ["42397086548163"]
    }
  ]
}

Query Parameters

private (optional): Use private API with authentication.
Default: false
format (optional): Response shape.
Values: "array" (default), "hash"
Note: Use "hash" for O(1) lookups in Shopify-style frontends.

Response Formats

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 }
  }
}

Response Codes

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 Example

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"] }
    ]
  }'

Validation Error Examples

{"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"}
← Back to overview
GET

Business Unit Summary

New

Endpoint URL

GET /api/v3/trustpilot/business-unit/{api-secret}/

Description

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, Rate limit & Caching

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.

Query Parameters (exactly one required)

domain (string): Bare hostname of the business website.
Example: example.com
Note: No scheme, port, or path.
business_unit_id (string): Trustpilot business unit ID.
Format: 8–64 alphanumeric characters.
Example: 507f1f77bcf86cd799439011

Success Response (200)

{
  "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.

Response Codes

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

cURL Examples

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"

Frontend Client Snippet (vanilla JS)

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", "");
  });

Implementation Tips

  • Pick one lookup key. Use 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.
  • Render server-side when possible. The response is small and cached - call it from your backend or build pipeline rather than from every visitor's browser when you can.
  • Handle null fields. trustScore, stars, and numberOfReviews may be null for a brand-new business unit with no reviews yet.
  • Retry only on 502. 4xx responses are deterministic; do not loop on them.
← Back to overview

Deprecated endpoints - Sunset on 2026-10-23

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

Product Reviews (v1)

Deprecated

Endpoint URL

GET /api/v1/trustpilot/product-reviews/{api-secret}/?sku=SKU1,SKU2

Migration

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

Product Reviews (v2)

Deprecated

Endpoint URL

POST /api/v2/trustpilot/product-reviews/{api-secret}/batch-summaries/

Migration

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/