Graph QL Create Products Best Practices, basic workflow

Topic summary

A developer needs to create over 100,000 products with basic information (handle, title, description, SKU, price, and images) without using product options. They’re uncertain about the correct workflow.

Proposed Workflow:

  1. Call productCreate mutation and store the product ID
  2. Call productVariantsBulkCreate mutation using that product ID

Key Questions:

Option ID confusion: The API documentation shows an optionId field in the variant creation example (e.g., "optionId": "gid://shopify/ProductOption/328272167"). The developer is unclear where this ID originates and whether it’s required, especially since they’re receiving an error: “You need to add option values for Title.”

Default variant behavior: They’re asking whether Shopify automatically creates a default variant when a product is created, which could result in duplicate variants (one default and one intentionally created).

The developer is also requesting links to tutorials or best practices guides for bulk product creation via GraphQL.

Summarized with AI on October 31. AI used: claude-sonnet-4-5-20250929.

Hello,
We have to create over 100K products. We dont make use of any kind of product options (yet). So for each product, we need basic information set like:

Handle

title
Description Html

sku

price

Image1

Image2

It is our understanding that we need to create a product, and one variant for each product. Here is the workflow we are trying to use:

  1. Call: productCreate mutation. store the returned product Id for later.
  2. Call ProductVariantsCreate mutation (known as productVariantsBulkCreate). Pass in the product ID.

I have a few questions.

  1. Looking at your documentation for ProductVariantsCreate, it shows this json for the inputs:
{
  "productId": "gid://shopify/Product/20995642",
  "variants": [
    {
      "price": 15.99,
      "compareAtPrice": 19.99,
      "optionValues": [
        {
          "name": "Golden",
          "optionId": "gid://shopify/ProductOption/328272167"
        }
      ]
    }
  ]
}

My first question is about:

variants[0].optionValues[0].optionId

  1. How are we passing in an ID here? Where did that ID come from? Is this required? This example in your documentation uses a “Golden” option, with an option ID specified. Im getting this back from your API:

“userErrors”:[{“field”:[“variants”,“0”],“message”:“You need to add option values for Title”}

So I assume this must be required.

  1. My second question is: Is a default variant created anyway when I create a new product? If so, then the process I am trying now would result in 2 variants (one real one and one bogus one).

Also, if you have any tutorial or best practices guide on how to do this, please give me the url.