shopify-product-upsert

POST /api/v1/shopify-product-upsert 1 credits/call shopify catalog

Create or update one Shopify product by style code, set its stock, and publish it to every sales channel. Idempotent.

Sign in + create an API key on the keys page to authenticate calls.

curl -X POST https://api.fulcrumgo.com/api/v1/shopify-product-upsert \
  -H "Authorization: Bearer mcpsk_<your_api_key>" \
  -H "Content-Type: application/json" \
  -d '{
  "style_code": "",
  "title": "",
  "vendor": "",
  "product_type": "",
  "variants": [],
  "description_html": "",
  "category_id": "",
  "status": "ACTIVE",
  "publish": true,
  "allow_new_vendor": false
}'

Add this server to Claude Desktop's claude_desktop_config.json. The endpoint becomes a callable tool inside Claude. See the MCP setup guide for the full walk-through.

{
  "mcpServers": {
    "this-api": {
      "url": "https://api.fulcrumgo.com/mcp",
      "transport": "http",
      "auth": {
        "type": "bearer",
        "token": "mcpsk_<your_api_key>"
      }
    }
  }
}

Inside Claude this endpoint surfaces as the tool shopify-product-upsert.

Standard requests — no custom SDK needed. pip install requests first.

import requests

r = requests.post(
    "https://api.fulcrumgo.com/api/v1/shopify-product-upsert",
    headers={"Authorization": "Bearer mcpsk_<your_api_key>"},
    json={
  "style_code": "",
  "title": "",
  "vendor": "",
  "product_type": "",
  "variants": [],
  "description_html": "",
  "category_id": "",
  "status": "ACTIVE",
  "publish": true,
  "allow_new_vendor": false
},
)
r.raise_for_status()
print(r.json())

Plain fetch. Works in Node 18+, Deno, Bun, and any modern browser.

const r = await fetch("https://api.fulcrumgo.com/api/v1/shopify-product-upsert", {
  method: "POST",
  headers: {
    "Authorization": "Bearer mcpsk_<your_api_key>",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
  "style_code": "",
  "title": "",
  "vendor": "",
  "product_type": "",
  "variants": [],
  "description_html": "",
  "category_id": "",
  "status": "ACTIVE",
  "publish": true,
  "allow_new_vendor": false
}),
});
if (!r.ok) throw new Error(`HTTP ${r.status}`);
console.log(await r.json());

Input

Field Type Required Default Description
style_code string required Stable supplier style code. This is the idempotency key: the same code always updates the same product.
maxLength=120
title string required
maxLength=255
vendor string required Must already exist on the store, spelled exactly. Set allow_new_vendor to create a new one.
product_type string required Must already exist on the store, spelled exactly.
options array<any> optional
variants array<any> required
description_html string optional
category_id string optional Shopify taxonomy GID, e.g. 'gid://shopify/TaxonomyCategory/aa-2-17'. Leaving this blank leaves the product Uncategorized.
tags array<string> optional
image_urls array<string> optional Public image URLs. Shopify fetches them; it never sees our host.
status string optional ACTIVE
pattern=^(ACTIVE|DRAFT|ARCHIVED)$
publish boolean optional True Publish to every sales channel after upserting.
allow_new_vendor boolean optional False Off by default. Creating vendors by accident is how a store ends up with 'Billionaire Boys Club' next to "Billionaire Boys' Club".

Output

Field Type Required Default Description
product_id string required
handle string required
admin_url string required
created boolean required False when an existing style code was updated.
variant_count integer required
stock_set boolean required
published boolean required False means the product exists but is NOT live on any channel. Never report it as live when this is false.
published_to array<string> optional
warnings array<string> optional Non-fatal problems. A product can land with stock unset or unpublished.

Try it

Fires a real POST /api/v1/shopify-product-upsert from your browser. Charges 1 credit per call against your account.

Sign in to use Try it. You'll need an API key from the keys page to authenticate the call.