Product Review API Endpoint to add/update reviews

SocialPanda
Shopify Partner
4 0 2

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. :)

KarlOffenberger
Shopify Partner
1867 182 777

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!

Liked this post? You might also like our fantastic upsell apps Candy Rack and Candy Cart or offer free gifts with Gift Box. All made with ❤️  and care by Digismoothie
0 Likes
jingjing
Tourist
3 0 0

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

0 Likes
craigfay
Shopify Partner
1 0 7

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. 

0 Likes
vantagedev
New Member
2 0 1

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

0 Likes
karmelcorn
Tourist
7 0 3

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

0 Likes
karmelcorn
Tourist
7 0 3

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. 

0 Likes