Tip
-
Find additional Celigo migration resources at Shopify 2024-04 API release: Product REST API deprecation.
-
Migrate your Shopify universal connection to leverage the latest GraphQL APIs (custom flows)
New flows
The following GraphQL-based product flows are now available in the Shopify - NetSuite integration app. You can transition to these new flows using the instructions provided below.
-
Flows > Product
-
NetSuite item to Shopify product (add or update)
-
NetSuite matrix item to Shopify product (add or update)
-
-
Flows > Inventory
-
Shopify product ID to NetSuite item (mass update)
-
Deprecating flows
Shopify deprecated REST-based product flows on 1 July 2025, and Celigo disabled the following REST-based flows at that time.
-
Flows > Product
-
(To be deprecated) NetSuite image to Shopify image (add or update)
-
(To be deprecated) NetSuite item to Shopify product (add or update)
-
(To be deprecated) NetSuite matrix item to Shopify product (add or update)
-
-
Flows > Inventory
-
(To be deprecated) Shopify product ID to NetSuite item (mass update)
-
The functionality of the NetSuite image to Shopify image(add or update) flow will be incorporated into the logic of the other two flows, so it will no longer exist as a separate flow.
Steps to configure the flows:
-
Transition to GraphQL-based flows: To avoid disruptions, disable REST-based product flows and enable GraphQL flows.
-
Re-authorize Shopify connection: Once GraphQL flows are enabled, you must reauthorize the Shopify connection.
-
Recreate custom mappings: If you’ve implemented custom mappings in REST flows, ensure equivalent mappings are correctly configured in the GraphQL flows. This applies to the flows NetSuite item to Shopify product (add or update) and NetSuite matrix item to Shopify product (add or update).
Note
GraphQL flows support Shopify’s 2048-variant limit per product, improving scalability for complex catalogs.
Transition to GraphQL-based product flows
To transition REST-based product flows to GraphQL:
-
Open your Shopify - NetSuite integration app.
-
Navigate to Flows > Product.
-
Turn on the toggle for the following flows:
-
NetSuite item to Shopify product (add or update)
-
NetSuite matrix item to Shopify product (add or update)
-
-
Re-authorize Shopify connection:
-
Reauthorize the Shopify connection if you use the Sync published scope from NetSuite to Shopify setting to sync scopes.
-
If you enable this setting after reauthorization, reauthorize the connection again to sync the scopes. For more information about the scopes settings, see Settings.
Note
If you enable the Sync published scope from NetSuite to Shopify setting before authorizing the connection, you will see this error: “Unable to get a response from Shopify. Refresh the page and try again. If the issue continues, contact Celigo Support. Shopify returned: Access denied for publications field. Request access: 'read publications' access scope”
-
-
Recreate custom mappings:
-
If you’ve implemented custom mappings in REST flows, ensure equivalent mappings are correctly configured in the GraphQL flows. This applies to the flows NetSuite item to Shopify product (add or update) and NetSuite matrix item to Shopify product (add or update).
-
The GraphQL-based Product API utilizes the productSet mutation outlined in the Shopify productSet mutation article. Only fields included in this mutation can be added to custom mappings.
-
-
Turn off the toggle for the following flows:
-
(To be deprecated) NetSuite item to Shopify product (add or update)
-
(To be deprecated) NetSuite matrix item to Shopify product (add or update)
-
-
Schedule the flow: Once the flow is enabled, schedule it according to your business requirements. You can refer to the current REST-based flow schedule and replicate the same settings.
-
Updating Saved Searches for Product flows: When updating a saved search for product flows, always make the changes via Settings > Product > NetSuite saved search to sync items and/or NetSuite saved search to sync matrix items rather than modifying them at the flow level. Updating the search at the Settings level ensures that the changes automatically apply to the flow level for both REST and GraphQL flows (item and matrix).
-
Do not update the saved search at the flow level (Get Items from NetSuite export), as this will not reflect across all flow areas.
-
If you have created a new saved search and want to test the flow, first update the saved searches at the Settings level as explained above. Then, disable the REST flow and proceed with testing the GraphQL flow. Once you are confident in its performance, keep the GraphQL flow enabled. If further testing is required, you can re-enable the REST flow as needed.
-
Note
-
Review your existing configurations and ensure all necessary updates are applied.
Shopify's release update: On January 15, 2025, Shopify introduced support for leveraging the inventoryItem object within productVariants. The Weight and Weight Unit fields are part of the inventoryItem object. As a result, you can now sync Inventory Information to Shopify using GraphQL product flows. Since this change was implemented after our initial release of GraphQL flows, the out-of-the-box solution did not include prebuilt Weight mappings. Therefore, you need to manually configure the mappings. For more details about Shopify's official changelog: Shopify Changelog - New InventoryItem Field.
You can sync the Weight from NetSuite to Shopify using GraphQL-based product flows. The mapping in the product flows ensures that both Weight and Weight Unit are accurately transferred to Shopify.
Pre-requisite: Before syncing, ensure that the Weight Unit and Weight Value fields are added to the Saved Search results criteria in NetSuite.
How the sync Works:-
By default, NetSuite passes the Weight Unit as "lb," "kg," etc., and the Weight Value as "null" if it is not provided.
-
However, Shopify expects the Weight Unit to be either "kilogram," "pounds," etc., and treats null weight values as "0.0" instead of null.
To ensure seamless synchronization, configure the weight settings in the mapping correctly as explained below for null value correction, and incorporate the provided handlebar for unit correction. This will ensure that the weight values align with Shopify’s expected format.
Configure mapping for weight fields-
In the Flows > Product section, open the "Field Mappings" for the NetSuite Item to Shopify Product Add/Update flow.
-
Click Post products to Shopify. Scroll to the standard mappings for variants.
-
Click + to add a new row under the variants.
-
In the text field, type in inventoryItem and select the datatype as the object.
-
Click + at the inventoryItem level. In the text field, type in measurement and select the datatype as the object.
-
Click + at the measurement level. In the text field, type in weight and select the datatype as the object.
-
Click + at the weight level. Type in value and select the datatype as number.
-
From the source field dropdown, select Item Weight (Variant).
For items with weight value zero or no value: If an item's weight value is zero or you do not need to define a weight in NetSuite (e.g., Item type as service), configure the mapping as explained below:
-
Click Settings next to the NetSuite Item Weight (Variant) field.
-
In the Action to take if source field has no value dropdown, select Use custom default value.
-
In the Custom value field, enter 0.0.
-
-
Click + at the weight level. Type in unit and select the datatype as string.
-
From the source field dropdown, selectItem Weight Units (Variant).
For items with weight units other than "kilogram" or "pounds": Shopify expects the weight unit to be either "kilogram" or "pounds". If an item's weight unit you want to sync from NetSuite is not in"kilogram" or "pounds", configure the mapping as explained below:
-
Click Settings next to the NetSuite Item Weight Units (Variant) field.
-
From the Destination data type dropdown, select string.
-
From the Field mapping type dropdown, select Handlebars expression.
-
In the Handlebars expression, copy and paste this:
{{#compare variants.[Item Weight Units (Variant)] "==" "lb"}}POUNDS{{else}}{{#compare variants.[Item Weight Units (Variant)] "==" "kg"}}KILOGRAMS{{else}}{{#compare variants.[Item Weight Units (Variant)] "==" "g"}}GRAMS{{else}}{{#compare variants.[Item Weight Units (Variant)] "==" "oz"}}OUNCES{{else}}{{variants.[Item Weight Units (Variant)]}}{{/compare}}{{/compare}}{{/compare}}{{/compare}} -
From the Action to take if handlebars expression returns and empty value, select Use custom default value.
-
In the Custom value text box, enter POUNDS.
-
Click Save.
-
-
Now, once you run the flow, the weight records get synced correctly without any errors.
You can sync the Cost from NetSuite to Shopify using GraphQL-based product flows. The mapping in the product flows ensures that Cost is accurately transferred to Shopify.
Pre-requisite: Before syncing, ensure that the Cost field is added to the Saved Search results criteria in NetSuite.
To ensure seamless synchronization, configure the cost settings in the mapping correctly as explained below.
Configure mapping for cost field-
In the Flows > Product section, open the "Field Mappings" for the NetSuite Item to Shopify Product Add/Update flow.
-
Click Post products to Shopify. Scroll to the standard mappings for variants.
-
Click + to add a new row under the variants.
-
In the text field, type in inventoryItem and select the datatype as the object.
-
Click + at the inventoryItem level. In the text field, type in Cost and select the datatype as the string.
-
From the source field dropdown, select Price (Variant).
-
-
Click Save.
Similarly, you can also sync the harmonizedSystemCode from NetSuite to Shopify, using the GraphQL-based product flows.
The following fields in the table have Standard Mapping (Mandatory) and Standard Mapping pre-configured as out-of-the-box mappings in the product flow.
Important
Do not delete any Standard mapping (mandatory) mappings, as they are essential for the flow to function correctly.
Table 1. Product flow: REST to GraphQL mappings
|
Required Field |
Shopify GraphQL |
NetSuite |
Comments |
|---|---|---|---|
|
✓ |
product > id |
$.product_id |
standard mapping (mandatory) |
|
✓ |
product > title |
$.Display Name |
standard mapping (mandatory) |
|
product > descriptionHtml |
$.Sales Description |
standard mapping |
|
|
product > productType |
$.Shopify Product Type |
standard mapping |
|
|
product > tags |
$.Shopify Product Tags |
standard mapping |
|
|
product > files |
$.Images[*] |
standard mapping |
|
|
✓ |
product > variants > id |
$.variants.variant_id |
standard mapping (mandatory) |
|
product > variants > sku |
$.variants.Item Name (Variant) |
standard mapping |
|
|
product > variants > price |
$.variants.Price (Variant) |
standard mapping |
|
|
product > variants > barcode |
$.variants.UPC Code (Variant) |
standard mapping |
|
|
product > variants > inventoryPolicy |
$.variants.Shopify Enable Out Of Stock Selling (Variant) |
standard mapping |
|
|
product > variants > inventoryItem > measurement > weight > value |
$.variants.[Item Weight (Variant)] |
custom mapping |
|
|
product > variants > inventoryItem > measurement > weight > unit |
{{#compare variants.[Item Weight Units (Variant)] "==" "lb"}}POUNDS{{else}}{{#compare variants.[Item Weight Units (Variant)] "==" "kg"}}KILOGRAMS{{else}}{{#compare variants.[Item Weight Units (Variant)] "==" "g"}}GRAMS{{else}}{{#compare variants.[Item Weight Units (Variant)] "==" "oz"}}OUNCES{{else}}{{variants.[Item Weight Units (Variant)]}}{{/compare}}{{/compare}}{{/compare}}{{/compare}} |
custom mapping |
|
|
✓ |
product > variants > option1 |
$.variants.Variation Option 1 (Variant) |
standard mapping (mandatory) |
|
✓ |
product > variants > option2 |
$.variants.Variation Option 2 (Variant) |
standard mapping (mandatory) |
|
✓ |
product > variants > option3 |
$.variants.Variation Option 3 (Variant) |
standard mapping (mandatory) |
|
product > variants > compareAtPrice |
$.variants.Compare at Price (Variant) |
standard mapping |
|
|
see help article for guidance |
meta[*].Frame:Width (Meta) |
custom mapping (metafields) |
|
|
see help article for guidance |
meta[*].custom:hardware_image(Meta) |
custom mapping (metafields) |
The following screenshot displays the list of standard mappings for simple items.
The following screenshot displays the list of standard mappings for matrix items.
Note
If your business requirements do not require standard mapping fields (that are not marked as mandatory or required) you can delete them as needed.
The flow supports seamless syncing of the tracked field via the Shopify ProductSet mutation for both Item and Matrix item flows:
-
If no tracked field mapping exists, the integration app will automatically add one.
-
If a mapping already exists, your existing configuration remains unchanged.
There are certain limitations when using GraphQL-based flows. These details will help you understand the constraints and necessary adjustments for a seamless migration and enhanced functionality.
Limitations:
-
Price lists: The price list updates are supported for products with fewer than 100 variants during the first sync. For products with more than 100 variants, the initial sync (Create scenario) will not include price list updates for variants beyond 100. However, in subsequent runs (Update scenario), the price list details will sync correctly.
-
HS codes: The HS codes are supported only for products with fewer than 100 variants. HS code updates are not supported for products with more than 100 variants.
-
Real-time product ID and inventory item ID sync: The real-time flow for writing back product_id and inventory_item_id to NetSuite is constrained by Shopify webhooks, which support a maximum of 100 variants. For products with more than 100 variants, users must trigger or schedule the mass ID update flow to sync IDs efficiently.
-
Sync scopes: You will need to re-authorize the Shopify connection to sync the scopes for new products and any additions to the scope for existing products.
-
Variant position handling: In GraphQL-based product flows, variant positions must start from 1. This behavior differs from Shopify’s REST API, which allows variant positions to start from any number.
-
GraphQL requirement: Variant positions must begin with 1.
-
REST behavior: Variant positions can begin from any number
This is a known limitation on Shopify’s side, and they have acknowledged the discrepancy between the two APIs. Shopify is currently investigating the issue.
-
Additional information
Field mappings:
-
GraphQL-based flows use 2.0 mappings, which have been moved to the new Mapper 2.0 from the previous REST-based versions.
-
The metadata structure has also been updated and will vary in GraphQL-based flows, enhancing data organization and compatibility.
-
To update metafield information for both variants and the parent level:
-
Use the "Specify your Shopify metafield components for products and variants" setting under Settings > Product —this is preferred over mappings if you’re not using handlebars.
-
If you’re using handlebars to sync metafields, you must use the mapping approach instead. For details, see sync metafields.
-
Publish scopes: The GraphQL-based product flow gives you full control over publishing and unpublishing product publications for a specific sales channel.
To manage publication visibility in NetSuite, navigate to:
Item > eTail tab > Shopify > Shopify Product Visibility.
Product sync behavior: When the Sync published scope from NetSuite to Shopify setting is enabled:
-
You must define all sales channels in NetSuite where you want the product to remain published.
-
Any channel that is not listed in NetSuite and not selected under Inventory Item > eTail > Shopify > Shopify Product Visibility for the product will be removed from Shopify during the sync.
Example: A merchant has a product published to 5 channels in Shopify: Online Store, Google, X, Meta, and Shop.
In NetSuite, only 3 channels are listed under product visibility: Online Store, Google, and X. The merchant updates the field in NetSuite to select just Online Store and Google.
Result in Shopify:
-
Product stays published to the Online Store and Google
-
Product is unpublished from X, Meta, and Shop
In short, NetSuite becomes the source of truth — only the channels you list and select in NetSuite will remain active in Shopify.