# Create products in bulk in Shopify: variants, prices, stock and images

Updated 14 Sept 2026 · 14 min read · https://apimate.chat/cases/shopify-bulk-create-products

A product in Shopify is a title, a set of options, the variants those options produce, a price per variant, stock per location, tags, a vendor, a type, and media. Creating one by hand is ten minutes. Creating thirty is a morning. Both are one instruction here, with a preview that lists every variant row before any product exists, and one approval that creates all of it.

Two instructions that show the range: "Create a product Ridge Hoodie with sizes S, M, L, XL and colors Black, Navy, price 59, XL 64, vendor Cedar & Pine, product type clothes" produced one product with eight variants and two prices. "Set up a new category Winter 2026: create the collection, generate 30 products with sizes S to XL, prices between 39 and 89, tags winter and new, and 10 in stock each at Shop location" produced the collection, thirty products, their variants, and stock at one location, all from one preview.

Creation is the one job undo does not cover. A created product is removed by a second instruction, archive or delete, with its own preview. Say "draft" in the instruction if you want to look before the storefront does; that is the safety net for this job, and the section on revert says why.

## Who runs this job, and why now

A new season arrives as a supplier list, a photo folder and a price sheet. The products do not exist in the store yet, and each one needs the same size matrix as the last season's, with prices that follow a rule and tags that put them in the right collection. The admin can do this; it cannot do it thirty times before lunch.

A store that sells one product in six colours has six products where it should have one product with six variants, because that is how the first version was set up and nobody wanted to rebuild it. Consolidating means creating the right product with the right variants, then archiving the six. The first half of that is this job.

A catalog of single-variant products needs sizes. Every product has a "Default Title" variant at one price, and the merchant now stocks S through XL. Adding four variants to each of two hundred products by hand is the kind of task that gets postponed for a quarter.

## How this is done without ApiMate, and where each way breaks

In the Shopify admin: Products, Add product, fill the form, add options, edit the variant grid, set prices per variant, set stock per location, save. Duplicate for the next one, then change everything that differs. For a size matrix on one product this is fine. For thirty products it is thirty forms, and the errors are the boring kind: a price copied from the wrong row, a size left out, stock at the wrong location.

A CSV import is one row per variant, with the handle repeated on every row of the same product, options in three column pairs, and image URLs in their own column with a position number. It works, and every merchant who has done it has lost an image column at least once, or created a second product because a handle was typed with a trailing space. There is no preview. An import that half-succeeds leaves half a catalog.

A supplier catalog of thousands of products with images, prices and SKUs already in a file is the case where the file is the right tool. The values exist; nothing needs deriving. That is a Matrixify import, and the comparison page says so. This job is for the case where the products exist as a description of a rule, not as a file.

Sources: [Shopify Help: adding products](https://help.shopify.com/en/manual/products/add-update-products), [Shopify Help: product CSV](https://help.shopify.com/en/manual/products/import-export/using-csv)

## The instruction, as written

A creation instruction names what the product is (title, vendor, type), what its options are and their values, the price rule, the stock and where, the tags, and the status. Anything left out is either defaulted and shown in the preview, or asked about. Status defaults to draft when the instruction does not say, because an active product is on the storefront the moment it is created.

Prices are a rule, not a list. "Price 59, XL 64" is a rule with one exception. "Prices between 39 and 89" is a range, and each generated product gets a price inside it, not the same price for all. "Same price as the Ridge Hoodie" is a reference the tool resolves by reading that product.

> **Instruction** Create a product "Ridge Hoodie" with sizes S, M, L, XL and colors Black, Navy. Price 59, XL 64. Vendor Cedar & Pine, product type clothes. Draft.

- Options: Size with four values, Color with two. Eight variants.
- Price: 59 on every variant except XL at 64.
- Vendor and type: set on the product; the storefront filters and Merchant Center brand read them.
- Status: draft. Say "active" only when you mean it.

## What the preview showed

The preview shows the product as it will be: title, vendor, type, options, every variant with its price and SKU, stock per location, tags, status. One row per variant, before the product exists. For thirty products, thirty blocks of rows, each with its own title and description, and the scope line at the top says how many products and how many variants the job will create.

The variant count is the number to read first. Four sizes times two colours is eight. If the preview says sixteen, an option was doubled, usually because a value was listed twice with different capitalisation. Fix the instruction, not the rows.

| Column | What it is | What to check |
| --- | --- | --- |
| Product | Title, vendor, type, status | Draft unless you said active; the title reads like yours, not a supplier's |
| Options | Option names and values | The names your theme expects: "Size", not "size" and "Size" on different products |
| Variant | One row per option combination | The count is what the multiplication says |
| Price | Per variant | The rule applied, the exception where you said |
| Stock / location | Quantity per named location | The right location; "Shop location" is a name, "in stock" is not |
| Tags, collection | Tags added; collection created or joined | Tags spelled as your existing ones so they land in the same filters |

_Creation has no revert, so this table is the last cheap moment._

![ApiMate preview for creating the Ridge Hoodie: product block with vendor, type and draft status, then eight variant rows with size, colour, price and SKU](https://apimate.chat/cases/shopify-bulk-create-products/01-preview.webp)

_One product, eight variant rows, prices applied by rule. Status draft._

## One product, a matrix of variants

Options multiply. Four sizes and two colours are eight variants, each with its own price, SKU and stock. Say the price rule once and the preview shows eight rows with the rule applied. Say a SKU pattern ("RH-{color}-{size}") and the SKUs are generated per row; leave it out and the SKUs are empty, which the preview shows as empty so you can decide.

Shopify allows three options per product. A product that needs four (size, colour, material, length) has to fold one into another or become two products. The tool says so when the instruction asks for four; it does not silently drop one.

Stock at creation is optional. A variant created without stock has inventory tracking on and quantity zero, which the storefront shows as sold out. If the products are for sale on day one, say the quantity and the location in the instruction.

## Thirty products in a new collection

The instruction names the collection, the count, the option set, a price range, tags and stock. ApiMate creates the collection, generates the products with distinct titles and descriptions from the category name and the tags, builds the variants, sets stock at the named location and adds the tags. All of it is one preview, and the collection is created first so the products can join it in the same job.

Thirty generated products are thirty generated names and thirty generated descriptions. Read them. The generator works from the category, the type and the tags, so the names are plausible for "Winter 2026" apparel and generic for anything the instruction did not describe. The ones that read wrong are excluded from the plan before approval, not renamed afterwards; the rest are created.

This is the job for a placeholder catalog: a new store that needs products to test a theme, a wholesale line that needs listings before the photos arrive, a seasonal collection where the merchant will rename each product as the real items are confirmed. It is not the job for a catalog whose titles already exist in a supplier file.

> **Instruction** Set up a new category "Winter 2026": create the collection, generate 30 products with sizes S-XL, prices between 39 and 89, tags winter and new, and 10 in stock each at Shop location. Draft.

- Stock needs a location by name. "Shop location" is a name; "in stock" alone is not.
- A price range produces a price per product inside the range, not the same price for all.
- Tags are added, not replaced, on products that already exist.
- The collection is a manual collection with the thirty products in it. An automated collection would need a rule; say which you want.

![Preview for thirty generated products: collection creation row at the top, then a compact block per product with generated title, price and four size variants, stock 10 at Shop location](https://apimate.chat/cases/shopify-bulk-create-products/02-collection-preview.webp)

_The collection first, then thirty product blocks. Every title is readable in the preview._

## Adding variants to products that exist

A product with only a "Default Title" variant can get sizes without being recreated. "Every Hydration product that has only a Default Title variant: add size variants S, M, L, XL at the current price" turns the existing variant into size S at its price and creates the rest at the same price. Orders and inventory history on the existing variant are kept, because it is the same variant with a new option value.

Adding an option to a product that already has options multiplies the variants. A product with four sizes that gets two colours goes from four variants to eight, and the existing four become one of the colours. The preview states the count and which colour the existing variants become. Look at it; this is where stock ends up on the wrong colour.

Adding values to an existing option ("add XXL to every product that has S through XL") is simpler: one new variant per product, at a price you name or the price of the largest existing size.

> **Instruction** Every Hydration product that has only a Default Title variant: add size variants S, M, L, XL at the current price.

## Images

Existing images are attached by URL or from the files already in the store's Files section. "Use the images in the Winter 2026 folder, matched by filename to the product title" is a rule the preview shows as a filename per product, with the unmatched ones listed. A product created without images shows the theme's placeholder until one is added.

Generated product photos are a separate model, paid per image, and the count is shown before generation starts. A generated image is a placeholder for a listing, not a photo of your product; say so on the storefront or replace it when the photos arrive. Merchant Center flags generated images that misrepresent the product, so do not send them to the feed.

Cloning a product: the copy does not carry the images unless the instruction asks for them, and cloning an active product publishes a second live listing at once. Clone into draft.

## Before you approve

Creation cannot be reverted, so the preview is the last cheap moment. Five checks.

- Variant count. Four sizes times two colours is eight. If the preview says sixteen, an option was doubled.
- Status. Draft unless you mean active. An active product is on the storefront and in the Google feed the moment it exists.
- Location for stock. The wrong location is a fulfilment problem, not a cosmetic one.
- Option names. "Size" on the new products and "size" on the old ones are two filters on the storefront.
- Generated titles. Read all of them; exclude the bad ones.

## What happened after approval

One approval creates the collection, then the products, then the variants and stock, in that order, so a failure partway leaves a consistent state: products that exist are complete, products that do not exist are not half-made. The job reports each product as it is created and lists any that failed with the reason, usually a title collision with an existing product.

The created products are in the admin under Products, filtered by status draft if you said draft, and in the new collection. Open two or three, check the variant grid and the stock, then set them active from the admin or with a second instruction: "Set every product in Winter 2026 to active".

## Revert

There is no revert for creation. The saved "before" of a product that did not exist is nothing, and a revert that deletes products is a destructive job that should not hide behind an undo button. To remove created products, send a second instruction: "Archive every product tagged winter and new created today" or "Delete the products in the Winter 2026 collection". Both are previewed with the product list. Archive is reversible; delete is not.

Variants added to existing products are reverted: the added variants are removed and the original variant gets its option value back. Stock on the removed variants is gone with them, so move it first if it matters.

## Where the tool stops

A supplier catalog of thousands of products with images, prices and SKUs in a file is an import job. The file is the source of truth; a sentence adds nothing.

Per-variant images and very large matrices (dozens of option values) are created in a second step, not in the same plan as the product, because the preview for a product with two hundred variants and an image each is not one a person can read.

Generated descriptions come from the title, type, vendor and tags. They do not come from the internet, and they do not copy another product's description.

Three options per product is Shopify's limit. A fourth is refused with the reason, not folded in silently.

## Other ways to say the same job

These resolve to plans of the same shape. The variant count in the scope line tells you whether the options were read the way you meant.

- "Create 30 hoodies in sizes S to XL at 59.99 with stock 20 each."
- "Add a product called Trail Sock, sizes S/M and L/XL, colours Grey and Black, 14.99, vendor Kestrel Supply, draft."
- "Make a new collection Spring Preview with 12 placeholder products, prices 20 to 60, tagged preview."
- "Add XXL to every product that has sizes S through XL, same price as XL."
- "Every single-variant product from Cedar & Pine: add sizes S, M, L at the current price."
- "Clone the Ridge Hoodie as Ridge Hoodie Kids with sizes 4, 6, 8, 10 at 39, draft, no images."
- "Which products have only a Default Title variant?" (A read, before the add-variants job.)

## Terms used on this page

- Option: a product attribute with values, such as Size with S, M, L. Three per product at most.
- Variant: one combination of option values. Price, SKU and stock live here.
- Default Title: the single variant Shopify creates for a product with no options.
- Handle: the URL slug, generated from the title at creation. Two products cannot share one.
- Draft: a product that exists in the admin and is not on the storefront or in any channel.
- Manual collection: a collection whose products are listed explicitly. An automated one uses a rule.
- Location: where stock is held. Stock at creation needs one by name.

## Questions

### Can I undo product creation?

No. Undo restores saved previous values, and a new product has none. Remove created products with an archive or delete instruction, which has its own preview.

### Does it create the collection too?

Yes, when the instruction says so. The collection, the products and the stock are one plan, and the collection is created first.

### Can it generate product images?

Yes, through a separate image model charged per image. The count and cost are shown before generation. Generated images are placeholders, not product photography, and should not go to the Google feed.

### Will new products go live immediately?

Only if the instruction says active. Without it, products are created as drafts to review in the admin first.

### Can I add sizes to products I already have?

Yes. Products with a single Default Title variant can get size variants at the current price in one job, keeping the existing variant's history.

### Can it set SKUs?

Yes, from a pattern in the instruction, such as "RH-{color}-{size}". Without a pattern the SKUs are left empty and the preview shows them empty.

### What if a title already exists?

The product is skipped with the reason, because a second product with the same title gets a numbered handle and shows up as a duplicate in Merchant Center. Rename in the instruction and run again.

### Is this the right tool for a supplier catalog in a spreadsheet?

No. If the products exist as rows in a file, import the file. This job is for products described by a rule.

## Related

- [Bulk edit SEO titles, meta descriptions and alt text in Shopify](https://apimate.chat/cases/shopify-bulk-edit-seo): The next job after the products exist.
- [Bulk update prices and inventory in Shopify, with undo](https://apimate.chat/cases/shopify-bulk-update-prices): Adjust what you created, with revert.
- [ApiMate vs Matrixify](https://apimate.chat/compare/apimate-vs-matrixify): When the products already sit in a supplier file.
