Skip to main content
Run createProductsWorkflow to add a product to the shared catalog from a custom route, a seed script, or an import job. It creates the product and its variants, attaches attributes, links any stores you name, and records the submission.

Before you begin

You need the following in place:
  • A Mercur server with @mercurjs/core installed
  • The ids of any attributes and stores you want to reference
Import createProductsWorkflow from @mercurjs/core/workflows, not @medusajs/medusa/core-flows. Medusa’s workflow has the same name but skips attributes, the allowlist, and the audit record.

Create the product

1

Add a route that runs the workflow

Create an admin route. The workflow returns the created ProductDTO objects in input order.
src/api/admin/supplier-products/route.ts
created_by is required. Mercur stores it on the PRODUCT_ADD change as the submitter. Without a status, the product starts as draft.
2

Add attributes and variants

Pass attributes instead of native options. A multi_select attribute with is_variant_axis becomes the option that variants bind to by title.
The first entry attaches a global attribute with a chosen value. The second creates a product-scoped axis. New variants get manage_inventory: false unless you set it, since stock lives on offers.
3

Restrict the product to stores

Add seller_ids to a product to put those stores on its allowlist.
Only these 2 stores can see and sell the product once it’s published. Leave seller_ids out to open it to every store.

Submit on behalf of a store

Pass the store’s seller id as created_by to make the product a submission from that store. That’s what the vendor API does, and it’s how Mercur lets a store see its own draft and proposed products.
The product appears in that store’s product list as a proposed submission, and stays hidden from other stores until it’s published.

Validate input with the validate hook

The workflow runs a validate hook before it creates anything. Throw from the handler to stop the run.
src/workflows/hooks/validate-products.ts
The hook receives the raw input and its products array, so you can check any field before Medusa writes rows.

Attach custom data with additional_data

Pass additional_data to carry extra values through the run. Mercur forwards it to Medusa’s product and variant workflows and to the productsCreated hook.
src/workflows/hooks/products-created.ts
Call the workflow with additional_data: { source: "supplier_feed" } and the handler receives it next to the created products.

Next steps