Skip to content

Catalog Product — Update

Updates a catalog product (any of the 7 types). This is a partial patch — send only the fields you want to change. Omitted fields keep their current value.

Endpoint

EndpointMethod
/api/admin/catalog/products/{id}PUT

Path parameters

FieldTypeRequiredNotes
idintegeryesProduct ID.

Query parameters

ParamDefaultNotes
localestore defaultThe locale that translatable fields (name, description, short_description, meta fields, …) are written to. One locale per request — repeat the call with a different ?locale= to edit another translation.
channelstore defaultThe channel used for channel-scoped attribute values.

Editing attributes by code

Every attribute on the product's family is editable by its code, sent at the top level of the JSON body (snake_case). This includes the common fields and any family-specific ones:

Field codeNotes
name, url_key, short_description, descriptionTranslatable — written to the requested ?locale=.
meta_title, meta_keywords, meta_descriptionSEO fields (translatable).
price, weightDecimal as string.
status, new, featured, visible_individually, guest_checkoutBoolean flags as 0 / 1.
tax_category_idExisting tax category id.
color, size, brand, product_number, …Any family-specific attribute, by its code.

Translatable fields write to the requested locale only — pass ?locale=fr&channel=default to target the French translation; the other locales are untouched.

Replace-on-send relations

These fields replace the product's current set when present, and are preserved when omitted:

FieldNotes
categoriesint[] — the product's category assignment.
channelsint[] — the product's channel assignment.
up_sells, cross_sells, related_productsint[] — product relation lists.

Type-structure fields

The type-specific structure keys replace that structure when sent — send the full set. See the examples: dropdown for the verified payload of each:

TypeFieldNotes
downloadabledownloadable_links, downloadable_samplesKeyed map of link/sample rows.
groupedlinksKeyed map of { associated_product_id, qty, sort_order }.
bundlebundle_optionsKeyed map of option groups (typeradio / checkbox / select / multiselect) each with a products map.
configurablevariantsKeyed by variant product id (from the create response or detail variants[].id). Replace-semantics — send every variant to keep.
bookingbookingObject with type (default / appointment / event / rental / table) plus sub-type fields (slots / tickets / pricing).

Sub-resources are not updated here

images, videos, inventories, and customer_group_prices are not handled by this endpoint — they have dedicated endpoints. If sent, they are ignored and noted in the _warnings array on the response:

Response

200 OK returning the full product detail payload — same shape as GET /api/admin/catalog/products/{id}.

_warnings is an array of human-readable strings; it is empty when nothing was dropped, and non-empty (naming each dropped sub-resource field and the endpoint it should be sent to instead) when sub-resource fields were stripped.

Errors

HTTPCause
401 UnauthorizedMissing or invalid admin Bearer token.
403 ForbiddenAdmin role lacks catalog.products.edit.
404 Not FoundProduct not found.
422 Unprocessable EntityValidation failure (duplicate SKU / url_key, invalid boolean, special_price ≥ price, invalid date range).

Released under the MIT License.