Importing and exporting reviews

Bringing an existing catalog of reviews across from Yotpo, Judge.me, Okendo, Stamped or Loox is a CSV upload, and their export files work as they come. Open Reviews, choose Import from the actions menu, pick your file, and set Format to the platform you are leaving. The import runs in the background, so you can leave the page. Progress and any problems show up under Settings, Imports.

Each platform's column mapping is in Migrating from a named platform below. Leave Format on Cascade if you have already reshaped the file into the columns in the next section.

Export works the same way in reverse: choose Export and the finished CSV appears under Settings, Exports. It uses the columns below, so an export can be edited and imported straight back in.

Before you start

Reviews are attached to products that already exist in Cascade, matched by product slug. Import your products first, otherwise every review will be skipped for want of something to attach to. Customers are matched by email address, and one the import has never seen is created from the email, so a customers import is optional. Import customers first anyway if you want names and other details on the new records.

Columns

ColumnRequiredDescription
customerYesEmail address of the reviewer. A customer Cascade has never seen is created from the email.
productYes*Slug of the product being reviewed. It must already exist. On Shopify this is the product handle.
ratingYesWhole number from 1 to 5. A decimal is rounded to the nearest star.
titleNoThe review's headline.
bodyNoThe review's text.
externalIdNoThe review's ID in the system you are migrating from. See Running it twice.
productExternalIdNoThe product's ID in your old platform. See Finding the product.
productUrlNoThe product's page URL on your storefront. See Finding the product.
siteNoSlug of the site the review belongs to. Leave it out and the product's own site is used.
productVariantNoSlug of the variant being reviewed, if the reviewer named one.
publishedNotrue or false. Defaults to true. See Moderation.
hiddenNotrue or false, the opposite of published. For platforms that export the flag that way round.
moderationStatusNoThe moderation word your old platform used, such as published, pending or spam. See Moderation.
verifiedBuyerNotrue or false. Defaults to false. Shows the Verified buyer badge on the review in the reviews widget.
orderReferenceNoThe order the review came from. Any row with one counts as a verified buyer. See Verified buyers.
responseNoYour store's reply to the review. See Merchant replies.
responderNameNoThe name shown above the reply. Defaults to your organization's name.
responseCreatedAtNoWhen the reply was written. Without it the reply is dated from the import.
createdAtNoWhen the review was originally written, for example 2023-04-11T09:15:00Z. Without it the review is dated from the import.
imageUrlsNoComma-separated URLs of the review's photos and videos. See Photos and videos.
metadataNoA JSON object of your own string key/value pairs.
question:<label>NoOne column per review question. See Review questions.

* A row needs one of product, productExternalId or productUrl. product is the one to use unless you are importing an export that has no handle in it.

A minimal file needs three columns:

customer,product,rating
[email protected],running-shoes,5
[email protected],coffee-mug,2

Finding the product

Cascade attaches a review to a product it already holds, and it looks for that product in three ways, in this order:

  1. product, matched against the product's slug. On Shopify the slug is the product handle, so a competitor export carrying handles lines up with no work.
  2. productExternalId, matched against the Shopify product ID your connected store recorded on the product. Either the numeric form (7788) or the gid:// form works. This only resolves when the store is connected, because the connector is what wrote those IDs down.
  3. productUrl, whose last path segment is read as a slug. So https://example.com/products/running-shoes finds running-shoes.

Yotpo, Okendo and Stamped export a numeric product ID rather than a handle, which is why the second and third rows exist. If you are on a custom storefront with no Shopify connection, the URL is what saves you, provided the last part of it matches your product slugs. Where it does not, add a product column in a spreadsheet before you upload.

A row that matches nothing is skipped and the job says which identifiers it tried.

Moderation

Imported reviews arrive already moderated, so they never land in the moderation queue. A migration of several thousand historical reviews would otherwise bury the handful that genuinely need a decision.

By default they go straight onto the storefront. Set published to false on any review you want kept off it. Either way the review counts as decided, so it shows up under Published or Rejected rather than Needs review.

moderationStatus takes the word your old platform used instead of a flag, so an export can be uploaded without editing. published, approved, live, visible, ok and public publish the review; unpublished, pending, hidden, rejected, draft and private keep it off the storefront; unknown and an empty cell mean the file has no opinion and the review is published.

Spam is not imported at all. A row whose moderation status is spam is left out and listed on the import job. Spam is the one state with nothing worth carrying across: an unpublished review is still a customer's opinion, and spam is not.

Where a file has more than one of these columns, published wins, then hidden, then moderationStatus.

Verified buyers

verifiedBuyer takes true or false, and also the words platforms print on the badge: buyer, verified and verified purchase all mean true, unverified and guest mean false.

Some platforms have no flag and prove the purchase with an order instead. Put that order's ID or number in orderReference and the review counts as a verified buyer. The reference is kept on the review's metadata so you can trace it later. An explicit verifiedBuyer value always wins over the order reference.

Photos and videos

Put publicly reachable URLs in imageUrls. Commas, spaces and semicolons all separate them, and a JSON array of URLs (or of objects with a url field) is accepted too, because that is how some platforms export their media. Cascade downloads each one and stores its own copy, so the attachments keep working after you close your old account. JPEG, PNG, GIF and WebP images are accepted, along with MP4, QuickTime and WebM video.

An attachment that can't be fetched is reported against its row and the review is still imported, so a few dead links won't cost you the migration.

An image already attached to a review from the same URL is not fetched twice, so running an import again does not give every review a second copy of its photos.

Merchant replies

Your replies come across. Put the reply text in response and it is written as the review's reply, published, with your organization's name above it. Set responderName to change that name and responseCreatedAt to keep the original date.

A review holds one reply, so importing the same review again rewrites the reply rather than adding a second.

Review questions

If you ask review questions, each live one gets its own column, named question: followed by the question's label, such as question:How is the fit?. An export writes those columns, so an export and a re-import round-trip cleanly.

What goes in the cell depends on the question. A scale takes the step number, counting from

  1. A list of options takes the option labels, separated by |, such as Yes|No. Leave a cell empty for a review that did not answer that question.

A cell naming an option that question does not offer, or a step outside its scale, skips the row and reports why. Nothing is required here: unlike a live submission, an imported review can leave a required question unanswered, since it was written before you asked it.

When a row doesn't match

An import doesn't stop at the first bad row. Rows that can't be placed are skipped, and each one is listed with its row number on the import job under Settings, Imports:

Row 3: No customer with the email "[email protected]".
Row 4: No product with the slug "discontinued-widget".

Fix those rows and import the file again. Because everything else was already imported, use externalId so the second run doesn't duplicate the reviews that worked the first time.

Running it twice

externalId is what makes an import safe to repeat. Give each row the review's ID from your old platform, and importing the same file again updates those reviews in place instead of adding a second copy of each. Without it, every import adds new reviews.

Every named format below maps the platform's own review ID onto externalId, so a competitor export is safe to re-run as it comes. This is the single most useful thing the mapping does, because review migrations get run twice more often than they get run once.

Exports fill externalId in for you, using the review's own Cascade ID where there is no external one. An export can therefore be edited and imported back without duplicating anything.

Migrating from a named platform

The Format picker on the import dialog reads a competitor's export as it comes, so you do not have to rename a column before you upload. Pick the platform, upload the file, and Cascade maps the columns for you.

Warning

These mappings were written from each platform's published documentation, not from a real export file. Compare the table for your platform against your own export before you upload. If a column name differs, tell us and we will fix the mapping; in the meantime, rename the column in a spreadsheet, or reshape the file and use the Cascade format.

Four things are true of every named format:

  • The picker is not a guess. Cascade uses the format you picked, and refuses the file if its columns are not that format's. Several of these platforms use column names that overlap, so detecting the format from the headers would be a coin toss on exactly the files where getting it wrong is most expensive.
  • Columns are matched loosely on case and punctuation. Product Handle, product_handle and productHandle are the same column.
  • Nothing is dropped quietly. Every column the mapping does not carry into Cascade is listed on the import job under Settings, Imports, with the reason. A completed job with a list of notices is normal for a competitor import.
  • Cascade's own site column is accepted alongside. Add it by hand if you sell the same catalog on more than one site and the reviews belong to a particular one.

Migrating from Yotpo

Export your reviews from Yotpo and upload the file with Format set to Yotpo. Yotpo identifies products by ID rather than handle, so connect your Shopify store first or make sure the product_url column points at pages whose last path segment is your product slug.

Yotpo columnBecomesNotes
review_id or idexternalIdRequired. What makes a re-run safe.
reviewer_email or emailcustomerRequired. A customer Cascade has not seen is created.
review_score, score or ratingratingRequired. Rounded to a whole star.
product_id or external_product_idproductExternalIdRequired. Matched against the Shopify product ID.
product_urlproductUrlThe fallback when the ID does not resolve.
review_title or titletitle
review_content, content or bodybody
review_created_at, created_at or datecreatedAt
publishedpublished
review_state or statusmoderationStatusspam rows are not imported.
verified_buyer or verifiedverifiedBuyer
order_id or external_order_idorderReference
images, image_urls, review_images, video_urlsimageUrlsAll of them together, in the order the columns appear.
review_comment or commentresponseYour reply to the review.
comment_created_atresponseCreatedAt
reviewer_name, display_nameNot importedNames belong to the customer record.
votes_up, votes_downNot importedCascade counts helpful votes from its own widget.
sentimentNot importedCascade has no sentiment score.
deletedNot importedRemove deleted reviews from the file before you upload.
product_titleNot importedThe product Cascade holds supplies the title.
custom_fieldsNot importedPut the ones you need in a metadata column as JSON.
sourceNot importedEverything in the file arrived by import.

The deleted column is the one to check. Cascade imports every row in the file, so a Yotpo export that still carries deleted reviews will bring them back. Filter them out in a spreadsheet first.

Migrating from Judge.me

Export your reviews from Judge.me and upload the file with Format set to Judge.me. Judge.me exports the Shopify handle, which is exactly Cascade's product slug, so this migration works with or without a connected store.

Judge.me columnBecomesNotes
id or review_idexternalIdRequired. What makes a re-run safe.
reviewer_email or emailcustomerRequired.
ratingratingRequired.
product_handle or handleproductRequired. The handle is Cascade's slug.
product_idproductExternalIdThe fallback when the handle has been renamed.
product_urlproductUrl
titletitle
body or review_contentbody
review_date or created_atcreatedAt
publishedpublished
hiddenhiddenThe opposite of published, read that way round.
curatedmoderationStatusspam rows are not imported.
verifiedverifiedBuyerbuyer counts as verified.
order_id, order_numberorderReference
picture_urls, pictures, photo_urlsimageUrlsAll of them together.
replyresponseYour reply to the review.
reply_dateresponseCreatedAt
reviewer_name, nameNot importedNames belong to the customer record.
ip_addressNot importedOnly storefront reviews record one.
custom_questionsNot importedPut the ones you need in a metadata column.
votes_up, votes_downNot importedCascade counts votes from its own widget.
product_titleNot importedThe product Cascade holds supplies the title.
locationNot importedCascade has no location on a review.
sourceNot importedEverything in the file arrived by import.

Custom question answers are the loss to plan for. Judge.me lets you ask "How did it fit?" alongside the review, and Cascade has no field for the answer. If you need them, copy the columns into a metadata column of JSON before you upload, and they land on the review as your own key/value pairs.

Migrating from Okendo

Export your reviews from Okendo and upload the file with Format set to Okendo. Okendo identifies products by Shopify ID, so connect your store first.

Okendo columnBecomesNotes
reviewId or idexternalIdRequired. What makes a re-run safe.
reviewerEmail or emailcustomerRequired.
ratingratingRequired.
productIdproductExternalIdRequired. Matched against the Shopify product ID.
productUrlproductUrlThe fallback when the ID does not resolve.
title, reviewTitletitle
body, reviewBody, reviewTextbody
dateCreated, reviewDatecreatedAt
publishedpublished
statusmoderationStatusspam rows are not imported.
verifiedPurchase, verifiedverifiedBuyer
orderIdorderReference
media, mediaUrls, imageUrl, videoUrlimageUrlsA JSON array of URLs is read as a list.
response, replyresponseYour reply to the review.
responseDateresponseCreatedAt
reviewerName, displayNameNot importedNames belong to the customer record.
attributes, customAttributesNot importedPut the ones you need in a metadata column.
helpfulVotes, upVotes, downVotesNot importedCascade counts votes from its own widget.
productNameNot importedThe product Cascade holds supplies the title.
sourceNot importedEverything in the file arrived by import.

Okendo often exports media separately from the reviews. If your export has no media column, the photos are in a second file keyed by review ID. Join the two in a spreadsheet into one media column of comma-separated URLs before you upload, or import the reviews now and their photos later with a two-column file of externalId and imageUrls.

Okendo attributes are the loss to plan for, for the same reason as Judge.me's custom questions: fit, size and your own attribute questions have no field in Cascade.

Migrating from Stamped

Export your reviews from Stamped and upload the file with Format set to Stamped.

Stamped columnBecomesNotes
id or reviewIdexternalIdRequired. What makes a re-run safe.
email or authorEmailcustomerRequired.
reviewRating or ratingratingRequired. Rounded to a whole star.
productIdproductExternalIdRequired. Matched against the Shopify product ID.
productHandleproductUsed first when the export carries it.
productUrlproductUrl
reviewTitle, titletitle
reviewMessage, message, bodybody
reviewDate, dateCreatedcreatedAt
published, isPublishedpublished
reviewState, statusmoderationStatusspam rows are not imported.
verifiedBuyer, verifiedverifiedBuyer
orderId, orderReforderReference
reviewPhotos, photos, photo, photo1 to photo3, reviewVideoimageUrlsAll of them together.
reviewReply, replyresponseYour reply to the review.
replyDateresponseCreatedAt
author, reviewerNameNot importedNames belong to the customer record.
locationNot importedCascade has no location on a review.
customFields, reviewQuestionsNot importedPut the ones you need in a metadata column.
reviewVotesUp, reviewVotesDownNot importedCascade counts votes from its own widget.
productTitleNot importedThe product Cascade holds supplies the title.

Migrating from Loox

Export your reviews from Loox and upload the file with Format set to Loox. Loox exports the Shopify handle, so this migration works without a connected store.

Loox columnBecomesNotes
id or review_idexternalIdRequired. What makes a re-run safe.
emailcustomerRequired.
rating or starsratingRequired.
product_handle or handleproductRequired. The handle is Cascade's slug.
product_idproductExternalId
product_urlproductUrl
titletitle
body, review, textbody
date, created_atcreatedAt
publishedpublished
statusmoderationStatusspam rows are not imported.
verifiedverifiedBuyer
order_id, order_nameorderReferenceLoox reviews come from orders, so this is usually what marks the buyer verified.
photo, photos, photo_url, image_url, videoimageUrlsAll of them together.
replyresponseYour reply to the review.
reply_dateresponseCreatedAt
name, reviewer_nameNot importedNames belong to the customer record.
product_titleNot importedThe product Cascade holds supplies the title.
featuredNot importedCascade has no featured flag on a review.
sourceNot importedEverything in the file arrived by import.

When Cascade refuses the file

If the columns are not the format's, the import fails before it writes anything and the job says what it looked for and what it found:

This file does not look like a Yotpo export.
Missing the review id column: expected "review_id" or "id".
Missing the product id column: expected "product_id" or "external_product_id".
Your file has: "email", "rating", "body".
Check that the Format picker matches the file you uploaded. The migration guide lists the
columns each format expects.

That is almost always the wrong format picked, or the wrong export downloaded. Nothing is imported, so fix whichever it was and upload again.