# Product catalog export & import > Export your products as Shopify or WooCommerce CSV files, import them into your store, keep SKUs in sync, and bulk-create products from a spreadsheet with the API. Source: https://swaglists.com/docs/catalog-export Your store needs products whose variant **SKUs match your SKUs here** — that is how orders find their way back to us. The fastest way to get there is to create products here and export them to your store. ## Export to your store In the dashboard open **Products**, optionally select products, then **Export** and pick a format. The download is a CSV ready for your store's importer: | Format | File | Import it in | | --- | --- | --- | | **Shopify CSV** | UTF-8, one row per variant, extra rows for additional images | Shopify admin → **Products → Import** | | **WooCommerce CSV** | UTF-8 with BOM, a `variable` parent row + one `variation` row per variant | WooCommerce → **Products → Import** | | **CSV** | UTF-8 with BOM, one row per variant | Spreadsheets or any other platform | Shopify and WooCommerce files contain enabled variants only (the generic CSV lists every variant with an `enabled` column). Archived products are left out unless you select them. ### Shopify columns | Column | Value | | --- | --- | | `Title`, `URL handle`, `Description` (HTML), `Tags` | From your product | | `Vendor` | Your brand name | | `Type` | The catalog product (e.g. *Classic Unisex Tee*) | | `Status`, `Published on online store` | `active` / `draft` from your product | | `Option1 name` / `Option1 value`, `Option2 …`, `Option3 …` | Variant options (e.g. Color, Size) | | `SKU` | **Your SKU** — do not change it in Shopify | | `Price` | Your retail price | | `Weight value (grams)`, `Requires shipping`, `Charge tax` | Shipping weight, `TRUE`, `TRUE` | | `Inventory tracker` | Empty (print on demand: never out of stock) | | `Fulfillment service` | `manual` (your server forwards the order — see the [Shopify recipe](https://swaglists.com/docs/shopify.md)) | | `Product image URL`, `Variant image URL` | Our rendered mockups | ### WooCommerce columns `Type` (`variable` / `variation` / `simple`), `SKU` (parent SKU on the variable row, **your SKU** on each variation), `Parent`, `Name`, `Published`, `Description`, `Regular price` (your retail price), `Attribute N name` / `value(s)` / `visible` / `global`, `Images` (mockups), `Categories`, `Tags`, `Tax status`, `In stock?` and `Weight (lbs)` or `Weight (kg)` (choose the unit your store uses). ### Generic CSV columns `product_id`, `product_title`, `product_status`, `product_external_id`, `catalog_product_id`, `variant_id`, `sku`, `catalog_variant_id`, `variant_title`, `color`, `size`, `options`, `enabled`, `retail_price`, `currency`, `variant_external_id`, `tags`, `image_url`, `created_at`. ## Keep your store in sync - **New variants or products** — export again and import with "overwrite existing products" (Shopify matches on `URL handle`; WooCommerce on `SKU`). - **Price changes** — wholesale price changes arrive as [`catalog.price_changed`](https://swaglists.com/docs/events.md#catalog.price_changed) events; your retail prices are yours to adjust. - **Changing a SKU** — change it here first (`PATCH /products/{id}/variants/{variant_id}`), then in your store. Until both match, orders for that variant fail with `400 resource_missing` on `items[i].sku`. - **Archiving** — archive the product here (`DELETE /products/{id}`) and unpublish it in your store. ## Import into Swaglists: bulk-create from a spreadsheet Have many designs? Create products with the API from a CSV of artwork URLs and SKUs. Example input: ```csv title="designs.csv" title,artwork_url,catalog_product_id,sku_prefix Sunset Vibes Tee,https://cdn.example.com/art/sunset.png,cp_01k8w1a2s3d4f5g6h7j8k9m0n1,SUNSET Mountain Air Tee,https://cdn.example.com/art/mountain.png,cp_01k8w1a2s3d4f5g6h7j8k9m0n1,MOUNTAIN ``` ```js title="Node.js" // bulk-create.mjs — node bulk-create.mjs designs.csv import { readFile } from "node:fs/promises"; const API = "https://swaglists.com/api/v1"; const headers = { Authorization: `Bearer ${process.env.API_KEY}`, "Content-Type": "application/json" }; const [header, ...rows] = (await readFile(process.argv[2], "utf8")).trim().split(/\r?\n/).map((l) => l.split(",")); const col = Object.fromEntries(header.map((h, i) => [h, i])); for (const row of rows) { const catalogProductId = row[col.catalog_product_id]; const catalog = await (await fetch(`${API}/catalog/products/${catalogProductId}`, { headers })).json(); const placement = catalog.placements[0].key; const res = await fetch(`${API}/products`, { method: "POST", headers: { ...headers, "Idempotency-Key": `bulk-${row[col.sku_prefix]}` }, body: JSON.stringify({ catalog_product_id: catalogProductId, title: row[col.title], designs: [{ placement, layers: [{ url: row[col.artwork_url] }] }], // we download the artwork variants: catalog.variants .filter((v) => v.available) .map((v) => ({ catalog_variant_id: v.id, sku: [row[col.sku_prefix], v.color, v.size].filter(Boolean).join("-").toUpperCase().replace(/[^A-Z0-9-]/g, "") })), }), }); const body = await res.json(); console.log(res.ok ? `✓ ${body.id} ${body.title} (${body.variants.length} variants)` : `✗ ${row[col.title]}: ${body.error.code} ${body.error.message}`); for (const w of body.warnings ?? []) console.log(` ⚠ ${w.code}: ${w.message}`); } ``` ```python title="Python" # bulk_create.py — python bulk_create.py designs.csv import csv, os, re, sys, requests API = "https://swaglists.com/api/v1" session = requests.Session() session.headers["Authorization"] = f"Bearer {os.environ['API_KEY']}" with open(sys.argv[1], newline="") as f: for row in csv.DictReader(f): catalog = session.get(f"{API}/catalog/products/{row['catalog_product_id']}").json() variants = [ {"catalog_variant_id": v["id"], "sku": re.sub(r"[^A-Z0-9-]", "", "-".join(filter(None, [row["sku_prefix"], v["color"], v["size"]])).upper())} for v in catalog["variants"] if v["available"] ] res = session.post( f"{API}/products", headers={"Idempotency-Key": f"bulk-{row['sku_prefix']}"}, json={ "catalog_product_id": row["catalog_product_id"], "title": row["title"], "designs": [{"placement": catalog["placements"][0]["key"], "layers": [{"url": row["artwork_url"]}]}], "variants": variants, }, ) body = res.json() print(f"✓ {body['id']} {body['title']}" if res.ok else f"✗ {row['title']}: {body['error']['code']} {body['error']['message']}") ``` Then export the new products to your store as described above. Respect the [rate limit](https://swaglists.com/docs/rate-limits.md) for large batches (the scripts make two requests per product).