Product Review API Endpoint to add/update reviews

SocialPanda
Shopify Partner
4 0 4

We are working on developing Shopify App and looking forward for API endpoints for adding/updating/deleting Product reviews.

 

So far i am unable to find any such option in API documentation of Shopify and no one has answered this question in the forum as well. Can you guys please help and suggest if there is any option and API endpoint available for same. 🙂

Replies 13 (13)

KarlOffenberger
Shopify Partner
1873 184 900

If you are referring to Shopify's product reviews, those aren't entirely part of the out-of-the-box offering and are a separate, stand alone app offered by Shopify. Which is why you won't find any specific Shopify API for reviews.

 

That said, some of the information is available via API because the review HTML is stored in a products' metafields so you can

 

GET /admin/products/<PRODUCT_ID>/metafields.json?namespace=spr&key=reviews

And then do some regex foo to get data you need 😉

 

You could also POST, PUT and DELETE that metafield entry but don't know if that's the only place data is stored for the reviews app - if it is, great, if not then no idea. Ultimately up to you to give it a try and share back here if you can.

 

Hope this helps!

jingjing
Tourist
3 0 0

Can you elaborate on this? I need your help. Thank you.

craigfay
Shopify Partner
2 0 15

Hey all. "Product Reviews" don't actually exist as a first class object in Shopify the way "Products", "Variants", or "Metafields" do. Instead of adding a "Product Reviews" object, Shopify made Product Reviews possible with an app, which you can install for free in your store. To say that this app stores Product Reviews as Metafields is an inadequate explanation for a few reasons.

 

Here's an example of what a "Review" Metafields looks like alongside other Product Metafields:

I retrieved this data using the Admin API: https://{mystore}.myshopify.com/admin/api/2019-07/products/{product_id}/metafields.json

 

{
  "metafields": [
    {
      "id": 7637328836,
      "namespace": "spr",
      "key": "reviews",
      "value": "<style scoped>.spr-container {\n    padding: 24px;\n    border-color: #ffffff;}\n  .spr-review, .spr-form {\n    border-color: #ececec;\n  }\n<\/style>\n\n<div class=\"spr-container\">\n  <div class=\"spr-header\">\n    <h2 class=\"spr-header-title\">Customer Reviews<\/h2><div class=\"spr-summary\" itemscope itemprop=\"aggregateRating\" itemtype=\"http:\/\/schema.org\/AggregateRating\">\n        <meta itemprop=\"itemReviewed\" content=\"Magnolia Farms Shirt\">\n\n        <span class=\"spr-starrating spr-summary-starrating\">\n          <meta itemprop=\"bestRating\" content=\"5\">\n          <meta itemprop=\"worstRating\" content=\"1\">\n          <meta itemprop=\"reviewCount\" content=\"27\">\n          <meta itemprop=\"ratingValue\" content=\"4.555555555555555\">\n          <i class=\"spr-icon spr-icon-star\"><\/i><i class=\"spr-icon spr-icon-star\"><\/i><i class=\"spr-icon spr-icon-star\"><\/i><i class=\"spr-icon spr-icon-star\"><\/i><i class=\"spr-icon spr-icon-star\"><\/i>\n        <\/span>\n        <span class=\"spr-summary-caption\"><span class='spr-summary-actions-togglereviews'>Based on 27 reviews<\/span>\n        <\/span><span class=\"spr-summary-actions\">\n        <a href='#' class='spr-summary-actions-newreview' onclick='SPR.toggleForm(359886801);return false'>Write a review<\/a>\n      <\/span>\n    <\/div>\n  <\/div>\n\n  <div class=\"spr-content\">\n    <div class='spr-form' id='form_359886801' style='display: none'><\/div>\n    <div class='spr-reviews' id='reviews_359886801' ><\/div>\n  <\/div>\n\n<\/div>\n",
      "value_type": "string",
      "description": null,
      "owner_id": 359886801,
      "created_at": "2015-09-24T13:46:33-05:00",
      "updated_at": "2018-12-04T11:20:26-06:00",
      "owner_resource": "product",
      "admin_graphql_api_id": "gid:\/\/shopify\/Metafield\/7637328836"
    },
    {
      "id": 13580799940,
      "namespace": "sva",
      "key": "visibility",
      "value": "visible",
      "value_type": "string",
      "description": null,
      "owner_id": 359886801,
      "created_at": "2016-01-19T12:49:52-06:00",
      "updated_at": "2016-01-19T12:49:52-06:00",
      "owner_resource": "product",
      "admin_graphql_api_id": "gid:\/\/shopify\/Metafield\/13580799940"
    },
    {
      "id": 17002210116,
      "namespace": "product",
      "key": "details",
      "value": "<h3>Details<\/h3>\n<ul>\n<li>100% Cotton<\/li>\n<li>Unisex<\/li>\n<li>Female Model is wearing a small<\/li>\n<li>male model is wearing a medium<\/li>\n<li>Designed in Waco<\/li>\n<li><strong>care instructions:<\/strong><\/li>\n<ul>\n<li>Wash in cold water separately from other clothing items.<\/li>\n<li>Only non-chlorine bleach.<\/li>\n<li>It is not advisable to use stain removers on pigment dyed garments since the color could potentially be removed as well. Tumble dry low. Do not iron if decorated<\/li>\n<\/ul>\n<\/ul>\n<style><!--\n.shipping-info h3 {\n margin: 30px 0px;\n}\n\n.shipping-info a {\n  color: #86a122;\n  text-decoration: none;\n}\n\n.shipping-info a:hover {\n  text-decoration: underline;\n}\n\n.shipping-costs-table {\n  font-weight: lighter;\n  font-family: Open Sans, Arial, sans-serif;\n  font-size: 12px;\n  letter-spacing: 2px;\n  margin-bottom: 30px;\n}\n\n.shipping-costs-table thead {\n  text-transform: uppercase;\n  text-align: center;\n}\n\n.shipping-costs-table thead th {\n  height: 48px;\n  color: #31444e;\n  font-weight: normal;\n}\n\n.shipping-costs-table tbody td {\n height: 48px;\n border-bottom: 1px solid #eeeeec;\n text-align: center;\n}\n\n.shipping-costs-table tr th:first-child, .shipping-costs-table tr td:first-child {\n text-align: left;\n padding-left: 10px;\n}\n--><\/style>\n<div class=\"shipping-info\">\n<h3>Size Chart<\/h3>\n<table class=\"shipping-costs-table\" cellpadding=\"0\" cellspacing=\"0\" style=\"width: 99.8227%;\">\n<thead>\n<tr>\n<th style=\"width: 14%; background: #f0ede6;\">Size<\/th>\n<th style=\"width: 24%; background: #e3e9ce;\">Body Length<\/th>\n<th style=\"width: 23.7161%; background: #e3e9ce;\">Body Width<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"width: 14%;\">S<\/td>\n<td style=\"width: 24%;\">27\"<\/td>\n<td style=\"width: 23.7161%;\">18.5\"<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14%;\">M<\/td>\n<td style=\"width: 24%;\">28.5\"<\/td>\n<td style=\"width: 23.7161%;\">\n<div><meta charset=\"utf-8\" \/><\/div>\n<span>20.5\"<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14%;\">L<\/td>\n<td style=\"width: 24%;\">30\"<\/td>\n<td style=\"width: 23.7161%;\">\n<div><meta charset=\"utf-8\" \/><\/div>\n<span>22.5\"<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14%;\">XL<\/td>\n<td style=\"width: 24%;\">31.5\"<\/td>\n<td style=\"width: 23.7161%;\">\n<div><meta charset=\"utf-8\" \/><\/div>\n<span>24.5\"<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14%;\">XXL<\/td>\n<td style=\"width: 24%;\">32.75\"<\/td>\n<td style=\"width: 23.7161%;\">\n<div><meta charset=\"utf-8\" \/><\/div>\n<span>26.5\"<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>",
      "value_type": "string",
      "description": null,
      "owner_id": 359886801,
      "created_at": "2016-03-04T10:00:06-06:00",
      "updated_at": "2019-01-08T16:46:14-06:00",
      "owner_resource": "product",
      "admin_graphql_api_id": "gid:\/\/shopify\/Metafield\/17002210116"
    },
] }

We're talking specifically about the first object in the metafields array. The other two have nothing to do with reviews.

 

What you'll notice about the value of the reviews metafield, is that it doesn't contain the actual product reviews. Instead, it contains some HTML, eventually to be targeted by frontend Javascript. Without knowing precisely how Shopify's Product Reviews app works under the hood, we know that it enqueues a Javascript file on your product pages that is responsible for showing/creating product reviews.

 

If you install and configure the app, then inspect a product page, you'll find a Javascript file loaded from productreviews.shopifycdn.com, called "spr.js?shop={mystore}.myshopify.com". Here's a few snippets of that code:

 

 

function e() {}
return e.shop = Shopify.shop,
e.host = "//productreviews.shopifycdn.com",
e.version = "v4",
e.api_url = e.host + "/proxy/" + e.version,
e.badgeEls = [],
e.reviewEls = [],
e.elSettings = {},
e.$ = void 0,
e.extraAjaxParams = {
shop: e.shop
},

Above, variables are being defined that can be used to make an AJAX request to https://productreviews.shopifycdn.com/proxy/v4. We can see that the request will included the name of your shop, which it pulls from the Shopify object that already exists on the page.

 

 

 

            e.pageReviews = function(e) {
                var t, r, a;
                return a = this.$(e).data("product-id"),
                r = this.$(e).data("page"),
                t = this.$.extend({
                    page: r,
                    product_id: a
                }, this.extraAjaxParams),
                this.$.get(this.api_url + "/reviews", t, this.paginateCallback, "jsonp"),
                !1
            }
            ,
            e.submitForm = function(e) {
                var t;
                return t = this.$(e).serializeObject(),
                t = this.$.extend(t, this.extraAjaxParams),
                t = this.$.param(t),
                t = t.replace(/%0D%0A/g, "%0A"),
                this.$.ajax({
                    url: this.api_url + "/reviews/create",
                    type: "GET",
                    dataType: "jsonp",
                    data: t,
                    success: this.formCallback,
                    beforeSend: function(e) {
                        return function() {
                            return e.$(".spr-button-primary").attr("disabled", "disabled")
                        }
                    }(this),
                    complete: function(e) {
                        return function() {
                            return e.$(".spr-button-primary").removeAttr("disabled")
                        }
                    }(this)
                }),
                !1
            }

 

Above, we can infer that this JS retrieves product review objects by sending a GET request to: https://productreviews.shopifycdn.com/proxy/v4/reviews

Likewise, we it creates a product review by sending a GET request to:  https://productreviews.shopifycdn.com/proxy/v4/reviews/create

 

Unfortunately, this API is not intended to be public, and attempts to access it will be Unauthorized. The punchline here is that Product Reviews created by the Product Reviews app are likely stored centrally on the Product Reviews app, and a  aren't easily accessible in any way that you might hope for, because they aren't actually housed in your Shopify Store.

 

The good news is that what I've described is just the way that the Shopify App accomplishes Product Reviews, but not the only way. What you might do instead is store Product Review JSON in product metafields. To accomplish this, you'd need to enqueue Javascript to build the Product Reviews UI, and use a Private App to interact with the Metafields Admin API on your behalf. Alternatively, some apps use an iFrame or WebView type approach to access the product reviews UI from another page, which is be a viable solution for some use cases.

 

It's not obvious why Shopify opted for the solution they did. Maybe they wanted to leverage the centrality of all product reviews for their own analytics, or maybe there's some technical limitation in their system that prevented them from pursuing simpler solutions. Either way, it's not enough to say that product reviews are stored in metafields. A common pattern within the Shopify ecosystem is that EVERYTHING gets stored in product metafields, which are not publicly accessible. This means that they require a public or private app that can retrieve them for you.

 

Hope this helps shed some light on the state of Product Reviews. I'm not an expert, and I may be missing some information. Maybe someone who was apart of these decisions can weigh in or give us a more detailed picture of how Product Review objects could be retrieved more directly from the Product Reviews App. I suspect it's not possible at the moment.

 

cordial666
Tourist
4 0 1

Is this still the current state of play still in mid 2020? I have a need to add reviews but the above approach seems pretty painful. 

vantagedev
Visitor
2 0 1

Yes, unfortunately it doesn't seem like anything has changed.

karmelcorn
Tourist
7 0 9

I am needing access to Product Reviews API too. Is there any place, we can request this as a feature update?

Crowesam
Shopify Partner
3 0 2

I must say this is exactly what I have been pulling my hair out trying to track down and appreciate the magnificent attention to detail and the care you invested in your answer above.

This puts me on a firm track to finding a solution for this challenge. You are a valuable member of this online community. Thank you! 

YazDev
Shopify Partner
1 0 0

This was extremely helpful and saved me a lot of time. Really appreciate the effort you put into this 👍

karmelcorn
Tourist
7 0 9

Hi, 

Since there is no APIs to directly access the reviews, I am thinking of creating a new page on Shopify just to present the reviews for each product. And I can just link to this page whenever I need to update or view the current reviews. 

 

https://help.shopify.com/en/manual/apps/apps-by-shopify/product-reviews/installation explains how to embed the review on the product page. 

 

Can you help me on how I can create a brand new empty page just to show the reviews on Shopify?

 

Thank you. 

iraklik
Visitor
1 0 1

Hi there,

Is there a way to retrieve product reviews from Shopify Product Reviews app and show them on the homepage? It seems like throwing money away to buy another app to do that for you when you already have all the product reviews that you can just hook on the Owl carousel and style them as you need. 

 

Thanks, Irakli

Tom_Keysers
Shopify Partner
40 0 7

What I use to retrieve product reviews on our shop is basically this:

$.ajax({
          method: 'GET',
          url: 'https://productreviews.shopifycdn.com/proxy/v4/reviews/product?shop=seres-collection.myshopify.com&product_id=' + el.id,
          dataType: 'jsonp', // jsonp does the trick to avoid cross-origin-policy shit! https://www.sitepoint.com/jsonp-examples/
          success: function(resp) {
            // console.log('succes: ', resp);
            var $html = $(resp.reviews);
            $html.each(function() {
              $(this).find('.spr-review-footer').remove();
              el.review_html += $(this).html();
            });
          },
          error: function(jqXHR, textStatus, errorThrown) {
            console.log(jqXHR, textStatus, errorThrown);
          }
        });

 

Based on that we made a custom page which shows all our reviews, without any paying apps or whatever. You can see it here: https://shop.serescollection.com/pages/reviews 

Freelance developer – http://tomkeysers.be
VajroDev
Shopify Partner
1 0 0

Hey Karl, 

Vajro is a mobile app partner for Shopify. We are having an issue with the reviews getting repeated. Upon deeper introspection we noticed that Shopify review doesn't support pagination. 

Say, we can increase the count of the reviews in single page ( 80 reviews per page in Shopify reviews dashboard) - first 80 review will be show in app. Post the 80 reviews, the reviews gets repeated. 

The API also passes the repeated values! Let me know how you can unblock us here

TopBit
New Member
10 0 0

yes i have same issue , no updates, they are pushing to pay for another apps .

 

that still don't have necessarily functions.

 

i just want to add reviews and rating to my dawn theme application json schema

 

didn't find solution

Optimistic men