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)
- Build GraphQL queries
- Map metafields at product level using the saved search
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 the REST-based product flows and enable the GraphQL flows.
- Reauthorize the Shopify connection: After enabling the GraphQL flows, reauthorize the Shopify connection.
-
Recreate custom mappings: If you implemented custom
mappings in the REST flows, configure equivalent mappings in the
following GraphQL flows:
- NetSuite item to Shopify product (add or update)
- 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 from REST-based product flows to GraphQL-based product flows:
- Open your Shopify–NetSuite integration app.
-
Navigate to Flows > Product.
-
Verify the SKU field mapping in your saved search: Before enabling the GraphQL flows, confirm which NetSuite field you use as the SKU.
If you use the default Name/Item ID field, no action is required. If you use an alternate field, such as UPC Code, EAN, or a custom field, map that field under the Item Name (Variant) custom label in your saved search results.
The GraphQL flows read SKUs exclusively from this label. If the SKU value is not mapped there, inventory lookups return empty results and items cannot be located or updated. See SKU field configuration for GraphQL flows and Error: Inventory item does not have inventory tracking enabled for more information.
-
Turn on the toggle for the following GraphQL flows:
- NetSuite item to Shopify product (add or update)
- NetSuite matrix item to Shopify product (add or update)
-
Reauthorize the Shopify connection: Reauthorize the connection if you use the Sync published scope from NetSuite to Shopify setting. If you enable this setting after reauthorization, reauthorize the connection again to sync the scopes.
For more information, see Settings.
Note
If you enable the Sync published scope from NetSuite to Shopify setting before authorizing the connection, you will see the following 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 implemented custom mappings in the REST flows, configure equivalent mappings in the following GraphQL flows:
- NetSuite item to Shopify product (add or update)
- NetSuite matrix item to Shopify product (add or update)
The GraphQL-based Product API uses the productSet mutation described in the Shopify productSet mutation article. You can add only the fields supported by this mutation to custom mappings.
-
Turn off the toggle for the following REST-based 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 flows: After enabling the GraphQL flows, schedule them according to your business requirements. You can refer to the existing REST-based flow schedules and replicate the same settings.
-
Update the saved searches for the 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.
- 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 data type as string.
-
From the source field dropdown, select Item 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 "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 an 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 > 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.
Configure the NetSuite SKU field for GraphQL flows
The Item Name (Variant) is a custom label in your NetSuite saved search, not a fixed field.
The GraphQL-based product and inventory flows resolve SKUs exclusively from this label. If your account uses the default identifier (Name/Item ID) as its SKU, this is already mapped correctly out of the box. But if you use an alternate field as your SKU, for example, UPC Code, EAN, or another custom field, you must map that field under the Item Name (Variant) label in your saved search's result columns.
If the actual SKU value isn't mapped under this label, the flow's inventory lookup query returns no results. The flow can't locate or update the corresponding inventory item, even though the item exists and its other configuration is correct.
- In NetSuite, open the saved search used to sync items or matrix items for these flows.
- In the search's Results columns, locate (or add) the column mapped to the Item Name (Variant) custom label.
- Set this column's source field to whichever NetSuite field holds your actual SKU value (for example, UPC Code).
- In the flow's field mappings, confirm the SKU mapping (product > variants > sku) still points to Item Name (Variant).
Track inventory for variants
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.
Troubleshoot "inventory tracking enabled" error
Why do I receive the “Inventory item does not have inventory tracking enabled” error?
A: Data flows:
GraphQL-based inventory and product flows:
- Shopify product ID to NetSuite item (mass update)
- NetSuite item to Shopify product (add or update)
Error message:
{"errors":["Inventory item does not have inventory tracking enabled"]}
This error can occur for either of the following reasons. Because both causes return the same error message, check the Shopify inventory setting first, followed by the NetSuite saved search configuration.
Scenario 1: Track quantity is disabled for the Shopify variant
Shopify can update inventory for a variant only when inventory tracking is enabled. If Track quantity is disabled, Shopify does not have an inventory record for the flow to update.
To resolve the error:
- In the Shopify admin, open the affected product.
- Select the variant reported in the error.
- In the Inventory section, enable Track quantity.
- Save the variant.
- Run the flow again.
Scenario 2: The Item Name (Variant) column does not use the correct SKU field
The GraphQL-based flows identify SKUs using the NetSuite saved search column labeled Item Name (Variant). If your account stores SKUs in another field, such as UPC Code, that field must be assigned the Item Name (Variant) custom label.
If the label is assigned to the wrong field, the flow cannot find the inventory item and returns the inventory-tracking error even when Track quantity is enabled.
To resolve the error:
- In NetSuite, open the saved search used to sync items.
- Go to the saved search results.
- Find the column with the Item Name (Variant) custom label.
- Set the column’s source field to the field containing the SKU value, such as UPC Code.
- In the flow’s field mappings, update the SKU mapping to reference the corrected field.
- Run the flow again.
For more information, see SKU field configuration for GraphQL flows.
Related articles