productCreate returns existing product

Hello,

I cannot create a first product using the admin API.

url = f"https://{SHOPIFY_STORE}/admin/api/2025-01/products.json"
headers = {
    "X-Shopify-Access-Token": ADMIN_API_TOKEN,
    "Content-Type": "application/json"
}
data = {
    "product": {
        "title": "Sadfgdfgct",
        "body_html": "<strong>Adfggmazing product description</strong>",
        "vendor": "YodfgurBrand",
        "product_type": "T-Shirt",
    }
}

response = requests.post(url, headers=headers, json=data)
print(response.status_code, response.json())  # P

The response returns an existing product
200 {'products': [{'id': 10118779109710, 'title': 'sdfds', 'body_html': '<p>sdfdsf</p>', 'vendor': 'Edurika Shop', 'product_type': '', 'created_at': '2025-02-02T15:18:21+01:00', 'handle': 'sdfds', 'updated_at': '2025-02-02T15:18:39+01:00', 'published_at': '2025-02-02T15:18:21+01:00', 'template_suffix': '', 'published_scope': 'global', 'tags': '', 'status': 'active', 'admin_graphql_api_id': 'gid://shopify/Product/10118779109710', 'variants': [{'id': 51002501103950, 'product_id': 10118779109710, 'title': 'Default Title', 'price': '0.00', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2025-02-02T15:18:22+01:00', 'updated_at': '2025-02-02T15:18:22+01:00', 'taxable': False, 'barcode': '', 'fulfillment_service': 'manual', 'grams': 0, 'inventory_management': None, 'requires_shipping': False, 'sku': '', 'weight': 0.0, 'weight_unit': 'kg', 'inventory_item_id': 53059789455694, 'inventory_quantity': 0, 'old_inventory_quantity': 0, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/51002501103950', 'image_id': None}], 'options': [{'id': 12825902612814, 'product_id': 10118779109710, 'name': 'Title', 'position': 1, 'values': ['Default Title']}], 'images': [], 'image': None}]}

I tried graphql, curl and different versions.

I’d recommend defaulting to GraphQL as the REST API for products is not deprecated. I tried this using the GraphiQL app and it worked for me:

mutation CreateProduct {
  productCreate(input: {
    title: "Sadfgdfgct",
    descriptionHtml: "<strong>Adfggmazing product description</strong>",
    vendor: "YodfgurBrand",
    productType: "T-Shirt"
  }) {
    product {
      id
      title
      descriptionHtml
      vendor
    }
    userErrors {
      field
      message
    }
  }
}

Thank you, the graphql app works. I can iterate from that.
Stay as you are!

1 Like

Great to hear Tilman!

Unfortunately I could not move forward (sample request with cURL using graphql), however I expect the problem is somewhere on my site! Sharing a short summary.

Target: Python with requests and graphql body.

  • using the “Admin-API-Token” from the shopify admin panel without the partner program.
  • added product read and write permissions

Note this query represent the format of the Shopify API docs. Expect it’s a double quote problem, will investigate this when I have time again

curl -v -L -i -X POST \
https://edurika-shop.myshopify.com/admin/api/2025-01/graphql.json \
-H 'Content-Type: application/json' \
-H 'X-Shopify-Access-Token: shpat_dXXXX' \
-d '{
"query": "query { productsCount(query: \"id:>=1000\") { count } }"
}'

some logs

Note: Unnecessary use of -X or --request, POST is already inferred.
* Host edurika-shop.myshopify.com:443 was resolved.
* IPv6: 2620:127:f00f:e::
* IPv4: 23.227.38.74
*   Trying [2620:127:f00f:e::]:443...
* Connected to edurika-shop.myshopify.com (2620:127:f00f:e::) port 443
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / X25519 / id-ecPublicKey
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=myshopify.com
*  start date: Feb  2 13:53:17 2025 GMT
*  expire date: May  3 13:53:16 2025 GMT
*  subjectAltName: host "edurika-shop.myshopify.com" matched cert's "*.myshopify.com"
*  issuer: C=US; O=Let's Encrypt; CN=E5
*  SSL certificate verify ok.
*   Certificate level 0: Public key type EC/prime256v1 (256/128 Bits/secBits), signed using ecdsa-with-SHA384
*   Certificate level 1: Public key type EC/secp384r1 (384/192 Bits/secBits), signed using sha256WithRSAEncryption
*   Certificate level 2: Public key type RSA (4096/152 Bits/secBits), signed using sha256WithRSAEncryption
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://edurika-shop.myshopify.com/admin/api/2025-01/graphql.json
* [HTTP/2] [1] [:method: POST]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: edurika-shop.myshopify.com]
* [HTTP/2] [1] [:path: /admin/api/2025-01/graphql.json]
* [HTTP/2] [1] [user-agent: curl/8.5.0]
* [HTTP/2] [1] [accept: */*]
* [HTTP/2] [1] [content-type: application/json]
* [HTTP/2] [1] [x-shopify-access-token: shpat_d]
* [HTTP/2] [1] [content-length: 70]
> POST /admin/api/2025-01/graphql.json HTTP/2
> Host: edurika-shop.myshopify.com
> User-Agent: curl/8.5.0
> Accept: */*
> Content-Type: application/json
> X-Shopify-Access-Token: shpat_dXXX
> Content-Length: 70
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
< HTTP/2 301 
HTTP/2 301 
< date: Sun, 09 Feb 2025 16:06:25 GMT
date: Sun, 09 Feb 2025 16:06:25 GMT
< content-type: application/json; charset=utf-8
content-type: application/json; charset=utf-8
< content-length: 0
content-length: 0
* Please rewind output before next send
< location: https://0zy5d1-14.myshopify.com/admin/api/2025-01/graphql.json
location: https://0zy5d1-14.myshopify.com/admin/api/2025-01/graphql.json
< x-sorting-hat-podid: 333

Actual error response

{"errors":{"query":"Required parameter missing or invalid"}}

Same problem with

curl -v -L -i -X POST \
https://edurika-shop.myshopify.com/admin/api/2025-01/graphql.json \
-H 'Content-Type: application/json' \
-H 'X-Shopify-Access-Token: shpat_dXXXX' \
-d '{
"query": "query { products(first: 10, after: \"eyYYYY\") { edges { node { id title handle } cursor } pageInfo { hasNextPage } } }"
}'

Edit: deinstalled app after logs contained token

Ok found the problem.

The shopify URL in the admin panel is not the expected URL. Checkout the response header. In case of “Moved permanently”, the the location header value is the actual shop URL.

Inspect your request with curl -i

HTTP/2 301 
date: Sat, 15 Feb 2025 18:42:06 GMT
content-type: application/json; charset=utf-8
content-length: 0
location: https://XXXXX.myshopify.com/admin/api/2025-01/graphql.json

Using the given URL works out of the box. Wishing you all health and wealth.

1 Like