Guide

How to bulk upload products to WooCommerce

WooCommerce can import hundreds of products at once from a CSV file. This guide walks through the built-in importer, when a plugin or the REST API makes more sense, and how to get clean data into the CSV in the first place.

Adding products one by one in the WooCommerce admin is fine for a small shop, but onboarding a supplier catalog that way can take days. WooCommerce includes a product CSV importer, and there are import plugins and an API for larger or recurring jobs.

The import itself is rarely the hard part. The hard part is producing a correct CSV: one row per product or variation, the right columns, consistent attributes, and descriptions worth publishing.

Option 1: The built-in WooCommerce CSV importer

WooCommerce ships with a product CSV importer and exporter. In the WordPress admin, go to Products → All Products and choose Import. Upload your CSV, map its columns to WooCommerce fields, and run the import. Ticking “Update existing products” lets you update products matched by ID or SKU instead of creating duplicates.

  • Export one existing product first and use that file as your template — it shows the exact column names your store expects.
  • Typical columns include Type, SKU, Name, Published, Short description, Description, Regular price, Categories, Tags, Images, and Attribute 1 name / Attribute 1 value(s).
  • Images are imported from URLs, so they must be publicly reachable when the import runs.
  • Variable products need a parent row of type “variable” and one row per variation that references the parent.
  • Very large files can time out on shared hosting — split them into batches of a few hundred rows.

Option 2: Import plugins

Third-party import plugins add features the core importer lacks: scheduled or recurring imports from a supplier feed, XML support, field transformation rules, and better handling of very large files. They make sense when a supplier sends updated price and stock files regularly.

Plugins still expect structured input. If your supplier provides PDFs rather than a feed, a plugin does not remove the work of turning those PDFs into rows.

Option 3: The WooCommerce REST API

Developers and integration tools can create products through the WooCommerce REST API, including a batch endpoint that creates or updates many products in one request. This suits automated pipelines and apps that create products directly without a CSV step.

Doc2Shelf uses this route: after review, it sends products to WooCommerce as simple draft products with long and short descriptions, so you can check them in WooCommerce before making them live. Global filter attributes and variable products are configured separately in WooCommerce.

Preparing product data for a bulk upload

Whatever import method you use, data quality decides the result. Before importing:

  • Give every product a unique SKU — it is how updates find the right product later.
  • Create categories and global attributes in WooCommerce first, then reference them consistently.
  • Normalize specifications: same units, same attribute names, one value per cell.
  • Write real descriptions instead of pasting supplier text; marketplaces and search engines reward unique copy.
  • Import as drafts for a first run — set Published to -1 (0 makes products private) — then review a sample before publishing everything.

When your supplier only sends PDFs

Many suppliers provide data sheets and catalogs as PDFs, not CSV feeds. In that case the bottleneck is extraction: someone has to read each PDF, fill in the columns, and write a description.

You can do this manually, or extract the data with a tool and review it. Doc2Shelf reads supplier PDFs, extracts the specifications for review, drafts WooCommerce long and short descriptions, and creates the products as drafts through the REST API — replacing the spreadsheet step for PDF-sourced catalogs.

Common WooCommerce import errors

If an import fails or produces unexpected results, check these first:

  • Duplicate or missing SKUs causing rows to be skipped or products to be duplicated.
  • Wrong file encoding — save the CSV as UTF-8 so accented characters import correctly.
  • Image URLs that redirect, require a login, or point to very large files.
  • Category paths written inconsistently (use “Parent > Child” for nested categories).
  • Variations whose attribute values do not match the parent product’s attribute values.

WooCommerce product CSV column reference

The core importer reads a fixed set of column names. Exporting one product from your own store gives you the exact headers your WooCommerce version expects; the table below explains the columns that matter most for a bulk upload. Only Name is required — every other column is optional, but a catalog imported without Type, SKU, prices, and categories leaves a lot of manual work for later.

Columns with a unit in the header, such as Weight and the three dimensions, show the unit configured in your store settings, so copy those headers from an export rather than typing them. Custom data that has no column of its own goes into a column whose header starts with meta: followed by the field key.

Core WooCommerce CSV importer columns (WooCommerce 3.1 and later)
ColumnWhat it holdsExampleNotes
IDExisting WooCommerce product ID—Leave blank for new products; update imports match on ID first.
TypeProduct typesimpleAlso variable, variation, grouped, or external. Virtual and downloadable are designations added to a product, not separate types.
SKUYour unique product codeACME-KTL-17Second match key for updates, after ID. Must be unique in the store.
GTIN, UPC, EAN, or ISBNGlobal product identifier4006381333931Core field. Since WooCommerce 11.2, the fallback match key when ID and SKU are both blank.
NameProduct titleStainless steel kettle 1.7 LThe only required column.
PublishedStatus after import-11 = published, 0 = private, -1 = draft, 2 = pending review.
Regular price / Sale pricePrices49.90Plain numbers without a currency symbol.
StockInventory quantity25Use with In stock? and Backorders allowed? as needed.
Weight (unit), Length (unit), Width (unit), Height (unit)Shipping weight and dimensions1.2The header shows your store’s unit, for example kg or cm.
CategoriesProduct categoriesKitchen > Kettles, GiftsComma-separated; “>” marks a subcategory.
ImagesImage URLshttps://cdn.example.com/ktl-front.jpgComma-separated; the first image becomes the featured image.
ParentParent product of a variation rowACME-KTLThe parent’s SKU, or id: followed by the parent’s ID.
Attribute 1 name / Attribute 1 value(s)An attribute and its valuesColor / Red, BlueAdd Attribute 2, Attribute 3, and so on for more attributes.
Attribute 1 visible / Attribute 1 globalFlags for that attribute1 / 1Visible shows it on the product page; global uses a store-wide attribute.
Attribute 1 defaultPreselected value of a variable productRedSet it on the parent row.
meta:supplier_codeA custom meta fieldD-4471Any header starting with meta: is stored as custom meta.

Variable products in a CSV: parent and variation rows

A variable product is spread over several rows: one parent row that defines the product and the attribute values it offers, and one row per variation that carries the price, SKU, and stock for a single combination. The parent row has Type “variable”; each variation row has Type “variation” and points back to the parent in the Parent column, using the parent’s SKU or id: followed by its ID.

The attribute columns tie the rows together. On the parent, Attribute 1 value(s) lists every value the product offers, separated by commas. On each variation, the same Attribute 1 name appears with exactly one of those values. Spelling and capitalization must match: a variation that says “red” under a parent that offers “Red” can end up without a usable attribute value.

Set Attribute 1 global to 1 on the parent and its variations when you use a store-wide attribute created under Products → Attributes — that is what layered navigation and filter widgets work with. Since WooCommerce 11.1, an update import can also add new variations to a variable product that already exists, so you can extend a range without rebuilding the parent.

  • Keep each parent row above its variations so the file is easy to check and the parent exists when its variations reference it.
  • Give every variation its own SKU and price; a variation without a price cannot be bought.
  • Use Attribute 1 default on the parent to control which option is preselected.
Example: one kettle sold in two colors
RowTypeSKUParentAttribute 1 nameAttribute 1 value(s)
ParentvariableACME-KTL—ColorRed, Blue
Variation 1variationACME-KTL-REDACME-KTLColorRed
Variation 2variationACME-KTL-BLUACME-KTLColorBlue

Adding product images through the CSV

The Images column takes one or more image URLs separated by commas. The first URL becomes the featured image and the rest form the product gallery in the order listed. During the import, WordPress downloads each file into your media library, so every URL must be publicly reachable at that moment — no login, no expiring share link, and no redirect to a web page instead of the file.

Images are usually the slowest part of an import: a few hundred products with five images each means over a thousand downloads. Resize images before hosting them, use descriptive file names (kettle-red-front.jpg, not IMG_0042.jpg), and split large catalogs into smaller files.

The core importer cannot set image alt text. Add alt text afterwards in the media library, through the REST API, or with an import extension that supports it. A variation holds a single image, so give each variation row one URL at most.

Creating products in bulk with the WooCommerce REST API

The REST API is the better route when imports repeat, when product data already lives in another system, or when nobody should have to handle a CSV at all. Its products batch endpoint (POST /wp-json/wc/v3/products/batch) accepts create, update, and delete operations in a single request.

By default, a batch request is limited to 100 objects across its creates, updates, and deletes. The same limit applies to the batch endpoints for variations, categories, attributes, and attribute terms. A 1,000-product catalog therefore takes at least ten requests, and more once variations are added.

  1. Create a REST API key with read/write permission under WooCommerce → Settings → Advanced → REST API, or let an app request one through WooCommerce’s authorization screen.
  2. Create the categories, global attributes, and attribute terms first, and note their IDs.
  3. Send simple and parent products in batches of up to 100, with the status set to draft.
  4. Create the variations of each variable product through that product’s variations batch endpoint.
  5. Check the result for each item in the response and retry only the items that failed.
  6. Spot-check a sample of the drafts in the admin, then publish them.

Choosing a WooCommerce bulk product upload plugin or route

If the core importer is not enough, judge an import plugin or extension by how it handles your data, not by the length of its feature list, and test it on a staging copy of the store with a real supplier file before committing to it. The table compares the four routes, followed by the questions worth asking of any plugin.

  • Source formats: CSV only, or also XML, spreadsheet files, and remote feeds fetched by URL.
  • Scheduling: whether it can re-run an import on a timetable to pick up new prices and stock.
  • Mapping and transforms: renaming columns, splitting values, converting units, and applying price rules during the import.
  • Variable products: whether it builds parents, variations, and global attributes reliably.
  • Images: how it downloads them, whether it detects duplicates, and whether it sets alt text.
  • Large files: background or chunked processing so long imports do not time out.
  • Update rules: which key it matches on (ID, SKU, or GTIN) and which fields it may overwrite.
Four ways to bulk upload WooCommerce products
RouteBest forWatch out for
Core CSV importerOne-off imports and bulk updates by store staffServer upload and time limits; no image alt text
Import plugin or extensionRecurring supplier feeds, XML or spreadsheet sources, scheduled updatesOne more plugin to maintain and keep compatible
REST API batch requestsAutomated pipelines and syncing from another systemDeveloper time; 100 objects per batch request by default
App that creates products for youProduct data that starts outside a spreadsheet, such as supplier documentsCheck which product types and fields the app actually sets

Pre-import checklist and error fixes

Most failed imports trace back to a skipped preparation step. Work through the checklist before every large import, and use the table to diagnose problems that still come up.

  1. Back up the database, or run the import on a staging copy of the store.
  2. Export one existing product and copy its header row into your file.
  3. Create the categories, global attributes, and attribute terms the file references.
  4. Check that every SKU is unique and that every variation’s Parent value matches an existing parent SKU.
  5. Use plain numbers in the price, stock, weight, and dimension columns.
  6. Open a sample of image URLs in a private browser window to confirm they load without a login.
  7. Set Published to -1 so the products arrive as drafts.
  8. Save the file as UTF-8 CSV.
  9. Import a ten-row test file, review the results, then import the rest in batches.
WooCommerce import problems: cause and fix
ProblemLikely causeFix
Products duplicated instead of updated“Update existing products” not ticked, or IDs and SKUs do not match the storeTick the option; copy IDs or SKUs from a fresh export
Rows skipped in an update importNo match on ID or SKU (GTIN is tried only when both are blank, since 11.2)Add the existing product’s SKU or ID to each row
Variations imported as separate productsType not set to variation, or the Parent column is empty or misspelledUse Type “variation” and the exact parent SKU
Images missingURL needs a login, redirects, or the host blocks the downloadHost images at public, direct URLs and re-run the import
File rejected on uploadFile larger than the server’s maximum upload sizeSplit the file, or ask your host to raise the limit
Import stops partwayServer time or memory limit reachedImport smaller files

Testing with dummy products before the real import

A small dummy file catches mapping mistakes before they touch hundreds of products. Build it from your real template so the headers are identical, and give every test product an obvious marker — a “TEST-” SKU prefix and a “test” tag — so you can find and delete the products afterwards.

Cover each case your real file contains, not just the easy one. Around ten rows are usually enough:

  • One simple product with every column you plan to use filled in.
  • One variable product with two attributes and at least three variations.
  • One product with a gallery of several images, and one with no images.
  • One product in a nested category that does not exist yet.
  • One product with accented characters, quotation marks, and a comma inside the description.
  • One row that updates an existing product by SKU.
  • Check the results in the admin and on the storefront — prices, variation dropdowns, image order, and category pages — then delete the test products before the real import.

Frequently asked questions

Does WooCommerce have a built-in bulk product upload?
Yes. WooCommerce includes a product CSV importer under Products → All Products → Import, and a matching exporter. No plugin is needed for standard CSV imports.
How many products can I import into WooCommerce at once?
There is no fixed product limit in the importer, but server timeouts and memory limits on your hosting determine what is practical. Splitting large catalogs into batches of a few hundred rows is the usual workaround.
Can I update existing products with a CSV import?
Yes. Enable “Update existing products” in the importer; rows are matched to existing products by ID or SKU and only the columns you include are updated.
Can I import products into WooCommerce directly from PDFs?
Not with the core importer, which expects CSV. You first need to extract the product data from the PDFs — manually or with an extraction tool — and then import it via CSV or create the products through the REST API.
Which columns does a WooCommerce product CSV need?
Only Name is required by the core importer. For a usable catalog, include at least Type, SKU, Published, Regular price, Categories, Images, and Description. Export one product from your store to get the exact header names your version expects.
How do I import variable products with a CSV?
Add one parent row with Type “variable” that lists every attribute value, then one row per variation with Type “variation”, the parent’s SKU in the Parent column, a single attribute value, and its own SKU and price.
Can I import product images and alt text with the CSV importer?
Images, yes: list public image URLs in the Images column, separated by commas, with the featured image first. Alt text, no — the core importer cannot set it, so add it afterwards or use the REST API or an extension.
How many products can I create per WooCommerce REST API request?
The batch endpoint accepts up to 100 objects per request by default, counting creates, updates, and deletes together. Larger catalogs are sent as a series of batch requests.

More guides

Turn supplier PDFs into reviewed product data

Doc2Shelf extracts product data from supplier documents and drafts listings and compliance documents for your review.

Create your free account