Slize Unified Commerce — API documentation
The Slize Unified Commerce API: pricing and contract logic, checkout and order creation, orders and documents, products, stock, certificates and cutting — with request and response shapes.
Slize is the unified commerce layer over your systems of record, and this is the surface it exposes: consistent APIs for the B2B workflows that are hard to model anywhere else — contract pricing, delivery logic, cutting services, certificates and purchase history.
It is written for developers, solution architects and technical partners working on integrations, custom frontends or system-to-system connectivity. These are the same APIs that power the Slize storefront, customer self-service and sales dashboards, so nothing here is a reduced public subset.
Use them to:
- Integrate Slize with ERP, PIM, CRM or customer-facing applications
- Expose pricing, availability and ordering logic across several channels
- Support complex B2B workflows — cutting, certificates, delivery prioritisation
- Keep one source of truth for commerce logic across systems
Slize does not replace your ERP's APIs. It complements them: commerce-specific logic — pricing, availability, delivery, orders — resolves here and is exposed through one consistent contract, while the ERP stays the system of record.
Conventions
Paths below omit the base URL, written as {baseUrl} in the source document. Two path parameters recur throughout: {company} is the legal entity or market, and {account} is the customer account — which is what makes contract pricing, personalised stock and customer-specific item numbers resolve per buyer rather than per catalog.
Every operation is one of two kinds, and the distinction matters when you plan an integration:
- Live request — called synchronously, in the flow of a page or an order. Prices, stock, delivery dates, order lookups and file downloads are all live.
- Batch operation — a data exchange rather than an endpoint: products, categories, property metadata, stock lists, order and invoice lists, and certificate lists move this way. The payload shape is documented; there is no URL to call.
Price
Get price bracketsLive request
GET/api/v1/price-brackets/{company}/{account}
Quantity brackets for the account, with the alloy component calculated separately from the unit price.
- QuantityTo is the top of the bracket; the last bracket in a set returns null for it, meaning "and above".
Response
[
{
"Item": "25007",
"QuantityFrom": 0.0,
"QuantityTo": 99.0,
"TotalPrice": 33.5,
"CalculatedAlloy": 43.55,
"UnitPrice": 10.55
},
{
"Item": "11007",
"QuantityFrom": 0.0,
"QuantityTo": 107.0,
"TotalPrice": 33.5,
"CalculatedAlloy": 43.55,
"UnitPrice": 10.55
}
]Repurchasing priceBatch operation
Replacement-cost pricing for a set of items, converted into the requested currency.
Request
{
"Items": [
{
"Item": "string",
"ProductTypeName": "string",
"UnitWeight": "decimal",
"UnitLength": "decimal"
}
],
"CurrencyTo": "string"
}Response
[
{
"itemNumber": "A1001",
"Company": "DK",
"Value": 1250.75
},
{
"itemNumber": "A1002",
"Company": "DK",
"Value": 980.50
}
]Checkout
Checkout is where the sourcing decision is made. Delivery dates come in two shapes — combined, where the whole order ships together, and individual, where each warehouse ships on its own date — and both take the stock availability and warehouse priorities you want applied.
Get accountLive request
GET/api/v1/account/{company}/{account}
The account's commercial terms: payment, transport, delivery, currency, sales manager and payment address.
- account and currency are mandatory — every other field may be absent.
- address3 is nullable, and address2 is an empty string rather than null when unused.
Response
{
"name": "Test Web-Shop",
"account": "TEST-UA-01",
"payment": "33",
"paymentDescription": "Next Day Payment",
"transport": "POST-01",
"transportDescription": "Post delivery",
"delivery": "FREE",
"deliveryDescription": "Free delivery",
"currency": "EURO",
"defaultCertificate": false,
"salesManager": {
"firstName": "Anna",
"lastName": "Sørensen"
},
"paymentAddress": {
"country": "Ukraine",
"city": "Kyiv",
"address1": "Antonovicha 33",
"address2": "",
"address3": null,
"postalCode": "78900"
}
}Get delivery addressesLive request
GET/api/v1/account/delivery-addresses/{company}/{account}
Saved addresses for the account, each with its transport and delivery mode.
- Exactly one address has Primary: true.
- AddressReferenceCode is what Create sales order expects — not the address id.
Response
[
{
"Primary": true,
"AddressReferenceCode": "0137",
"CompanyName": "Slize Ltd",
"Country": "Ukraine",
"City": "Kyiv",
"PostalCode": "08702",
"Address1": "Antonovicha 33",
"Address2": null,
"Address3": null,
"Transport": "Car",
"TransportDescription": "Fast delivery",
"Delivery": "Express",
"DeliveryDescription": "Next-day delivery"
}
]Get delivery dates — combinedLive request
GET/v1/delivery-dates-combine/{company}/{account}
Available delivery dates for the address and the stock availability supplied, sourced as one shipment.
Request
{
"CompanyId": "6c37717c-42b1-490a-97cd-f0fbe1399180",
"AdressReferenceCode": "000365304",
"DeliveryMode": "0602",
"DeliveryType": 1,
"DaysReturned": 10,
"StockAvailability": [
{
"ProductId": "950d4281-0add-489e-a058-23f76ab15fcb",
"BasketItem": "15bc2240-25d2-4e10-9d20-1771515d4f74",
"OutOfStock": false,
"SourceFromMainStock": false,
"SourcingStocks": [
{ "ShipmentStock": "FI-10", "Quantity": 1, "UnitAmount": 1.0, "UnitLength": 1.0 }
]
}
],
"StockPriorities": {
"LV-10": { "Priority": 1, "WarehouseCode": "LV-10" },
"FI-10": { "Priority": 2, "WarehouseCode": "FI-10" },
"DK-10": { "Priority": 3, "WarehouseCode": "DK-10" },
"DE-10": { "Priority": 4, "WarehouseCode": "DE-10" },
"MS-10": { "Priority": 5, "WarehouseCode": "MS-10" },
"MS-50": { "Priority": 6, "WarehouseCode": "MS-50" }
}
}Response
{
"FirstStock": "LV-10",
"SecondStock": "DE-10",
"OutOfStock": false,
"DeliveryDates": [
{ "ReceiptDate": "3/5/2024 12:00:00 AM", "ShipDate": "3/5/2024 12:00:00 AM" },
{ "ReceiptDate": "3/6/2024 12:00:00 AM", "ShipDate": "3/6/2024 12:00:00 AM" },
{ "ReceiptDate": "3/7/2024 12:00:00 AM", "ShipDate": "3/7/2024 12:00:00 AM" }
]
}Get delivery dates — individualLive request
GET/v1/delivery-dates-individual/{company}/{account}
The same request, answered per warehouse, when lines ship separately.
Response
{
"DeliveryDates": {
"FI-10": {
"ReceiptDate": "2/29/2024 12:00:00 AM",
"ShipDate": "2/29/2024 12:00:00 AM"
},
"DE-10": {
"ReceiptDate": "3/5/2024 12:00:00 AM",
"ShipDate": "3/5/2024 12:00:00 AM"
}
}
}Create sales orderLive request
POST/v1/sales-order
Turns a basket into an order. Order type per line covers single items, bundles and cuts; sourcing stock and stock priorities decide where each line is picked; delivery dates can be combined or per warehouse.
- BasketType — 0 = Order, 1 = Quotation.
- BasketMode — 0 = None, 1 = OnePush, 2 = Upload.
- DeliveryType — 1 = SavedAddress, 2 = NewAddress, 3 = PickupAddress.
- DeliveryDateType — 1 = Combine (one shipment), 2 = Individual (per warehouse).
- SourcingVendorLogic — 0 = Base, 1 = DeltaInox, 2 = Sweden, 3 = Norway.
- OrderItems[].OrderType — 1 = Single, 2 = Bundle, 3 = Cut. The third line above is the cutting form: quantity in kg with a CutLength.
- The FIRST line in OrderItems is the shape of a basket line with no product resolved — ItemNumber: null and OutOfStock: true.
- Nullable: Seller, DeliveryDate, ShipDate, IndividualDeliveryDates, HardStamping, RestampCert, and the five Delivery* address fields (used only when DeliveryType is 2).
- DeliveryAddress in the response is null when the order ships to a pickup point.
Request
{
"BasketId": "7d8a52a1-aeb1-4f21-8bb6-378efbf6f81d",
"Seller": "[email protected]",
"BasketType": 0,
"BasketMode": 0,
"PutOrderOnHold": false,
"IsNeutralPacking": false,
"Notes": "",
"CompanyCode": "WA",
"AccountCode": "44-606",
"DeliveryDate": "2024-07-15T12:00:00",
"ShipDate": "2024-07-12T12:00:00",
"IndividualDeliveryDates": {
"DK-10": { "DeliveryDate": "2024-07-12T12:00:00", "ShipDate": "2024-07-11T12:00:00" },
"DE-10": { "DeliveryDate": "2024-07-15T12:00:00", "ShipDate": "2024-07-12T12:00:00" }
},
"OrderReference": "test 01",
"GoodsMark": "",
"CustomerEmail": "[email protected]",
"OrderConfirmationEmail": "",
"DefaultOrderConfirmationEmail": "",
"DeliveryType": 1,
"DeliveryDateType": 1,
"AddressReferenceCode": "0104",
"DeliveryCompanyName": null,
"DeliveryCountry": null,
"DeliveryCity": null,
"DeliveryPostalCode": null,
"DeliveryAddressStreet": null,
"SourcingVendorLogic": 0,
"OrderItems": [
{
"ItemNumber": null,
"Quantity": 0,
"LineReference": "",
"OutOfStock": true
},
{
"OrderType": 1,
"ItemNumber": "001-00010",
"Certificate": false,
"Quantity": 2,
"Unit": "pcs",
"Price": 100,
"Alloy": 0,
"HardStamping": false,
"RestampCert": false,
"CutLength": 0,
"Comment": "",
"OutOfStock": false,
"SourcingStock": [
{ "Warehouse": "DK-10", "Quantity": 1, "UnitAmount": 1.0, "UnitLength": 1.0 }
]
},
{
"OrderType": 3,
"ItemNumber": "001-00010",
"Certificate": false,
"Quantity": 0,
"Unit": "kg",
"Price": 7.01,
"Alloy": 0,
"CutLength": 10,
"Comment": "",
"OutOfStock": false,
"SourcingStock": [
{ "Warehouse": "DK-10", "Quantity": 1, "UnitAmount": 1.0, "UnitLength": 1.0 }
]
}
],
"StockPriorities": {
"LV-10": { "Priority": 1, "WarehouseCode": "LV-10" },
"FI-10": { "Priority": 2, "WarehouseCode": "FI-10" },
"DK-10": { "Priority": 3, "WarehouseCode": "DK-10" },
"DE-10": { "Priority": 4, "WarehouseCode": "DE-10" },
"MS-10": { "Priority": 5, "WarehouseCode": "MS-10" },
"MS-50": { "Priority": 6, "WarehouseCode": "MS-50" }
}
}Response
{
"DeliveryAddress": {
"Address1": "Hangøvej 2",
"Address2": "",
"Address3": "",
"PostalCode": "8200",
"Primary": true,
"City": "Aarhus N",
"Country": "DNK",
"Transport": "0104",
"TransportDescription": "Bytur",
"Delivery": null,
"DeliveryDescription": null,
"AddressReferenceCode": "000048021",
"CompanyName": "Aarhus Universitet"
}
}Orders and invoices
Lists arrive as batch operations; anything a customer opens on demand — an order, its lines, an invoice file, a packing document — is a live request. That split is what lets the self-service area stay current without polling.
Orders listBatch operation
Order headers for the account, for a list view.
Response
[
{
"OrderNumber": "string",
"Status": "string",
"AccountCode": "string",
"Company": "string",
"Reference": "string",
"TotalAmount": 0.000000,
"CreationDate": "2025-10-22T00:00:00Z",
"TotalLinesCount": 0,
"TotalWeight": 0.0
}
]Invoices listBatch operation
Invoice headers, keyed back to the order they belong to.
Response
[
{
"Company": "string",
"AccountCode": "string",
"OrderNumber": "string",
"InvoiceAmount": 0.000000,
"InvoiceNumber": "string",
"CreationDate": "2025-10-22T00:00:00Z"
}
]Get orderLive request
GET/api/v1/order/{company}/{orderNumber}
One order with its terms and both addresses.
Response
[
{
"OrderStatus": "Completed",
"OrderNumber": "12345",
"OrderDate": "2023-04-13T00:00:00",
"CustomerAccount": "ACME Corp.",
"CustomerOrderReference": "REF-123",
"OrderTotalAmount": 100.0,
"DeliveryTerms": "Ex Works",
"PaymentTerms": "Net 30",
"DeliveryModeCode": "UPS",
"DeliveryAddress": {
"AddressName": "John Smith",
"Street": "123 Main Street",
"City": "Kyiv",
"ZipCode": "02000",
"CountryRegionId": "UKR"
},
"InvoiceAddress": {
"Street": "456 Main Street",
"City": "Kyiv",
"ZipCode": "02000",
"CountryRegionId": "UKR"
}
}
]Get order linesLive request
GET/api/v1/order-lines/{company}/{orderNumber}
The lines of an order, each carrying its certificates by heat and batch number — which is what makes traceability answerable from the portal rather than by email.
Response
[
{
"ItemNumber": "ABC123",
"DeliveryDate": "2023-11-15T12:30:00",
"UnitConversionCode": "EA",
"Quantity": 10,
"LinePrice": 150.5,
"Comment": "Sample comment",
"Certificates": [
{ "ItemNumber": "CERT001", "InventBatch": "BATCH001", "HeatNumber": "HEAT001" },
{ "ItemNumber": "CERT002", "InventBatch": "BATCH002", "HeatNumber": "HEAT002" }
],
"Price": 15.99,
"LineWeight": 2.5,
"OrderType": 1,
"OrderTypeDescription": "Standard Order"
}
]Get order invoicesLive request
GET/api/v1/invoices/{company}/{account}?invoicesNumbers=item1&invoicesNumbers=item2
Invoice details for the numbers supplied, including outstanding debt per invoice.
Response
[
{
"invoiceNumber": "item1",
"invoiceDate": "2021-07-28T12:00:00Z",
"totalAmount": 300.55,
"dueDate": "2021-10-28T12:00:00Z",
"debt": 0.00
},
{
"invoiceNumber": "item2",
"invoiceDate": "2021-07-30T12:00:00Z",
"totalAmount": 900.00,
"dueDate": "2022-10-25T12:00:00Z",
"debt": 10.00
}
]Get invoice fileLive request
GET/api/v1/invoices/{company}/{invoiceNumber}/file
Returns the invoice file for an invoice number.
Get document typesLive request
GET/api/v1/order/{account}/{orderNumber}/doc-types
Which documents exist for an order, grouped by type.
Response
{
"OrderNumber": "string",
"DocTypes": {
"TypeName1": [
{
"Customer": "string",
"DocumentID": "string",
"OrderID": "string",
"DocumentType": "string"
}
],
"TypeName2": [
{
"Customer": "string",
"DocumentID": "string",
"OrderID": "string",
"DocumentType": "string"
}
]
}
}Get document fileLive request
GET/api/v1/invoices/{account}/{docType}/{orderNumber}/{documentId}/file
Returns a document file by document id.
Certificates
Certificate listBatch operation
Certificates available per item, identified by heat number and inventory batch.
Response
[
{
"Company": "string",
"OrderNumber": "string",
"ItemNumber": "string",
"HeatNumber": "string",
"InventBatch": "string"
}
]Get certificate fileLive request
GET/api/v1/certificate/{company}/{itemNumber}/{certificate}/file
Returns the certificate file for a certificate number.
Purchase history
Get purchase historyLive request
GET/api/v1/purchase-history
Incoming purchases, filterable by item, order, status and date range, with paging through Skip and Take.
Request
{
"ItemNumber": "ST-1020",
"Order": "PO-456789",
"Search": "steel",
"Status": "Received",
"Skip": 0,
"Take": 20,
"From": "2025-10-01T00:00:00Z",
"To": "2025-10-22T23:59:59Z"
}Response
[
{
"Supplier": "SteelWorks Ltd.",
"IncomingDate": "2025-10-22T14:30:00Z",
"Currency": "EUR",
"Status": "Received",
"Amount": 1200.50,
"Unit": "kg",
"Price": 4.25
},
{
"Supplier": "Metallia SpA",
"IncomingDate": "2025-10-20T11:00:00Z",
"Currency": "EUR",
"Status": "Received",
"Amount": 500.00,
"Unit": "m",
"Price": 5.10
}
]External item numbers
This is the group that makes a customer's own part numbers work as first-class references: the mapping is readable, creatable and deletable per account, so a buyer searches and orders with the numbers already in their own system.
Get external item numbersLive request
GET/api/v1/external-item-number/{company}/{account}
The full mapping of item numbers to the account's external references.
Response
[
{ "ItemNumber": "Item1", "ExternalItemNumber": "ExtItem1" },
{ "ItemNumber": "Item2", "ExternalItemNumber": "ExtItem2" },
{ "ItemNumber": "Item3", "ExternalItemNumber": "ExtItem3" }
]Get selected external item numbersLive request
GET/api/v1/external-item-number/selected/{company}/{account}
The mapping for a specific set of item numbers.
Request
[
"ItemNumber1",
"ItemNumber2",
"ItemNumber3"
]Response
[
{ "ItemNumber": "ItemNumber1", "ExternalItemNumber": "ExtItem1" },
{ "ItemNumber": "ItemNumber2", "ExternalItemNumber": "ExtItem2" },
{ "ItemNumber": "ItemNumber3", "ExternalItemNumber": "ExtItem3" }
]Create external item numberLive request
POST/api/v1/external-item-number/{company}/{account}
Adds a mapping; the response is the account's mapping after the change.
Request
{
"ItemNumber": "Item1",
"ExternalItemNumber": "ExtItem1"
}Response
[
{ "ItemNumber": "Item1", "ExternalItemNumber": "ExtItem1" },
{ "ItemNumber": "Item2", "ExternalItemNumber": "ExtItem2" }
]Delete external item numberLive request
DELETE/api/v1/external-item-number/{company}/{account}
Removes a mapping; the response is the account's mapping after the change.
Request
{
"ItemNumber": "Item1",
"ExternalItemNumber": "ExtItem1"
}Response
[
{ "ItemNumber": "Item2", "ExternalItemNumber": "ExtItem2" },
{ "ItemNumber": "Item3", "ExternalItemNumber": "ExtItem3" }
]Products
Product data moves in batch, and the shapes are large because industrial catalogs are: units and weights, primary and secondary categories, CAD drawings per format, and a translation block per language carrying its own properties, cutting rules and certificate flags.
ProductBatch operation
One record per item: dimensions, categories, images, drawings, and per-language translations with the property set behind the specification table.
- UnitConversionCode is the product’s unit code — "m" here, and the unit every quantity for this item is expressed in.
- ExternalCategoryId is the PRIMARY category; AdditionalCategories are secondary.
- Translations is keyed by culture, and each carries its own Properties — the same item can be cuttable in one market and not another.
Response
[
{
"ItemNumber": "556221",
"UnitConversionCode": "m",
"UnitWeight": 4.809,
"UnitLength": 6,
"UnitWidth": 4.77,
"ExternalCategoryId": 97871,
"AdditionalCategories": [97844, 97855],
"ExternalId": "39513",
"BundleOnly": false,
"IsContactNumber": false,
"Images": [
{ "Id": "290cf54c-62b4-40bd-bbb4-d0709b91bc43", "Name": "tube.jpg" }
],
"SkipStockFactor": false,
"Variant": null,
"ProductType": "Tubes",
"Strength": 0,
"Accounts": null,
"Drawings": {
"IGS": { "Id": "500a4a40-ff9e-417c-bc75-8c13c73d62e6", "Name": "39513.igs" },
"STP": { "Id": "290cf54c-62b4-40bd-bbb4-d0709b91bc43", "Name": "39513.step" },
"SLDPRT": { "Id": "95fc3edf-1c68-4e61-a77f-988fc81d671c", "Name": "39513.sldprt" }
},
"Translations": {
"EN": {
"Header": "18 x 2 mm Seamless precision tube EN 1.4541 EN 10216-5 TC2 EN 10305-1",
"Description": "tube",
"Dimension": "18 x 2 (6000 mm)",
"BundleSize": 56,
"HasCertificate": true,
"Cuttable": false,
"PublishOnWeb": false,
"MinCuttingLength": 2,
"MinCuttingWidth": 2,
"AdminCuttable": false,
"CutWidthAble": true,
"HasMaterialEmissionCertificate": false,
"Properties": {
"D365Commodity": "Seamless tube",
"ItemNumber": "556221",
"D365GradeAlloy": "EN 1.4541",
"ToleranceNorm": "EN 10305-1",
"D365ProductionNorm": "EN 10216-5 TC2",
"Diameter": "18",
"Wallthickness": "2",
"UnitWeight": "0.802",
"Length": "6000"
}
}
}
}
]CategoriesBatch operation
The category tree, with translations, imagery, and the filter and table layouts each category drives in the storefront.
Response
[
{
"Sequence": 18,
"Id": 97871,
"ParentId": 82679,
"Image": { "Id": "4a81667c-daed-4680-a86b-fdcd5fe0b742", "Name": "instrument.png" },
"Icon": { "Id": "068e7b19-50da-47fe-bc8c-a0b2aabd929c", "Name": "instrument-icon.png" },
"IconSVG": { "Id": "3d07a560-a281-4d29-bb2b-a942599f8f54", "Name": "instrumente.svg" },
"Translations": {
"EN": {
"MetaTitle": "High-Quality Instrument Collection",
"MetaKeywords": "instrument, precision tool, measurement",
"MetaDescription": "Discover our premium selection of instruments.",
"Name": "Instrument",
"Text": "Our instruments are engineered for accuracy and durability."
}
},
"Catalogs": ["DE"],
"Units": ["PCS"],
"PrimaryFilters": [
{ "Sequence": 1, "FieldName": "Diameter" },
{ "Sequence": 2, "FieldName": "Diameter1" },
{ "Sequence": 3, "FieldName": "Wallthickness" }
],
"SecondaryFilters": [
{ "Sequence": 1, "FieldName": "ProductionNorm" },
{ "Sequence": 2, "FieldName": "ProductionNorm2" }
],
"TableSequence": [
{ "Sequence": 0, "FieldName": "Diameter" },
{ "Sequence": 1, "FieldName": "Diameter1" }
],
"ProductSpecification": [
{ "Sequence": 1, "FieldName": "Diameter" },
{ "Sequence": 2, "FieldName": "Diameter1" }
],
"PriceSystemFilters": [
{ "Sequence": 1, "FieldName": "Diameter" },
{ "Sequence": 5, "FieldName": "GradeAlloy" }
]
}
]Product properties metadataBatch operation
What each property field is, per language — its type, whether it is a facet, and whether it is searchable. This is the contract behind the filters, so a new attribute becomes a filter without a release.
Response
[
{
"FieldName": "Diameter",
"Translations": {
"EN": { "Label": "Diameter" },
"DE": { "Label": "Durchmesser" }
},
"Type": "Number",
"IconType": "fa-star",
"Translatable": false,
"Facet": true,
"Searchable": false
},
{
"FieldName": "Grade",
"Translations": {
"EN": { "Label": "Grade" },
"DE": { "Label": "Grad" }
},
"Type": "String",
"IconType": null,
"Translatable": false,
"Facet": true,
"Searchable": true
}
]Stock and cutting
Stock availability listBatch operation
Availability per item and warehouse, with the stock factor and maximum order that personalise what a given customer is shown.
Response
[
{
"ItemNumber": "string",
"Warehouse": "string",
"InStock": "number",
"EstimatedDeliveryDate": "YYYY-MM-DD",
"StockFactor": 0.0,
"MaximumOrder": 0.0
}
]Get price for cuttingLive request
GET/api/v1/cutting-price/{company}/{account}?itemNumbers=1234&itemNumbers=4443
Cutting charges in quantity brackets, per item, priced either by quantity or by unit.
Response
[
{
"ItemNumber": "1234",
"QuantityFrom": 0.0,
"QuantityTo": 99.0,
"CuttingPrice": 33.5,
"Type": "Quantity|Unit"
},
{
"ItemNumber": "1234",
"QuantityFrom": 100.0,
"QuantityTo": null,
"CuttingPrice": 30.5,
"Type": "Quantity|Unit"
}
]Newsletter
Get newsletter statusLive request
GET/api/v1/newsletter?email={}&culture={}
Whether an address is subscribed, per culture.
- Status — 1 = subscribed, 2 = unsubscribed.
Response
{
"Status": 1
}Update newsletter statusLive request
POST/api/v1/newsletter
Subscribes or unsubscribes an address against a list.
- Status — 1 = subscribe, 2 = unsubscribe.
Request
{
"FirstName": "string",
"LastName": "string",
"Email": "string",
"Status": 1,
"Culture": "",
"ListId": ""
}The payloads above are the examples from the reference document, kept as they were written — comments, union notation and all — because the union values are the part that is hard to guess and easy to get wrong.
See what Slize does with your catalog and ERP landscape.
Book a walkthrough tailored to your systems and product complexity — or just say hello.