Skip to main content
Create global catalog attributes from your own server code, for example when you seed a marketplace or import a taxonomy from a product information system.

Before you begin

You need the following:
  • A Mercur server: an API app with @mercurjs/core registered through withMercur()
  • Workflow imports: every workflow on this page comes from @mercurjs/core/workflows

Create the attribute

1

Run createProductAttributesWorkflow from a route

The workflow takes a list of attributes, each with its values, and returns the created records.
src/api/admin/catalog-import/attributes/route.ts
Leaving out product_id makes the attribute global. The service derives the handle material and a handle for each value.
2

Scope it to categories

Pass category_ids to link the attribute to product categories in the same run. An attribute with no categories is offered for every product.
A unit attribute has no predefined values. Each product gets its own value when you attach the attribute.
3

Add values later

Run createProductAttributeValuesWorkflow to add values to an existing select attribute. It takes one attribute_id and the new values.
For a variant axis, the workflow also adds the values to the mirror ProductOption.

Attach custom data with additional_data

Every catalog workflow accepts additional_data and passes it to its completion hook. Register a handler on productAttributesCreated to store your own data next to the attribute without forking the workflow.
src/workflows/hooks/product-attributes-created.ts
Pass the data when you run the workflow, for example additional_data: { imported_from: "legacy_pim" }. The workflow also exposes a validate hook that runs before anything is written, so you can throw there to reject the input.

Update or delete an attribute

updateProductAttributesWorkflow takes a selector and an update. Keep these rules in mind:
  • Type is fixed: the service throws if update.type differs from the current type
  • Renames reach the option: changing name on an axis also renames its ProductOption
  • Deletes check usage: deleteProductAttributesWorkflow throws NOT_ALLOWED while any value is linked to a product
The run renames the attribute and turns off its facet flag. The handle stays material, because handles are derived only on create.

Next steps