# The Product Data Model in Norce Commerce Product Service **Product Model Overview:** The Norce Commerce Product model is hierarchical. The main Product entity (the "Product root") contains general product data and may include a list of variants. Each variant holds unique information, while the root holds shared data such as images, text, pricing, and availability. ![Product model](/assets/the-product-data-model-from-storm-api-new.b2fe95f37a4b7a9070523464eed0fa0924bfd79d4805a3a2943cb1b2852bf880.afe294b5.png) ## Product Model Structure The primary entity in Norce Commerce is the [Product](/api-reference/schemas/product#product). This entity contains data for display to end customers and for frontend application logic, enabling custom business logic. The Product model is organized hierarchically: - **Product root:** Holds general/shared data. - **Variants:** Each variant contains unique information. > **Note:** Norce does not have a fixed "master" Product. When displaying variants, one is designated as the Product root, but this is not predetermined. Variants form a "cluster" with shared and unique data. ## Product Elements Products without variants store all data in the root Product element. The Product entity includes various types of information, such as identifiers, text fields, parametrics, flags, images, pricing, and availability. [View the full Product Schema in the API reference.](/api-reference/schemas/product#product) details summary Example: Product without variants ```JSON { "Id": 31234587, "Name": "Forest Helmet Technical", "Description": "", "PartNo": "PRD0001273", "SubHeader": "", "Manufacturer": { "Id": 1685, "Name": "Husqvarna", "PartNo": "Foresthelmettechnical", "LogoPath": "", "LogoKey": null, "UniqueName": "husqvarna" }, "Image": null, "CampaignImage": null, "LargeImage": null, "ThumbnailImage": null, "Files": [], "FlagIdSeed": "915", "Price": 2191.20, "PriceCatalog": null, "PriceRecommended": null, "PriceFreight": null, "PriceFreightVatRate": null, "VatRate": 1.25, "RecommendedQuantity": 1.000, "OnHand": { "Value": 0.000, "IncomingValue": 0.000, "NextDeliveryDate": null, "LeadtimeDayCount": 0, "LastChecked": null, "IsActive": true, "IsReturnable": false, "Info": null }, "OnHandStore": { "Value": 0.000, "IncomingValue": 0.000, "NextDeliveryDate": null, "LeadtimeDayCount": null, "LastChecked": null, "IsActive": false, "IsReturnable": false, "Info": null }, "OnHandSupplier": { "Value": 0.000, "IncomingValue": 0.000, "NextDeliveryDate": null, "LeadtimeDayCount": 5, "LastChecked": "/Date(1487085384177+0100)/", "IsActive": true, "IsReturnable": false, "Info": null }, "Variants": [], "PriceListId": 1, "Key": "4ad9d701-170d-4446-a7b5-f09835cf71e0", "Updated": "/Date(1554808947000+0200)/", "NavigationNodeKey": "8cf3381a-4205-4fd8-8d90-034e8fa6e249", "CategoryId": 41722, "CategoryName": "Forest & Garden", "ImageKey": "3a689ca9-5d6c-481d-a080-66149fbd6034", "VariantParametrics": [ { "Name": "Cylindervolym", "Value": "123 cm3", "Id": 12330, "ValueId": null, "Description": "", "ValueDescription": null, "IsPrimary": true, "ValueIdSeed": "", "Value2": "123", "Uom": "cm3", "GroupId": 0, "GroupName": null, "SortOrder": 4 } ], "StatusId": 1, "MetaTags": "", "MetaDescription": "", "VariantName": null, "DescriptionHeader": "", "UniqueName": "forest-helmet-technical", "StockDisplayBreakPoint": null, "Parametrics": [ { "Name": "Cylindervolym", "Value": "123 cm3", "Id": 12330, "ValueId": null, "Description": "", "ValueDescription": null, "IsPrimary": true, "ValueIdSeed": "", "Value2": "123", "Uom": "cm3", "GroupId": 0, "GroupName": null, "SortOrder": 4 } ], "Families": [], "IsBuyable": true, "SubDescription": "", "Uom": "st", "UomCount": 1.000, "EanCode": "", "Type": 1, "Categories": [ { "Id": 41722, "Value": "Forest & Garden", "Code": "1010" }, { "Id": 41791, "Value": "Smycken", "Code": "" } ], "IsRecommendedQuantityFixed": false, "PopularityRank": null, "CostPurchase": 1202.63, "CostUnit": 0.00, "Title": null, "ActualWeight": 0.00, "IsDropShipOnly": false, "Synonyms": null, "IsSubscribable": false, "UnspscCode": "", "PriceStandard": 0.00, "Width": null, "Height": null, "Depth": null } ``` ## Product Identifiers Each product has several identifiers: - **Id:** Internal, globally unique within a Norce Commerce environment. - **PartNo:** Exposed/imported from external systems (e.g., ERP). - **UniqueName:** SEO-friendly, language-specific identifier. - **Manufacturer.PartNo:** Unique for the specified manufacturer. You can retrieve product information using: - [GetProduct by Id](/api-reference/services/productservice/openapi/products/getproduct) - [GetProductByPartNo](/api-reference/services/productservice/openapi/products/getproductbypartno) - [GetProductByUniqueName](/api-reference/services/productservice/openapi/products/getproductbyuniquename) > **Note:** "Environment" refers to contexts like "Prod" or "Stage." Ids are unique within an environment but not across environments. ## Product Text Information Product entities include language-specific fields (e.g., `Name`, `Description`, `Header`). The language is determined by the application's default or the specified culture code. If no text exists for a culture, a fallback language can be set. ## Parametrics **Parametrics** are structured product attributes (e.g., boolean, integer, decimal, text, html, list, multiple list). They can be grouped by `GroupName` and are found in the `Parametrics` element. - For list-type parametrics, use [ListParametricInfo](/api-reference/services/productservice/openapi/parametric/listparametricinfo) and [ListParametricValues](/api-reference/services/productservice/openapi/parametric/listparametricvalues2) to look up values. > **Note:** For products without variants, `VariantParametrics` contains the same information as `Parametrics`. ## Product Flags The `FlagIdSeed` field lists flag IDs (comma-separated). Use [ListFlags](/api-reference/services/productservice/openapi/flags/listflags) and [ListFlagGroups](/api-reference/services/productservice/openapi/flags/listflaggroups) to resolve flag details. Flags are often used to segment business logic (e.g., special purchase handling). ## Images and Files Images and files are identified by a GUID (e.g., `ImageKey`, `Files`). The file type is indicated by the `Id` field. Use [ListFileTypeIds](/api-reference/services/productservice/openapi/files/listfiletypeids) to get file type names. To access an image or file: ``` https://[clientname].[environment].cdn-norce.tech/[filekey] ``` For Norce Storm: ``` https://[clientname].cdn.storm.io/[filekey] ``` You can resize images using query parameters (see [Image Scaling and CDN documentation](/legacy/stormapiclient-images-cdn)). ## Price Information Norce Commerce Services returns the **Best price** (lowest valid price). The `Price` field is excluding VAT; `PriceIncVat` includes VAT. `PriceListId` identifies the price list. `PriceStandard` holds the standard price for comparison. `CostUnit` and `CostPurchase` are included for margin calculations. ## On Hand (Availability) Information Product availability is provided in `OnHand` objects: - **OnHand:** Aggregated stock from all relevant warehouses. - **OnHandStore:** Stock from specified stores. - **OnHandSupplier:** Availability from the primary supplier. Each object includes: - `Value`: Current stock quantity - `IncomingValue`: Incoming stock - `NextDeliveryDate`: Next restock date - `LeadTimeDayCount`: Estimated delivery time (relative value) - ...and more > **Note:** `LeadTimeDayCount` is a relative value (e.g., days, hours); interpretation is up to the client. [Read more about availability structure.](/solution-portal/detailed-design/availability-structure) ## Buying Information Fields to assist with buying logic: - **IsBuyable:** Indicates if the product can be purchased. - **RecommendedQuantity:** Suggested default quantity for basket. - **IsRecommendedQuantityFixed:** If true, only multiples of `RecommendedQuantity` are allowed. - **StockDisplayBreakpoint:** Used to determine how to display availability (e.g., show "low stock" if below breakpoint). > **Note:** Always validate "is buyable" in your backend. For example, prevent purchase if out of stock. [See example.](/developer-portal/app-development/working-with-products-and-variants#is-buyable)