Register a new product with HTML description using GraphQL and Python

Topic summary

A developer is encountering errors when registering Shopify products via GraphQL and Python when the product description contains HTML. Plain text descriptions work successfully, but HTML content causes failures.

The Issue:

  • The descriptionHtml field with an <img> tag is not being properly formatted
  • The HTML tag appears to be improperly closed in the mutation
  • The code successfully creates products with plain text but fails with HTML content

Solution Provided:

  • The <img> tag needs proper closing to avoid parsing errors
  • A working mutation example was shared that correctly handles HTML in the description field

Additional Recommendations:

  • The images field is deprecated as of API version 2023-07; use media instead
  • Upgrade to the latest API version (2023-10) for better long-term support
  • Use Shopify’s GraphQL Explorer tool to test queries before implementing them in application code

The discussion remains open for the original poster to confirm whether the suggested fix resolves their issue.

Summarized with AI on November 15. AI used: claude-sonnet-4-5-20250929.

I’m new to Shopify GraphQL and trying to register products through GraphQL and Python.

I wrote a code as below but it returns an error. Products with only text can be registered but products with HTML are not registered.

Using GCP, Theme: Debut

import requests
import json

# Shopify API credentials
shop_url = "ShopURL"
access_token = "ACCESS TOKEN"

# GraphQL mutation
mutation = '''
mutation {
  productCreate(input: {
    title: "ProductCreateTest"
    descriptionHtml: '<img data-src=\"https://cdn.shopify.com/s/files/test.jpg?v=123456\" alt=\"\">
    variants: [
      {
        price: 29.99
      }
    ]
    images: [
      {
        src: "https://example.com/image.jpg"
      }
    ]
  }) {
    product {
      id
      title
    }
  }
}
'''

# GraphQL API endpoint
api_url = f"{shop_url}/admin/api/2023-07/graphql.json"

# Headers with authentication
headers = {
    "Content-Type": "application/json",
    "X-Shopify-Access-Token": access_token
}

# Send the GraphQL request
response = requests.post(api_url, headers=headers, data=json.dumps({"query": mutation}))

# Check for success or handle errors
if response.status_code == 200:
    result = response.json()
    created_product = result.get("data", {}).get("productCreate", {}).get("product", {})
    if created_product:
        product_id = created_product.get("id")
        print(f"Product created with ID: {product_id}")
    else:
        print("Error creating product")
else:
    print(f"Error: {response.status_code}, {response.text}")

When putting plain text on the descriptionHTML field, it works perfectly.

What I have tried on descriptionHTML field :

descriptionHtml: “<img data-src=“https://cdn.shopify.com/s/files/test.jpg?v=123456&quot; alt=””>

“doublequotes”

"

descriptionHtml: “<img data-src="[https://cdn.shopify.com/s/files/test.jpg?v=123456\](https://cdn.shopify.com/s/files/test.jpg?v=123456\)” alt="">

"doublequotes"

"

Hey @heyuuuuu it looks like The tag in your HTML is not properly closed, which could be causing the issue.

Testing the following mutation here does work:

I do want to note as well that the images field is deprecated as of the 2023-07 API release so it’s recommended to use media instead. Since you’re just getting started, adopting the latest API version (2023-10) will ensure the endpoints and fields you use will be supported the longest!

mutation {> productCreate(input: {> title: “ProductCreateTest”> descriptionHtml: “”> variants: [> {> price: 29.99> }> ]> images: [> {> src: “https://example.com/image.jpg”> }> ]> }) {> product {> id> title> }> }> }

Our graphiql Explorer tool is also a really great resource to test your API queries before adding them to your app code.

Hope this helps!

  • Kyle G.