Skip to content

Update Product Review

About

The updateProductReview mutation edits an existing review in place. Use it to:

  • Correct the title or comment of a review a shopper has already submitted
  • Change the rating when the shopper reassesses the product
  • Fix the reviewer name shown on the review
  • Attach further images or video to an existing review

Every field except the review's id is optional, and omitted fields keep their current value. The mutation returns the review as it stands after the update.

A review can only be edited by the customer who wrote it. Send that customer's Bearer token — an unauthenticated request, a different customer's token, or a review submitted by a guest is refused.

Arguments

ArgumentTypeRequiredDescription
idID!✅ YesIdentifies the review. Accepts the IRI form (/api/shop/reviews/1) or a plain numeric ID.
productIdInt❌ NoMoves the review to a different product. The product must exist. Rarely useful — omit it on a normal edit.
titleString❌ NoNew review headline.
commentString❌ NoNew review body text.
ratingInt❌ NoNew star rating. Must be 1 to 5.
nameString❌ NoNew reviewer display name.
emailString❌ NoAccepted by the schema but not stored on the review.
statusInt❌ NoLeave unset — see Review Status.
clientMutationIdString❌ NoArbitrary string echoed back in the payload.

Only the fields you send are written. Sending title alone changes the title and leaves the rating, comment, and name untouched.

Possible Returns

FieldTypeDescription
productReviewupdateProductReviewPayloadDataThe review after the update.
productReview.idID!IRI-style review identifier.
productReview._idIntNumeric review ID.
productReview.nameStringReviewer's name.
productReview.titleStringReview title.
productReview.ratingIntStar rating, 1 to 5.
productReview.commentStringReview body text.
productReview.statusStringApproval status — "pending", "approved", or "disapproved".
productReview.attachmentsStringJSON string of the stored attachments, each with a type and a url.
productReview.createdAtStringISO 8601 timestamp of when the review was submitted.
productReview.updatedAtStringISO 8601 timestamp of this update.
clientMutationIdStringThe clientMutationId sent with the request, echoed back.

Review Status

A review's status is one of three strings:

StatusDescription
"pending"Awaiting moderation. Not shown on the storefront.
"approved"Published and visible on the product page.
"disapproved"Declined and never published.

The status input takes an integer and is written to the review unchanged, so it cannot produce any of those three values — a review updated with status: 1 ends up holding 1, which no status filter matches and no storefront page displays. Approving or declining a review is an admin action; leave this field unset.

Identifying the Review

The id argument accepts either form — the trailing number is what identifies the review:

ValueResult
"/api/shop/reviews/92"Resolves to review 92
"92"Resolves to review 92
"reviews/92"Resolves to review 92
"abc"Resolves to review 0, which does not exist, so the mutation fails

Prefer the IRI form: it is what the query and create responses hand back, so it round-trips without conversion.

Use Cases

1. Letting a shopper edit their own review

Send only the fields the edit form changed. Everything else on the review is left as it was.

graphql
mutation editReview($input: updateProductReviewInput!) {
  updateProductReview(input: $input) {
    productReview {
      _id
      title
      comment
      rating
      status
      updatedAt
    }
  }
}
json
{
  "input": {
    "id": "/api/shop/reviews/74",
    "comment": "Updated after a month of use — the fabric still looks new.",
    "rating": 4
  }
}

2. Re-checking the review after an edit

The response carries the review's current status. An approved review that is edited keeps whatever status it held, so read the field back rather than assuming the edit sent it for re-moderation.

Best Practices

  1. Send only the fields being changed — omitted fields keep their stored value, so a partial input is the normal case rather than an optimisation
  2. Use the IRI form of id — a numeric ID also resolves, but the IRI is what the query and create responses return, so it round-trips without conversion
  3. Never send status — the field takes an integer that cannot map to pending, approved, or disapproved, and writing it leaves the review in a state no query matches
  4. Leave productId out — it exists to move a review to a different product, which is not something an edit form should do by accident
  5. Attach media at creation time — this mutation takes no attachments field, so images and video can only be sent with Create Product Review
  6. Read updatedAt back — it confirms the write landed, since a partial update that changed nothing returns the same values it was sent

Error Scenarios

ScenarioCause
Missing IDThe id field was omitted from input. GraphQL rejects the document before the mutation runs.
Review not foundThe ID resolves to a review that does not exist.
Not signed inNo customer Bearer token was sent, so ownership cannot be established.
Not your reviewThe review belongs to another customer, or was submitted by a guest and has no owner.
Rating out of rangerating was sent below 1 or above 5.
Product not foundproductId was sent and no product has that ID.
Invalid attachmentA data URI is malformed, its Base64 will not decode, or a decoded file exceeds 5 MB.

Released under the MIT License.