- Shopify Products
- Create, update, and bulk-import Shopify products. Produces live products in the store via the GraphQL Admin API or CSV import.
- Prerequisites
- Admin API access token (use the
- shopify-setup
- skill if not configured)
- Store URL and API version from
- shopify.config.json
- or
- .dev.vars
- Workflow
- Step 1: Gather Product Data
- Determine what the user wants to create or update:
- Product basics
-
- title, description (HTML), product type, vendor, tags
- Variants
-
- options (size, colour, material), prices, SKUs, inventory quantities
- Images
-
- URLs to upload, or local files
- SEO
-
- page title, meta description, URL handle
- Organisation
-
- collections, product type, tags
- Accept data from:
- Direct conversation (user describes products)
- Spreadsheet/CSV file (user provides a file)
- Website scraping (user provides a URL to extract from)
- Step 2: Choose Method
- Scenario
- Method
- 1-5 products
- GraphQL mutations
- 6-20 products
- GraphQL with batching
- 20+ products
- CSV import via admin
- Updates to existing
- GraphQL mutations
- Inventory adjustments
- inventorySetQuantities
- mutation
- Step 3a: Create via GraphQL (Recommended)
- Single product with variants
- :
- curl
- -s
- https://
- {
- store
- }
- /admin/api/2025-01/graphql.json
- \
- -H
- "Content-Type: application/json"
- \
- -H
- "X-Shopify-Access-Token: {token}"
- \
- -d
- '{
- "query": "mutation productCreate($product: ProductCreateInput!) { productCreate(product: $product) { product { id title } userErrors { field message } } }",
- "variables": {
- "product": {
- "title": "Example T-Shirt",
- "descriptionHtml": "
Premium cotton tee
", - "vendor": "My Brand",
- "productType": "T-Shirts",
- "tags": ["summer", "cotton"],
- "options": ["Size", "Colour"],
- "variants": [
- {"optionValues": [{"optionName": "Size", "name": "S"}, {"optionName": "Colour", "name": "Black"}], "price": "29.95"},
- {"optionValues": [{"optionName": "Size", "name": "M"}, {"optionName": "Colour", "name": "Black"}], "price": "29.95"},
- {"optionValues": [{"optionName": "Size", "name": "L"}, {"optionName": "Colour", "name": "Black"}], "price": "29.95"}
- ]
- }
- }
- }'
- See
- references/graphql-mutations.md
- for all mutation patterns.
- Batching multiple products
-
- Create products sequentially with a short delay between each to respect rate limits (1,000 cost points/second).
- Step 3b: Bulk Import via CSV
- For 20+ products, generate a CSV and import through Shopify admin:
- Generate CSV using the format in
- references/csv-format.md
- Use the template from
- assets/product-csv-template.csv
- Navigate to
- https://{store}.myshopify.com/admin/products/import
- Upload the CSV file
- Review the preview and confirm import
- Use browser automation to assist with the upload if needed.
- Step 4: Upload Product Images
- Images require a two-step process — staged upload then attach:
- mutation
- {
- stagedUploadsCreate
- (
- input
- :
- [
- {
- filename
- :
- "
- product-image.jpg
- "
- mimeType
- :
- "
- image/jpeg
- "
- httpMethod
- :
- POST
- resource
- :
- IMAGE
- }
- ]
- )
- {
- stagedTargets
- {
- url
- resourceUrl
- parameters
- {
- name
- value
- }
- }
- }
- }
- Then upload to the staged URL, and attach with
- productCreateMedia
- .
- Shortcut
- If images are already hosted at a public URL, pass src directly in the product creation: { "images" : [ { "src" : "https://example.com/image.jpg" , "alt" : "Product front view" } ] } Step 5: Assign to Collections After creation, add products to collections: mutation { collectionAddProducts ( id : " gid://shopify/Collection/123456 " productIds : [ "gid://shopify/Product/789" ] ) { collection { title productsCount } userErrors { field message } } } To find collection IDs: { collections ( first : 50 ) { edges { node { id title handle } } } } Step 6: Verify Query back the created products to confirm: { products ( first : 10 , reverse : true ) { edges { node { id title status variants ( first : 5 ) { edges { node { title price inventoryQuantity } } } images ( first : 3 ) { edges { node { url altText } } } } } } } Provide the admin URL for the user to review: https://{store}.myshopify.com/admin/products Critical Patterns Product Status New products default to DRAFT . To make them visible: { "status" : "ACTIVE" } Always confirm with the user before setting status to ACTIVE . Variant Limits Shopify allows max 100 variants per product and 3 options (e.g. Size, Colour, Material). If you need more, split into separate products. Inventory Tracking To set inventory quantities, use inventorySetQuantities after product creation: mutation { inventorySetQuantities ( input : { reason : " correction " name : " available " quantities : [ { inventoryItemId : " gid://shopify/InventoryItem/123 " locationId : " gid://shopify/Location/456 " quantity : 50 } ] } ) { inventoryAdjustmentGroup { reason } userErrors { field message } } } Price Formatting Prices are strings, not numbers. Always quote them: "price": "29.95" not "price": 29.95 . HTML Descriptions Product descriptions accept HTML. Keep it simple — Shopify's editor handles basic tags:
, , ,