Reviews
Shoppers' product reviews: moderate them, reply in the shop's name, or delete them.
Reach them through $admin->reviews. Reading needs the reviews:read scope, changing them reviews:write. Reviews need a plan with reviews (403 plan_required).
List reviews
$admin->reviews->list(array $query = []): array
One page of the shop's reviews, newest first, or oldest change first with updatedSince. Read the next page with meta.nextCursor as cursor. Scope: reviews:read.
Parameters
| Parameter |
Type |
|
$query |
array |
The query fields below, by name. |
Query fields
| Parameter | Type | Description |
|---|
status | any | |
rating | integer | At least 1. At most 5. |
productId | integer | |
limit | integer | At least 1. At most 100. Default 50. |
cursor | string | meta.nextCursor (or the cursor in links.next) of the previous page. At most 1000 characters. |
updatedSince | string (date-time) | Records changed at or after this time (ISO 8601, any offset or Z), oldest change first, for incremental sync. |
Returns
An array with data (a list of AdminReview), links and meta:
| Field | Type | Description |
|---|
links | object | |
links.first | null | |
links.last | null | |
links.prev | string (uri) or null | |
links.next | string (uri) or null | |
meta | object | |
meta.path | string (uri) | |
meta.perPage | integer | |
meta.nextCursor | string or null | |
meta.prevCursor | string or null | |
data | array of AdminReview | |
data[].id | integer | |
data[].productId | integer or null | |
data[].customerId | integer or null | |
data[].orderId | integer or null | |
data[].rating | integer | At least 1. At most 5. |
data[].title | string or null | |
data[].body | string or null | |
data[].authorName | string or null | |
data[].verifiedBuyer | boolean | |
data[].locale | string or null | |
data[].status | string | One of pending_approval, published, rejected, flagged. |
data[].reply | object or null | |
data[].reply.body | string | |
data[].reply.updatedAt | string (date-time) or null | |
data[].publishedAt | string (date-time) or null | |
data[].createdAt | string (date-time) or null | |
data[].updatedAt | string (date-time) or null | |
Errors
| Status | When |
|---|
401 | invalid_api_key: no active Admin key in Authorization: Bearer. |
403 | admin_key_in_browser (an Origin header was sent), ip_not_allowed, plan_required(the shop's plan lacks the Integration API, or the feature the endpoint needs), orinsufficient_scope. |
422 | Validation errors ({ message, errors }), or an idempotency refusal(idempotency_key_reused, idempotency_key_invalid). |
429 | Rate limited. |
Example
$page = $admin->reviews->list(['rating' => 1, 'productId' => 12]);
Iterate over every review
$admin->reviews->all(array $query = []): Generator
Every review matching the query, one at a time, fetching the next page as you read. It takes the same query as list, without cursor. Scope: reviews:read.
Returns
A generator of AdminReview arrays, each:
| Field | Type | Description |
|---|
[].id | integer | |
[].productId | integer or null | |
[].customerId | integer or null | |
[].orderId | integer or null | |
[].rating | integer | At least 1. At most 5. |
[].title | string or null | |
[].body | string or null | |
[].authorName | string or null | |
[].verifiedBuyer | boolean | |
[].locale | string or null | |
[].status | string | One of pending_approval, published, rejected, flagged. |
[].reply | object or null | |
[].reply.body | string | |
[].reply.updatedAt | string (date-time) or null | |
[].publishedAt | string (date-time) or null | |
[].createdAt | string (date-time) or null | |
[].updatedAt | string (date-time) or null | |
Example
foreach ($admin->reviews->all(['status' => 'pending_approval']) as $review) {
$admin->reviews->setStatus($review['id'], 'published');
$admin->reviews->reply($review['id'], 'Thank you for your review!');
}
Get a review
$admin->reviews->get(int $id): array
One review by its id, with the shop's reply. Scope: reviews:read.
Parameters
| Parameter |
Type |
|
$id |
int |
The review's id. |
Returns
An AdminReview:
| Field | Type | Description |
|---|
id | integer | |
productId | integer or null | |
customerId | integer or null | |
orderId | integer or null | |
rating | integer | At least 1. At most 5. |
title | string or null | |
body | string or null | |
authorName | string or null | |
verifiedBuyer | boolean | |
locale | string or null | |
status | string | One of pending_approval, published, rejected, flagged. |
reply | object or null | |
reply.body | string | |
reply.updatedAt | string (date-time) or null | |
publishedAt | string (date-time) or null | |
createdAt | string (date-time) or null | |
updatedAt | string (date-time) or null | |
Errors
| Status | When |
|---|
401 | invalid_api_key: no active Admin key in Authorization: Bearer. |
403 | admin_key_in_browser (an Origin header was sent), ip_not_allowed, plan_required(the shop's plan lacks the Integration API, or the feature the endpoint needs), orinsufficient_scope. |
404 | not_found: the shop has no such record. |
429 | Rate limited. |
Moderate a review
$admin->reviews->setStatus(int $id, string $status, string|false|null $idempotencyKey = null): array
Publishes, rejects, flags or holds a review; the product's rating follows. Scope: reviews:write.
Parameters
| Parameter |
Type |
|
$id |
int |
The review's id. |
$status |
string |
pending_approval, published, rejected or flagged. |
$idempotencyKey |
string|false|null |
Your own Idempotency-Key, or false for none. One is made for you when null. |
Returns
The moderated AdminReview:
| Field | Type | Description |
|---|
id | integer | |
productId | integer or null | |
customerId | integer or null | |
orderId | integer or null | |
rating | integer | At least 1. At most 5. |
title | string or null | |
body | string or null | |
authorName | string or null | |
verifiedBuyer | boolean | |
locale | string or null | |
status | string | One of pending_approval, published, rejected, flagged. |
reply | object or null | |
reply.body | string | |
reply.updatedAt | string (date-time) or null | |
publishedAt | string (date-time) or null | |
createdAt | string (date-time) or null | |
updatedAt | string (date-time) or null | |
Errors
| Status | When |
|---|
401 | invalid_api_key: no active Admin key in Authorization: Bearer. |
403 | admin_key_in_browser (an Origin header was sent), ip_not_allowed, plan_required(the shop's plan lacks the Integration API, or the feature the endpoint needs), orinsufficient_scope. |
404 | not_found: the shop has no such record. |
409 | idempotency_in_progress: a request with this Idempotency-Key is still running. Retry with the same key after Retry-After seconds; the first answer is then replayed. |
422 | Validation errors ({ message, errors }), or an idempotency refusal(idempotency_key_reused, idempotency_key_invalid). |
429 | Rate limited. |
Example
$admin->reviews->setStatus(41, 'rejected');
Reply to a review
$admin->reviews->reply(int $id, string $body, string|false|null $idempotencyKey = null): array
Writes or rewrites the shop's public reply. It also touches the review's updatedAt. Scope: reviews:write.
Parameters
| Parameter |
Type |
|
$id |
int |
The review's id. |
$body |
string |
The reply, at most the platform's review body length. |
$idempotencyKey |
string|false|null |
Your own Idempotency-Key, or false for none. One is made for you when null. |
Returns
The AdminReview, with its reply:
| Field | Type | Description |
|---|
id | integer | |
productId | integer or null | |
customerId | integer or null | |
orderId | integer or null | |
rating | integer | At least 1. At most 5. |
title | string or null | |
body | string or null | |
authorName | string or null | |
verifiedBuyer | boolean | |
locale | string or null | |
status | string | One of pending_approval, published, rejected, flagged. |
reply | object or null | |
reply.body | string | |
reply.updatedAt | string (date-time) or null | |
publishedAt | string (date-time) or null | |
createdAt | string (date-time) or null | |
updatedAt | string (date-time) or null | |
Errors
| Status | When |
|---|
401 | invalid_api_key: no active Admin key in Authorization: Bearer. |
403 | admin_key_in_browser (an Origin header was sent), ip_not_allowed, plan_required(the shop's plan lacks the Integration API, or the feature the endpoint needs), orinsufficient_scope. |
404 | not_found: the shop has no such record. |
409 | idempotency_in_progress: a request with this Idempotency-Key is still running. Retry with the same key after Retry-After seconds; the first answer is then replayed. |
422 | Validation errors ({ message, errors }), or an idempotency refusal(idempotency_key_reused, idempotency_key_invalid). |
429 | Rate limited. |
Example
$admin->reviews->reply(41, 'Sorry to hear that. We have sent you a replacement.');
Delete the shop's reply
$admin->reviews->deleteReply(int $id): array
Removes the shop's reply and answers with the review. Scope: reviews:write.
Parameters
| Parameter |
Type |
|
$id |
int |
The review's id. |
Returns
The AdminReview, without a reply:
| Field | Type | Description |
|---|
id | integer | |
productId | integer or null | |
customerId | integer or null | |
orderId | integer or null | |
rating | integer | At least 1. At most 5. |
title | string or null | |
body | string or null | |
authorName | string or null | |
verifiedBuyer | boolean | |
locale | string or null | |
status | string | One of pending_approval, published, rejected, flagged. |
reply | object or null | |
reply.body | string | |
reply.updatedAt | string (date-time) or null | |
publishedAt | string (date-time) or null | |
createdAt | string (date-time) or null | |
updatedAt | string (date-time) or null | |
Errors
| Status | When |
|---|
401 | invalid_api_key: no active Admin key in Authorization: Bearer. |
403 | admin_key_in_browser (an Origin header was sent), ip_not_allowed, plan_required(the shop's plan lacks the Integration API, or the feature the endpoint needs), orinsufficient_scope. |
404 | not_found: the shop has no such record. |
409 | idempotency_in_progress: a request with this Idempotency-Key is still running. Retry with the same key after Retry-After seconds; the first answer is then replayed. |
422 | Validation errors ({ message, errors }), or an idempotency refusal(idempotency_key_reused, idempotency_key_invalid). |
429 | Rate limited. |
Delete a review
$admin->reviews->delete(int $id): void
Deletes the review for good, with its reply. Scope: reviews:write.
Parameters
| Parameter |
Type |
|
$id |
int |
The review's id. |
Returns
Nothing.
Errors
| Status | When |
|---|
401 | invalid_api_key: no active Admin key in Authorization: Bearer. |
403 | admin_key_in_browser (an Origin header was sent), ip_not_allowed, plan_required(the shop's plan lacks the Integration API, or the feature the endpoint needs), orinsufficient_scope. |
404 | not_found: the shop has no such record. |
409 | idempotency_in_progress: a request with this Idempotency-Key is still running. Retry with the same key after Retry-After seconds; the first answer is then replayed. |
422 | Validation errors ({ message, errors }), or an idempotency refusal(idempotency_key_reused, idempotency_key_invalid). |
429 | Rate limited. |