Queries
productReviews
List public reviews with cursor pagination, search, rating, and sorting.
Last updated:
productReviews returns published reviews for a visible product. Use nextCursor to continue without building offsets or interpreting the cursor.
Signature
productReviews(
productId: String!
limit: Int
cursor: String
search: String
sortBy: String
sortDirection: SortDirection
rating: Int
): CursorPaginatedItemsOfStorefrontReviewDto!Arguments
| Argument | Default | Rules |
|---|---|---|
productId | — | Required. Valid opaque public ID. |
limit | 20 | Between 1 and 200. |
cursor | null | Opaque cursor returned by the previous page; at most 2000 characters. |
search | null | Free text up to 200 characters. |
sortBy | null | createdOn or rating, case-insensitive. |
sortDirection | Field-dependent | ASC or DESC. It only applies when sorting by rating; createdOn always uses DESC. |
rating | null | Integer from 1 through 5. |
Return value
| Field | Type | Description |
|---|---|---|
data | [StorefrontReviewDto!]! | Reviews in the current page. |
hasNextPage | Boolean! | Whether another page exists. |
nextCursor | String | Opaque cursor for the next query. |
totalCount | Long | Total reviews matching the filters, when available. |
Each review exposes id: String!, productId: String!, isVerifiedPurchase: Boolean!, rating: Int!, title: String, content: String!, reviewerName: String, and createdOn: DateTime!.
Query
query ProductReviews(
$productId: String!
$limit: Int
$cursor: String
$rating: Int
) {
productReviews(
productId: $productId
limit: $limit
cursor: $cursor
rating: $rating
sortBy: "createdOn"
) {
data {
id
productId
isVerifiedPurchase
rating
title
content
reviewerName
createdOn
}
hasNextPage
nextCursor
totalCount
}
}{
"productId": "456",
"limit": 20,
"cursor": null,
"rating": 5
}cURL
curl --request POST "https://storefront.ecomiq.pe/graphql" \
--header "Content-Type: application/json" \
--header "x-Store-Domain: my-store" \
--data-binary '{
"query": "query ProductReviews($productId: String!, $limit: Int, $cursor: String, $rating: Int) { productReviews(productId: $productId, limit: $limit, cursor: $cursor, rating: $rating, sortBy: \"createdOn\") { data { id productId isVerifiedPurchase rating title content reviewerName createdOn } hasNextPage nextCursor totalCount } }",
"variables": {
"productId": "456",
"limit": 20,
"cursor": null,
"rating": 5
}
}'Response
{
"data": {
"productReviews": {
"data": [
{
"id": "review-1",
"productId": "456",
"isVerifiedPurchase": true,
"rating": 5,
"title": "Excellent",
"content": "Useful review",
"reviewerName": "Ana",
"createdOn": "2026-08-25T15:30:00Z"
}
],
"hasNextPage": true,
"nextCursor": "eyJpZCI6InJldmlldy0xIn0=",
"totalCount": 31
}
}
}On the next request, send nextCursor without decoding or modifying it. When hasNextPage is false, nextCursor is null.
Errors
| Code | When it occurs |
|---|---|
BAD_USER_INPUT | The ID, limit, cursor, search, sort, or rating violates the contract. |
STORE_CONTEXT_REQUIRED | x-Store-Domain cannot resolve a store. |