Skip to main content

Product fields & validation reference

This is a lookup reference for the fields on a product record: the identity fields that name and match it, the validation rules and numeric bounds enforced on create and edit, the behavior flags (sellability, lot-tracking, expiry), the shipping-dimension fields, and the endpoint that supplies the form dropdown values.

For the task of creating or editing a product, see Create a product and Edit a product's details. For what each product type means, see Product types explained.

Before you begin

  • Creating a product requires the products.create permission; editing requires products.update. Both also require the products read/write scope. See Product permissions reference.
  • Inventory figures (On Hand, Available, FIFO cost) aren't product fields — they're computed from real-time stock. See the Inventory guide for how those are derived.

Identity fields

These fields name a product and let SKU.io and your channels match it.

FieldPayload keyStored asUnique?Notes
SKUskuskuYesThe canonical reference for the product and its unique key. Required on create.
BarcodebarcodebarcodeNoUPC/EAN/GTIN. Free text — duplicates are allowed.
MPNmpnmpnNoManufacturer part number. Free text — duplicates are allowed.
NamenamenameNoDisplay name. Optional.
Brandbrand_namebrand_idSupply the brand name; SKU.io matches an existing brand or creates one, then stores its id. See Manage brands.

Key points about identity:

  • SKU is the identity of the product. It's the value returned as the product's reference and the field the uniqueness guard is built on. Once movements exist, changing a SKU can detach external links (for example some 3PL stock feeds match on the SKU string), so treat it as stable.
  • Barcode and MPN aren't unique-constrained. Two products can share a barcode or MPN. Use SKU when you need a guaranteed-unique key.
  • Brand is set by name, not id. Passing brand_name on create or edit finds-or-creates the brand, so a typo silently creates a new brand rather than erroring.

How search and typeahead rank these fields

Product search (Typesense via Scout) queries SKU, name, barcode, and MPN together, weighted so that SKU matches rank highest by a wide margin, then MPN, with name and barcode tied lowest. Barcode and MPN are only added to the search index when they have a value, so a blank barcode or MPN never dilutes a match. Typeahead pickers additionally push an exact SKU match to the top, then SKU prefix matches, ahead of everything else. Full column and lookup detail is in Products list columns, search & filters reference.

Create & edit validation rules

The create form (POST) and edit form (PUT) share one rule set, with the differences below. Fields not listed are optional and unvalidated beyond their type.

Required fields & uniqueness

FieldOn create (POST)On edit (PUT)
skuRequired, max:255, must be unique across all productsmax:255, unique except this product (so you can save without changing it)
typeRequired, one of the six product typesOptional — omit to keep the existing type
barcodeOptional, max:255Same
mpnOptional, max:255Same
nameOptional, max:255Same
brand_nameOptional, max:255Same

The six accepted type values are standard, bundle, kit, matrix, blemished, and manufactured. See Product types explained. Blemished products are created through a dedicated flow — see Create a blemished product.

Numeric bounds

All numeric fields are optional; when supplied they must fall within these bounds. lt means strictly less than.

FieldRule
weight, length, width, heightnumeric, lt:1000000
case_quantitynumeric, lt:10000
case_length, case_width, case_height, case_weightnumeric, lt:10000
expiration_offset_monthsinteger, 0120
target_stock_daysinteger, 1365
min_stock_levelinteger, min:0
unit_costnumeric, 0 to < 100000
default_pricenumeric, 0 to < 100000
default_supplier_pricenumeric, 0 to < 100000
pricing.*.price (tier prices)numeric, < 100000
suppliers.*.pricing.*.pricenumeric, 0 to < 100000
proforma_shipping_cost, proforma_landed_cost_percentagenumeric (no bound)

Relationship & existence checks

FieldRule
weight_unit, case_weight_unitone of lb, g, kg, oz
dimension_unit, case_dimension_unitone of in, cm, mm
categories.*Category must exist and be a leaf — attaching a non-leaf category fails with a non-leaf error. See How product taxonomy works.
suppliers.*.supplier_skuMust be unique per supplier — the same supplier SKU can't map to two products for one supplier. See Manage a product's suppliers.
sales_nominal_code_id, cogs_nominal_code_idMust exist in nominal codes. See Set a product's accounting.
default_tax_rate_idMust exist in tax rates
attributes.*.id / .nameAttribute must exist (by id) or is matched/created by name
stock_uom_idMust exist in units of measure. See Units of measure reference.
parent_idMust exist and can't be the product itself; a variation can't itself have a parent (no two-level nesting)

Bundle & kit component rules

Bundles and kits must always resolve to at least one component:

  • Creating a bundle or kit requires a non-empty components array.
  • Editing a product's type into a bundle or kit (when it has no existing components) also requires components.
  • Any save that submits components: [] for a bundle or kit is rejected — it would wipe the configuration.
  • Each component needs a valid product id and a quantity of at least 1.

Editing the components of a kit that already has inventory movements is refused (the request returns a 422 validation-style error, not a server error), because the kit's assembled stock is already committed. See Kit & bundle component reference and Build bundles & kits in the Workshop.

Unit defaulting on create

When you omit a unit field on create, it falls back to your account's default weight unit and dimension unit (from General Settings). Units you do submit are respected as-is — a product saved as kg stays kg. Edit behaves the same way: units you send are kept, omitted units are left unchanged.

Sellability & behavior flags

These booleans govern how a product behaves across selling, tax, and POS surfaces. All default appropriately for a normal sellable product unless you change them.

FlagPayload keyEffect
Sellableis_sellableWhen off, the product is treated as non-sellable — for example decoration consumables like thread or ink. Non-sellable products are hidden from channel listing pickers (the integration product-mapping modals request sellable products only).
Dropshippableis_dropshippableMarks the product as eligible for dropship fulfillment flows.
Decoration consumableis_decoration_consumableMarks a consumable used in decoration/production. A decoration consumable is the one product kind that's not decorable (it can't itself carry decoration).
Taxableis_taxable + default_tax_rate_idWhen taxable, default_tax_rate_id sets the default tax rate applied.
Show in registershow_in_registerControls POS register visibility. On a new product this defaults from the auto-show new products in register product setting (on by default) unless you set it explicitly on the form or an import.
Non-Sellable is a stock bucket too

is_sellable on the product is separate from the Non-Sellable on-hand quantity, which comes from stock held in non-sellable warehouse locations. Product On Hand includes Non-Sellable stock. See the Inventory guide for the stock buckets.

Listing a sellable product to a sales channel is out of scope here — that's covered in the Listings guide. See Products, channels & reporting (seams) for where product data hands off to channels.

Lot-tracking & expiry flags

These flags turn on lot/expiry handling and set its thresholds. The deep behavior — how lots are created, picked, and expired — lives in the Inventory area; this page only documents the fields on the product.

Flag / fieldPayload keyNotes
Lot trackedis_lot_trackedTurns on lot tracking for the product.
Lot tracking methodlot_tracking_methodRequired when is_lot_tracked is on. One of fifo (first-in, first-out) or fefo (first-expired, first-out).
Shelf life (days)shelf_life_daysInteger, min:1.
Near-expiry threshold (days)near_expiry_threshold_daysInteger, min:1.
Min remaining shelf life (days)min_remaining_shelf_life_daysInteger, min:0.
Expiry-aware availabilityexpiry_aware_availabilityWhen on, availability accounts for expiry.
Catch weight enabledcatch_weight_enabledVariable-weight handling flag (set outside the main form).
Manufacturing enabledmanufacturing_enabledManufacturing/assembly flag (set outside the main form).

For lot creation, FEFO/FIFO picking, and expiry availability behavior, see the Inventory guide.

Shipping fields

The product detail Shipping tab holds the physical dimensions used for FBA prep, case packing, and shipping calculations. Editing the tab requires the products.update permission and is subject to the product edit-lock — if another user is editing the product, the Edit button is disabled and names who holds the lock.

Product Dimensions

FieldPayload keyUnit field
Weightweightweight_unit (lb, g, kg, oz)
Lengthlengthdimension_unit (in, cm, mm)
Widthwidthdimension_unit
Heightheightdimension_unit

Case Shipping Details

These define how individual units pack into a shipping case, used for bulk and FBA inbound shipments.

FieldPayload keyUnit field
Case quantitycase_quantityUnits per case (shown in the product's stock unit of measure)
Case weightcase_weightcase_weight_unit (lb, g, kg, oz)
Case length / width / heightcase_length, case_width, case_heightcase_dimension_unit (in, cm, mm)
Expiration offset (months)expiration_offset_months0120; blank falls back to the app default of 10 months, used to pre-fill FBA inbound expiration dates
FBA prep instructionsfba_prep_instructionsFree text, max:255 (for example, polybagging, labeling)

The stock unit of measure that labels Case quantity is configured separately — see Configure a product's units of measure.

Form constants endpoint

The product form loads its dropdown options from a single endpoint rather than hardcoding them, so the values always match the back end enums.

GET /products/constants returns:

KeyContents
product_typesstandard, bundle, kit, matrix, blemished, manufactured
weight_unitslb, g, kg, oz
dimension_unitsin, cm, mm
attribute_typesSupported attribute value types — see Attribute fields & types reference
warehouse_typesWarehouse type enum
inventory_movement_typeInventory movement type enum
inventory_movement_statusInventory movement status enum

The endpoint requires the products read/write scope. It's read-only and carries no per-field permission of its own.

Next steps

Last verified: