Get Product Reviews
Retrieve reviews and ratings for a specific product. By default only approved reviews are returned; pass the status parameter to fetch a different status.
Endpoint
GET /api/shop/products/{productId}/reviewsRequest Headers
| Header | Required | Description |
|---|---|---|
Content-Type | Yes | application/json |
X-STOREFRONT-KEY | Yes | Your storefront API key |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
productId | integer | Yes | Product ID |
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
status | string | approved | Filter by status (approved, pending). Omit to get approved reviews only. |
rating | integer | – | Filter by star rating (1–5). |
page | integer | 1 | Page number (1-based). |
per_page | integer | 30 | Reviews per page. Alias: limit. Maximum 50. |
Combining filters narrows the result — ?status=approved&rating=4 returns only four-star approved reviews. Sorting is not configurable; rows always come back oldest first, by ID.
A storefront product page shows approved reviews only, which is why status defaults to approved. Moderation or preview tooling has to ask for another status explicitly, one value per request.
Response (200 OK)
Returns a JSON array of review objects.
| Field | Type | Description |
|---|---|---|
id | integer | Review ID |
name | string | Reviewer display name |
title | string | Review title |
rating | integer | Rating (1–5 stars) |
comment | string | Review body |
status | string | Review status (approved, pending) |
createdAt | string | Review creation date (ISO 8601) |
updatedAt | string | Last update date (ISO 8601) |
Pagination
Pagination metadata is returned in response headers (not the body):
| Header | Description |
|---|---|
X-Total-Count | Total reviews matching the filters |
X-Page | Current page |
X-Per-Page | Reviews per page |
X-Total-Pages | Total page count |
Use Cases
- Review block on a product page — call with no parameters; the default already excludes anything unapproved, so nothing needs filtering client-side.
- Rating breakdown — the endpoint returns rows, not aggregates, so a "5 star (12)" histogram needs one call per rating with
?rating=n, readingX-Total-Countfrom each. - "Your review is awaiting approval" state — after a customer submits,
?status=pendingis the only way to show it back to them; it is absent from the default list.
Best Practices
- Read the count from
X-Total-Count— the body is one page, soarray.lengthunder-reports whenever a product has more than 30 reviews. - Raise the page size instead of looping —
per_pageaccepts up to 50 and silently caps there; a larger value does not error, it just returns 50. - Do not expect newest-first — the order is by ID ascending, so a "latest reviews" widget must request the last page or reverse the array itself.
- Ask for one status at a time —
statustakes a single value; a moderation queue showing both pending and approved needs two calls.
Related Resources
- Get Product Review — one review by id, whatever its status
- Create Product Review — submit a review; it starts as pending
- Get Product — one product's full detail with its relations inlined

