Skip to main content
PUT
Update a product (PUT)

Authorizations

Authorization
string
header
required

Authenticate using a bearer token. To create a token, navigate to /settings/api-tokens and click Create API Token.

Body

application/json
name
string

Product name

Maximum string length: 200
category_id
integer

ID of the product category

category
object | null

Product category information

sku
string

Internal SKU. Changing this value requires the skus.update.sku permission; the request returns 403 if the authenticated token's role lacks it. Omitting the field or sending the same value as the current SKU skips the check.

Maximum string length: 100
qty_low_alert
integer | null

Quantity threshold for low stock alerts

qty_reorder_threshold
integer | null

Quantity threshold for reordering

qty_minimum
integer | null

Minimum quantity to maintain

supplier_id
integer | null

ID of the preferred supplier

supplier
object | null

Product preferred supplier information

distribution_template_id
integer | null

ID of the distribution template (size curve) to assign to this product. Pass null to clear the current assignment. Use GET /products/{productId}/distribution-template/candidates to find compatible templates for a master SKU.

grid_template_category_id
integer | null

ID of the variant distribution group (size-curve category) to assign to this product. Omitting it or passing null leaves the current group unchanged. Unlike distribution_template_id, this does not pin a single curve: the group is combined with each destination warehouse to pick the right curve per buy. Returned as distribution_template_category on the product response. Returns 422 if the group's axes don't fit the product.

image_url
string | null

URL to product image

Maximum string length: 255
sellable
boolean | null

Whether the product can be sold

lot_tracking
boolean | null

Whether to track product by lots

is_drop_ship_item
boolean | null

Flag the product as a drop-ship item. A preference marker only — it does not currently change fulfillment-order routing or purchase-order creation.

taxable
boolean | null

Whether the product is subject to sales tax. Defaults to true when omitted.

sub_category_id
integer | null

ID of the product subcategory

subcategory
object | null

Product sub-category information

default_receiving_location_id
integer | null

Default location ID for receiving this product

default_assembly_location_id
integer | null

Default location (bin) ID where assembled goods (BOM output) are credited for this product. When set, it is used as the destination when defaulting assembly/disassembly work, falling back to default_receiving_location_id and then the warehouse default.

description
string | null

Product description

wholesale_price
number<float> | null

Wholesale price

Required range: x >= 0
retail_price
number<float> | null

Retail price

Required range: x >= 0
unit_cost
number<float> | null

Cost per unit. Interpreted in the currency given by unit_cost_currency; when that is omitted, unit_cost is the tenant base-currency inventory cost.

Required range: x >= 0
unit_cost_currency
string | null

Optional ISO currency code for unit_cost. Omit (or send null) to treat unit_cost as the base-currency inventory cost (existing behavior; any stored supplier purchase price is left untouched). Send the tenant base currency to set the base cost explicitly and clear a foreign-currency purchase price on the preferred supplier. Send the preferred supplier's default currency to store unit_cost as the supplier purchase (FOB) price on that supplier's SKU; it is converted at today's exchange rate into the base-currency inventory cost. Any other currency, or a supplier currency without a preferred supplier that has a currency, returns 422 keyed on unit_cost_currency. Only applies when unit_cost is also sent.

Example:

"EUR"

manufacturing_fee
number<float> | null

Manufacturing fee per unit

Required range: x >= 0
estimated_landed_cost
number<float> | null

Planner's estimated landed cost per unit, stored on the product. Separate from the computed landed_cost. Uses the same currency as the product's other costs (there is no separate currency field). Send null to clear it.

Required range: x >= 0

Product design URL or link. Send null to clear it.

Maximum string length: 2000
product_weight
object

Product weight. Accepts a single {unit, value} object or an array of such segments (a compound weight like 4 lb + 6 oz is written as two entries and summed).

Accepted units. Imperial units are stored as-is: lb/lbs (pounds) and oz/ozs (ounces). Metric units are accepted on input and converted to ounces at storage — g/gram/grams and kg/kgs/kilogram/kilograms. Because metric is converted, the input unit is not round-tripped: a weight submitted in grams or kilograms reads back in ounces.

Rejected input (400). A bare number with no unit; a comma inside a number (2,5kg — ambiguous decimal vs. thousands separator, use 2.5kg); a negative value; mixing metric and imperial units in one weight (e.g. 1 lb (454 g)); or repeating a metric unit (e.g. 3kg / 2.8kg) — these read as the same weight written twice rather than a total.

dimensional_weight
object

Product weight. Accepts a single {unit, value} object or an array of such segments (a compound weight like 4 lb + 6 oz is written as two entries and summed).

Accepted units. Imperial units are stored as-is: lb/lbs (pounds) and oz/ozs (ounces). Metric units are accepted on input and converted to ounces at storage — g/gram/grams and kg/kgs/kilogram/kilograms. Because metric is converted, the input unit is not round-tripped: a weight submitted in grams or kilograms reads back in ounces.

Rejected input (400). A bare number with no unit; a comma inside a number (2,5kg — ambiguous decimal vs. thousands separator, use 2.5kg); a negative value; mixing metric and imperial units in one weight (e.g. 1 lb (454 g)); or repeating a metric unit (e.g. 3kg / 2.8kg) — these read as the same weight written twice rather than a total.

product_length
number<float> | null

Length of the product (in inches)

Required range: x >= 0
product_width
number<float> | null

Width of the product (in inches)

Required range: x >= 0
product_height
number<float> | null

Height of the product (in inches)

Required range: x >= 0
box_weight
object

Product weight. Accepts a single {unit, value} object or an array of such segments (a compound weight like 4 lb + 6 oz is written as two entries and summed).

Accepted units. Imperial units are stored as-is: lb/lbs (pounds) and oz/ozs (ounces). Metric units are accepted on input and converted to ounces at storage — g/gram/grams and kg/kgs/kilogram/kilograms. Because metric is converted, the input unit is not round-tripped: a weight submitted in grams or kilograms reads back in ounces.

Rejected input (400). A bare number with no unit; a comma inside a number (2,5kg — ambiguous decimal vs. thousands separator, use 2.5kg); a negative value; mixing metric and imperial units in one weight (e.g. 1 lb (454 g)); or repeating a metric unit (e.g. 3kg / 2.8kg) — these read as the same weight written twice rather than a total.

box_length
number<float> | null

Length of the box (in inches)

Required range: x >= 0
box_width
number<float> | null

Width of the box (in inches)

Required range: x >= 0
box_height
number<float> | null

Height of the box (in inches)

Required range: x >= 0
carton_weight
object

Product weight. Accepts a single {unit, value} object or an array of such segments (a compound weight like 4 lb + 6 oz is written as two entries and summed).

Accepted units. Imperial units are stored as-is: lb/lbs (pounds) and oz/ozs (ounces). Metric units are accepted on input and converted to ounces at storage — g/gram/grams and kg/kgs/kilogram/kilograms. Because metric is converted, the input unit is not round-tripped: a weight submitted in grams or kilograms reads back in ounces.

Rejected input (400). A bare number with no unit; a comma inside a number (2,5kg — ambiguous decimal vs. thousands separator, use 2.5kg); a negative value; mixing metric and imperial units in one weight (e.g. 1 lb (454 g)); or repeating a metric unit (e.g. 3kg / 2.8kg) — these read as the same weight written twice rather than a total.

carton_length
number<float> | null

Length of the carton (in inches)

Required range: x >= 0
carton_width
number<float> | null

Width of the carton (in inches)

Required range: x >= 0
carton_height
number<float> | null

Height of the carton (in inches)

Required range: x >= 0
shipping_weight
object

Product weight. Accepts a single {unit, value} object or an array of such segments (a compound weight like 4 lb + 6 oz is written as two entries and summed).

Accepted units. Imperial units are stored as-is: lb/lbs (pounds) and oz/ozs (ounces). Metric units are accepted on input and converted to ounces at storage — g/gram/grams and kg/kgs/kilogram/kilograms. Because metric is converted, the input unit is not round-tripped: a weight submitted in grams or kilograms reads back in ounces.

Rejected input (400). A bare number with no unit; a comma inside a number (2,5kg — ambiguous decimal vs. thousands separator, use 2.5kg); a negative value; mixing metric and imperial units in one weight (e.g. 1 lb (454 g)); or repeating a metric unit (e.g. 3kg / 2.8kg) — these read as the same weight written twice rather than a total.

shipping_length
number<float> | null

Shipping length (in inches)

Required range: x >= 0
shipping_width
number<float> | null

Shipping width (in inches)

Required range: x >= 0
shipping_height
number<float> | null

Shipping height (in inches)

Required range: x >= 0
pallet_weight
object

Product weight. Accepts a single {unit, value} object or an array of such segments (a compound weight like 4 lb + 6 oz is written as two entries and summed).

Accepted units. Imperial units are stored as-is: lb/lbs (pounds) and oz/ozs (ounces). Metric units are accepted on input and converted to ounces at storage — g/gram/grams and kg/kgs/kilogram/kilograms. Because metric is converted, the input unit is not round-tripped: a weight submitted in grams or kilograms reads back in ounces.

Rejected input (400). A bare number with no unit; a comma inside a number (2,5kg — ambiguous decimal vs. thousands separator, use 2.5kg); a negative value; mixing metric and imperial units in one weight (e.g. 1 lb (454 g)); or repeating a metric unit (e.g. 3kg / 2.8kg) — these read as the same weight written twice rather than a total.

pallet_length
number<float> | null

Length of the pallet (in inches)

Required range: x >= 0
pallet_width
number<float> | null

Width of the pallet (in inches)

Required range: x >= 0
pallet_height
number<float> | null

Height of the pallet (in inches)

Required range: x >= 0
units_per_carton
number<float> | null

Number of units per carton (Shipping & Packing). Omit to leave unchanged. Setting units_per_carton or units_per_pallet also updates the product's Carton / Pallet unit conversion, as saving in the app does.

Required range: x >= 0
cartons_per_pallet
number<float> | null

Number of cartons per pallet (Shipping & Packing). Omit to leave unchanged. Setting units_per_carton or units_per_pallet also updates the product's Carton / Pallet unit conversion, as saving in the app does.

Required range: x >= 0
units_per_pallet
number<float> | null

Number of units per pallet (Shipping & Packing). Omit to leave unchanged. Setting units_per_carton or units_per_pallet also updates the product's Carton / Pallet unit conversion, as saving in the app does.

Required range: x >= 0
upc
string | null

UPC/Barcode. Changing this value requires the skus.update.upc permission; the request returns 403 if the authenticated token's role lacks it. Omitting the field or sending the same value as the current UPC skips the check.

default_supply_method
enum<string> | null

Default supply mode used when planning replenishment for this product. Determines whether the system expects to purchase, drop-ship, assemble, or pull from on-hand stock when supplying demand.

Available options:
purchase,
vendor_supplied,
assemble,
on_hand,
assembly_order,
buy_and_ship,
brand_supplied
Maximum string length: 50
priority_list_id
integer | null

ID of the fulfillment priority list to assign to this product

custom_fields
object | null

Custom field values, keyed by label. Only the labels sent are changed. Sending null, "" or [] for a label clears that field's value (dropdown fields included); an empty value for a label that is not defined is ignored.

tags
string[] | null

Tags to associate with the product

default_selling_unit_id
integer | null

ID of the unit of measure this product is sold in.

If omitted (along with selling_uom), Luminous defaults it to the account's base unit of measure (e.g. ea under the Quantity unit class). The request is rejected only if the account has no unit of measure configured at all.

Required range: x >= 1
default_purchase_unit_id
integer | null

ID of the unit of measure this product is purchased in.

If omitted (along with purchase_uom), Luminous defaults it to the account's base unit of measure (e.g. ea).

Required range: x >= 1
unit_class_id
integer | null

ID of the unit class this product's units belong to (e.g. Quantity).

If omitted, Luminous defaults it to the unit class of the account's base unit.

Required range: x >= 1
selling_uom
object | null

Selling unit of measure by name — an alternative to default_selling_unit_id. When default_selling_unit_id is not provided, the named UOM is resolved to its ID.

purchase_uom
object | null

Purchase unit of measure by name — an alternative to default_purchase_unit_id. When default_purchase_unit_id is not provided, the named UOM is resolved to its ID.

product_variants
object[] | null

Variant option taxonomy for the product — the axes (e.g. Size, Color) and the allowed terms on each axis.

You almost never need to set this. Tag each child SKU under variants[].product_variants with the terms it represents instead, and Luminous will extend the parent taxonomy automatically as the union of every term used by the children. Setting this directly is only useful as an escape hatch (e.g. seeding an empty option set, or pruning a term no child uses).

Returned on the response as variant_attributes (same shape).

variant_template

A variant template to expand into child SKUs, given as either the template's id (integer) or its name (string). When set on a master product, the template's option axes are expanded into child variant SKUs — the same one-click "generate variants" step available in the SKU form, reachable from the API.

Rules:

  • Ignored when you also send an explicit variants array — being specific always wins over a preset.
  • Idempotent — skipped when the product already has child variants, so re-sending the same request does not duplicate them.
  • An unknown template name/id fails loudly with a 422 validation error rather than silently producing a master with no variants.
variants
object[] | null

Product variants

boms
integer[] | null

Array of BOM IDs to attach to the product. Omit this field entirely to leave the product's existing BOM associations unchanged (partial updates do not touch BOMs unless boms is provided). When the field is provided, it replaces all existing BOM associations: pass an array of IDs to set them, or null/an empty array to detach all BOMs.

BOM ID

Response

Successful response

data
object