Standard product review metaobject definition
The standard product review metaobject is a restricted definition available to approved product review apps. This guide covers implementation requirements, the approval process, and how to syndicate reviews using the standard definition. Any partner can participate in the program by meeting the requirements and signing the review-specific amendment.
The standard product review metaobject allows review apps to store and manage product reviews in a consistent format across Shopify. When you syndicate reviews to this metaobject, they become eligible for display in the Shop app (subject to eligibility requirements). To implement the standard product review metaobject in your app, follow these steps:
If you join the standard product review syndication program, all valid reviews must be syndicated to product review metaobjects and all total review counts and average star ratings must be syndicated to product review metafields.
-
Request test access through Partner Dashboard
- From your development app, go to Partners Internal
- Navigate to API Access
- Click on the card to request access to the scope for standard product reviews
- This will enable the scopes on your dev test store only
- The Shop app channel will be enabled for your dev shop so you can test functionality in the Shop app
-
Test your implementation
- Implement the review syndication with your dev app
- Test the implementation thoroughly in your dev store
- Verify functionality in the Shop app
-
Submit for review
- Submit your app for review
- If you already have a production app you want to opt in, include that production app ID in your review request
- The app review team will review your implementation
- If approved, you'll need to sign an updated agreement
- After signing:
- Your dev app will either be promoted to a live app with the necessary scopes, OR
- If you included a production app ID in your review request, that app will be granted the necessary scopes
Apps must meet the following requirements before being accepted into the standard product review syndication program:
All reviews must be synchronized as standard metaobject entries. Reviews must be properly validated according to the metaobject field requirements:
- Rating field must be a valid JSON object matching the schema:
{"scale_min":"1.0","scale_max":"5.0","value":"5.0"}
. - Required fields must be populated:
rating
,submitted_at
,source
,product
, andapp_verification_status
. - Reference fields (
author
,order
,product
,product_variant
) must reference valid resources in the merchant's store. - Language field must use valid ISO 639-1 standard language codes.
Anchor to Requirement 2: aggregate count updatesRequirement 2: aggregate count updates
Apps must maintain accurate aggregate review data by updating the following standard metafields on each product:
- Product Rating (
reviews.rating
): The average star rating for the product - Product Rating Count (
reviews.rating_count
): The total number of reviews for the product
These metafields must be kept in sync with the metaobject reviews and updated whenever:
- A new review is created
- An existing review is updated
- A review is deleted
- A review's published status changes
Anchor to Additional Implementation RequirementsAdditional Implementation Requirements
When importing/exporting reviews via CSV:
-
Reviews with existing metaobject handles must be sourced from the metaobjects API.
-
Reviews must be enriched with data from CSV imports to support all merchant imported fields.
-
Metaobject webhook events must be handled for all merchants with the app installed.
For bulk operations:
-
JSONL files must not exceed 20MB.
-
Consider partitioning JSONL files into batches of 10,000 reviews.
-
Handle validation errors and retry logic for failed operations.
For review publication status:
-
Published reviews must have publishable status set to
ACTIVE
and a validpublished_at
timestamp. -
Unpublished reviews must have publishable status set to
DRAFT
andpublished_at
set tonull
.When handling webhooks:
-
Subscribe to all metaobject topics:
METAOBJECTS_CREATE
,METAOBJECTS_UPDATE
,METAOBJECTS_DELETE
. -
Include the
subTopic
field in the webhook subscription payload. -
Handle webhook requests asynchronously to prevent API throttling.
-
Implement retry/backoff strategy for API requests.
For review syndication:
-
All valid reviews must be syndicated to metaobjects.
-
Reviews must be eligible for display in the Shop app (subject to eligibility requirements).
-
Maintain proper attribution through the
createdByAppId
field. -
Handle cases where imported reviews may not have correct order, product, or customer references.
Anchor to Verified by Shop Branding RequirementsVerified by Shop Branding Requirements
Apps that participate in the standard product review syndication program must display the "Verified by Shop" badge to indicate that their reviews are eligible for display in the Shop app. This helps merchants and customers identify trusted review sources.
Anchor to Badge RequirementsBadge Requirements
-
Badge Assets
-
Badge Placement
- Display the badge prominently in your app's review interface
- Include the badge on any review widgets or components that display syndicated reviews
- Ensure the badge is visible when reviews are displayed on the merchant's storefront
-
Badge Usage
- Use the badge only for reviews that are successfully syndicated to or from the standard product review metaobject
- Do not use the badge for reviews that are not eligible for Shop app display
- Ensure the badge is properly sized and legible on all devices and screen sizes
For questions about badge usage or to request access to the badge assets, contact the Shop team through the Partner Dashboard.
Anchor to Product review metaobject fieldsProduct review metaobject fields
The following table details all available fields for the product review metaobject:
Field name | Field key | Field type | Required | Validation |
---|---|---|---|---|
Rating | rating | Rating field | Yes | A validated JSON object matching the following schema: {"scale_min":"1.0","scale_max":"5.0","value":"5.0"} |
Title | title | Single line text field | No | None |
Body | body | Multi line text field | No | None |
Submitted at | submitted_at | Date time | Yes | None |
Edited at | edited_at | Date time | No | None |
Published at | published_at | Date time | No | None |
Source | source | Single line text field | Yes | None |
Author | author | Customer reference | No | When this field is populated, the customer must be present in the merchant's store. |
Author display name | author_display_name | Single line text field | No | None |
Order | order | Order reference | No | When this field is populated, the order must be present in the merchant's store. |
Product | product | Product reference | Yes* | When this field is populated, the product must be present in the merchant's store. |
Product variant | product_variant | Product variant reference | No | When this field is populated, the product variant must be present in the merchant's store. |
Merchant reply | merchant_reply | Multi line text field | No | None |
Merchant replied at | merchant_replied_at | Date time | No | None |
Language | language | Language field | No | This should be a valid ISO 639-1 standard language code |
App verification status | app_verification_status | Single line text field | Yes* | Validates that the value is one of: verified_buyer , verified_reviewer , unverified |
Media URLs | media_urls | URL list | No | None |
Fields marked with * are required by implementation but not enforced by the schema. This can happen because of the deprecation and renaming of existing fields, or the introduction of new fields.
Anchor to Key concepts for building your apps integration to the standard product review metaobjectKey concepts for building your apps integration to the standard product review metaobject
Anchor to Access scopes that must be granted by the merchantAccess scopes that must be granted by the merchant
In order for your app to syndicate reviews through metaobjects, you'll need to make sure that it has the necessary access scopes.
Scope | Required | Access |
---|---|---|
write_product_reviews | Yes | Read, create, or update product review metaobjects and enable the standard metaobject definitions for product reviews |
read_metaobjects | Yes | Read any metaobject and subscribe to metaobject webhooks |
read_customers | Yes | Read customer information |
read_orders | Yes | Read order information |
read_products | Yes | Read product information |
For existing apps that are new to syndication, required permissions can be backfilled after app review by the app review team.
The Shopify OAuth docs contain more information around how to enable access scopes. You'll need to verify that the correct scopes have been added.
Anchor to Enabling the metaobject definitionEnabling the metaobject definition
To leverage the product review standard definition on a merchant's store, you'll first need to run a mutation to enable the product_review
standard metaobject definition. This is done by calling the standardMetaobjectDefinitionEnable
mutation:
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL mutation
JSON response
Anchor to Webhook subscriptionWebhook subscription
Before you can subscribe to the product review metaobject webhooks, you'll need to ensure you have the required access scopes and have the product review metaobject definition enabled.
To subscribe to product review metaobject webhooks, use the following GraphQL mutation:
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL mutation
JSON response
Shopify expects your app to subscribe to all metaobject topics when handling webhooks for product review metaobjects. The available topics are:
-
METAOBJECTS_CREATE
-
METAOBJECTS_UPDATE
-
METAOBJECTS_DELETE
When you subscribe to metaobject topics, you must provide a
filter
field in the payload to specify the type of metaobject you want to receive webhooks for.To unsubscribe your app from receiving webhooks, use this GraphQL mutation:
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL mutation
JSON response
Anchor to Webhook payloadWebhook payload
For METAOBJECTS_CREATE
and METAOBJECTS_UPDATE
lifecycle events, your app receives the payload for the product review metaobject, as shown below. Note that empty fields may not be populated.
For METAOBJECTS_DELETE
, your app receives:
Anchor to Managing reviews with the GraphQL Admin APIManaging reviews with the Graph QL Admin API
Anchor to Getting a review metaobjectGetting a review metaobject
You can read metaobjects by id
using the metaobject
query. Alternatively, you can read metaobjects by their handle using the metaobjectByHandle
query.
Example GraphQL:
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL query
JSON response
Anchor to Getting multiple review metaobjects in bulkGetting multiple review metaobjects in bulk
Use a bulk query to get all product review metaobjects for a shop. You can select as many fields as your app requires, as shown in the previous example.
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL mutation
JSON response
The following example fetches data asynchronously and stores it in a JSONL
file. When it finishes, you can fetch the file with the currentBulkOperation
query. You can only run one bulk operation (query or mutation) at a time, and you can only fetch the most recent operation. Previous bulk operation results are not available.
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL query
JSON response
The response from the currentBulkOperation
contains a URL link to a file with the response. To ensure the creation of the corresponding metaobject, it's important to inspect the file for any userErrors
that occurred during the operation. If any userErrors
are found, the metaobject is not created.
Anchor to Creating a review metaobjectCreating a review metaobject
You can create reviews by issuing a metaobjectUpsert
mutation.
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL mutation
JSON response
An example MetaobjectUpsertInput
. Note that this example is incomplete, with only one field. You must supply all available and required fields.
Anchor to Updating a review metaobjectUpdating a review metaobject
To update a review, use the same metaobjectUpsert
mutation used for creating a new review. This mutation updates an existing review or creates a new review if it doesn't already exist. When you provide a list of fields to update, those fields are overwritten and the final metaobject is merged with the remaining fields left intact.
Anchor to Bulk upserting multiple review metaobjectsBulk upserting multiple review metaobjects
Upload a JSONL
file containing newline-separated JSON objects with the mutation parameters with the stagedUploadCreate
mutation. You can provide as many fields you wish to update. Refer to all available and required fields. There is a hard limit of 20MB on the JSONL
file. You can partition the JSONL
file into batches of 10,000 reviews to ensure it does not exceed this limit.
Pass the resulting path to the staged upload to a bulkOperationRunMutation
that performs the mutations asynchronously.
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL mutation
JSON response
The guidelines for bulk importing data provide more detailed information around bulk operations.
Anchor to Deleting a single review metaobjectDeleting a single review metaobject
Deleting a single review metaobject can be done through the metaobjectDelete
mutation.
Anchor to Bulk deleting multiple review metaobjectsBulk deleting multiple review metaobjects
Multiple reviews can be deleted through the metaobjectBulkDelete
mutation. There's a limit of 250 review IDs per request.
Anchor to Mark a review metaobject as published or unpublishedMark a review metaobject as published or unpublished
In order to mark a review as published or unpublished in its metaobject, supply two things in the metaobjectUpdate
payload:
- Publishable status capability:
{"capabilities": {"publishable": {"status": "ACTIVE"}}
when published{"capabilities": {"publishable": {"status": "DRAFT"}}
when unpublished
published_at
:- A UTC timestamp when published
null
when unpublished
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL mutation
JSON response
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL mutation
JSON response
Anchor to Importing and exporting reviews with handlesImporting and exporting reviews with handles
If you support importing reviews from another partner via CSV import, you should avoid duplicating reviews in metaobjects. When a metaobject handle is present for an imported review, source the review from the metaobjects API.
To support review importing, do the following things:
-
Update your review export flow to include the review's metaobject handle.
-
Update your review import flows to support reading metaobject handles.
-
Shop reviews from the CSV import should be sourced from the metaobjects API.
-
Partner reviews from the CSV import with handles should be sourced from the metaobjects API.
-
To support all merchant imported fields, review data sourced from the metaobjects API should be enriched with the data from CSV imports. For example, custom questions.
-
To prevent outdated reviews in your app, handle all metaobject webhook events for merchants with your app installed regardless of which app ID has created the metaobject.
The partner app responsible for creating the metaobject can be identified by reading the
createdByAppId
field. It is important to note that this field is immutable and is always attributed to the app that created the metaobject. This means that not all metaobjects for your active merchants will show thecreatedByAppId
field, populated with your app ID.Furthermore, if your application supports exporting and importing reviews from one Shopify store to another, you should recreate the metaobjects using the same handle. Shop may not be able to ingest such reviews, since the imported reviews will not have correct order, product or customer references for the new store.
Anchor to TestingTesting
Before you can test the integration, you'll need a test store that is configured to be visible in the Shop App.
Your test store must meet the following conditions:
-
The Shop channel is installed.
-
The app for which you are testing the integration is installed.
-
The store has at least one test product that can be purchased.
-
Test payments have been enabled, or there's a 100% order discount you can use to complete the checkout.
To test your development shop with the Shop app integration:
- Install the Shop app on your development store from the Shopify App Store
- From the Shop app in your store admin, toggle on development mode to enable testing functionality
When your test store meets these conditions, let the Shop team know, so they can enable your store. The steps outlined in the test plan may vary depending on the features available in your app.
Anchor to Handling validation errorsHandling validation errors
GraphQL mutations return validation errors in the userErrors
field. These errors can be a good first indication of how well your app's syndication of reviews to metaobjects is working.
When syndicating reviews to metaobjects, common integration errors usually have to do with incorrectly provided values, especially around reference fields. You should review the validation errors you receive and make the required adjustments to your integration, to ensure as many reviews can be syndicated to metaobjects as possible. That being said, reference fields are more complicated to handle and fix, as your app may have a resource ID that's not present on the merchant's store at the time of review syndication. In such a scenario, retry the review syndication without the resource ID.
Anchor to Encountering internal server errorsEncountering internal server errors
To account for intermittent internal server errors from Shopify's APIs, your app should use retry logic to ensure recovery and eventual success. For major outages, refer to Shopify's status page.
Anchor to Encountering rate limitsEncountering rate limits
Shopify API rate limits are applicable to all requests for metaobjects, and handling large volumes of incoming webhooks may throttle the API requests.
Consider the following strategies for handling webhook requests in your app:
- Handling incoming webhook requests asynchronously
- Having a retry/backoff strategy when making requests to Shopify APIs
- Implementing rate limiting internally within your app to reduce the chance of your app getting throttled by Shopify