Review actions

Upload review media, submit product reviews, and vote with merchant policy enforced.

POST /reviews/media
{% form 'review_media_upload' %}

Multipart; one image per request, repeat for more. Pending uploads expire unclaimed.

Form fields

file Required

One image per request (multipart). Returns a media id to pass in review_media_ids.

Validation

Multipart with a file field containing JPEG or PNG; visitor identity is required. The image is virus-scanned, decoded, dimension-checked, re-encoded as JPEG, and metadata is removed. Only the uploader may claim the returned media id.

Limits

8 MiB input; 4096 px maximum dimension; 10 uploads/minute per visitor; 10 pending per uploader; 200 MiB pending per store; unclaimed uploads expire after 2 hours.

Response

{
  media_id,
  width,
  height,
  size_bytes,
  expires_at
}

errors use the public review-media error envelope.

POST /reviews/submit
{% form 'review_submit' %}

Gated by review settings (guest reviews, require purchase, moderation).

Form fields

product_id Required

Product being reviewed.

variant_id Optional

Specific product variant being reviewed.

rating Required

1–5.

content Required

Review body. Length bounds are merchant review settings — read them from ctx.forms.review.content.

title Optional

Optional review heading.

reviewer_name Optional

Display name; defaults to the customer's name when logged in.

reviewer_email Optional

Optional contact email; validated when supplied.

review_media_ids Optional

Comma-separated ids from review_media_upload.

Validation

Positive product and optional variant belonging to it; rating 1–5; review policy, reviewer name, optional reviewer email, verified-purchase requirement, customer duplicate prevention, moderation, blocked content, and uploaded-media ownership are enforced.

Limits

Merchant content minimum 10–100 characters, content maximum 500–5000, and max_images 0–5; title 200, reviewer name 100, reviewer email 255.

Response

{
  success:true,
  response,
  review_id,
  review_status
}

review_status is approved, pending, or rejected according to policy.

POST /reviews/vote
{% form 'review_vote' %}

One vote per session per review.

Form fields

review_id Required

Review being voted on.

vote Optional

helpful or unhelpful; required unless remove is true.

remove Optional

true removes the visitor's existing vote.

Validation

Existing visible review; vote is helpful or unhelpful unless remove=true. One current vote per visitor session and review.

Limits

One vote state per visitor/review; repeated writes update or remove that state.

Response

{
  success:true,
  response,
  helpful_count,
  unhelpful_count
}

User error codes#

Code

When

STORE_REVIEW_PRODUCT_REQUIRED

product_id missing — reviews always target a product.

STORE_REVIEW_RATING_RANGE

rating outside 1–5.

STORE_REVIEW_CONTENT_TOO_SHORT / _TOO_LONG

Length limits from the store's review settings — params carry min/max.

STORE_REVIEW_TITLE_TOO_LONG

Title over the limit.

STORE_REVIEW_REVIEWER_NAME_REQUIRED

Anonymous submit without reviewer_name.

STORE_REVIEW_PURCHASE_REQUIRED

The store requires a purchase and this customer has none for the product.

STORE_REVIEW_DUPLICATE_PRODUCT

This visitor already reviewed the product.

STORE_REVIEW_IMAGES_NOT_ALLOWED / _LIMIT / _INVALID

Photos off, over the store's max, or media_ids that aren't yours / already claimed / expired.

STORE_REVIEW_VOTE_INVALID

vote is not helpful/unhelpful.