/reviews/media/intents
JavaScript workflow exposed as tringify.reviews.uploadMedia(file). The image bytes upload directly to the signed storage request; they do not pass through the storefront server.
Request fields
-
original_filenameRequired Original image filename.
-
mime_typeRequired image/jpeg or image/png.
-
size_bytesRequired Image size in bytes.
Validation
The intent request requires a filename, JPEG or PNG MIME type, declared byte size, a visitor session, and the current CSRF token. The browser uploads the image to the returned signed request, then the bridge finalizes and polls it. The image is virus-scanned, decoded, dimension-checked, re-encoded as JPEG, and stripped of metadata. 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
{
success,
data
}
the intent endpoint returns the signed request. tringify.reviews.uploadMedia(file) completes the workflow and resolves {success: true, media_id, width, height, size_bytes, expires_at}. It never rejects: a refused or failed upload resolves {success: false, message, user_errors, status_code}, where message is the store's reason (for example STOREFRONT_REVIEW_LOGIN_REQUIRED when a signed-out visitor may not review) and is empty when there is none. Show message, or your own fallback when it is empty.
/reviews/submit
{% form 'review_submit' %}
Gated by review settings (guest reviews, require purchase, moderation). When ctx.forms.review.guests_allowed is false, a signed-out visitor is refused: show a sign-in link instead of the form. When ctx.forms.review.purchase_required is true, only a signed-in customer who bought the product, or a shopper opening a review request from an order, can post; signed-out visitors are refused even when guests_allowed is true. Tell visitors before they write.
Form fields
-
product_idRequired Product being reviewed.
-
variant_idOptional Specific product variant being reviewed.
-
ratingRequired 1–5.
-
contentRequired Review body. Length bounds are merchant review settings — read them from ctx.forms.review.content.
-
titleOptional Optional review heading.
-
reviewer_nameOptional Display name; defaults to the customer's name when logged in.
-
reviewer_emailOptional Optional contact email; validated when supplied.
-
review_media_idsOptional Comma-separated ids from review_media_upload.
Validation
Positive product and optional variant belonging to it; rating 1–5; reviewer name and optional reviewer email. Current submission and moderation settings are enforced at save, including purchase requirements, content limits, blocked content and photo limits. A private order invitation authenticates the purchased product, including for a guest. Uploaded media must belong to the same visitor and store, be unexpired and unclaimed, and contain no duplicate IDs. Photos are saved in review_media_ids order; the review and all photo attachments save together.
Limits
Merchant content minimum 10–100 characters, content maximum 500–5000, and up to max_images photos (1–5, or none when photos are off); title 200, reviewer name 100, reviewer email 255.
Response
{
success:true,
response,
review_id,
review_status
}
review_status is approved or pending according to moderation settings. Submissions the content filters refuse are not saved and return an error instead.
/reviews/vote
{% form 'review_vote' %}
One vote per session per review.
Form fields
-
review_idRequired Review being voted on.
-
voteOptional helpful or unhelpful; required unless remove is true.
-
removeOptional 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. |
STOREFRONT_REVIEW_LOGIN_REQUIRED |
A signed-out visitor on a store that does not take guest reviews, from the submit and the photo upload. Read ctx.forms.review.guests_allowed and show a sign-in link instead of the form when it is false. A visitor with a review invitation from their order can still review. |