Skip to main content

shopify

Shopify Admin & Storefront GraphQL APIs via curl. Products, orders, customers, inventory, metafields.

Informations de source

Dépôt
dabit3/sonic-agent
Dernière activité de la source
2 septembre 2026 à 16:08
Langue détectée de SKILL.md
anglais
Étoiles
0
Forks
0

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
shopify
description
Shopify Admin & Storefront GraphQL APIs via curl. Products, orders, customers, inventory, metafields.
version
1.0.0
author
community
license
MIT
platforms
["linux","macos","windows"]
prerequisites
{"env_vars":["SHOPIFY_ACCESS_TOKEN","SHOPIFY_STORE_DOMAIN"],"commands":["curl","jq"]}
required_environment_variables
[{"name":"SHOPIFY_ACCESS_TOKEN","prompt":"Shopify Admin API access token (starts with shpat_)","help":"Shopify admin → Settings → Apps and sales channels → Develop apps → Create an app → API credentials. Token shown ONCE on install."},{"name":"SHOPIFY_STORE_DOMAIN","prompt":"Your shop subdomain without protocol (e.g. my-store.myshopify.com)","help":"The permanent myshopify.com domain, not your custom domain."},{"name":"SHOPIFY_API_VERSION","prompt":"Shopify API version (default 2026-01)","help":"Stable quarterly version. Override if you need an older one."}]
metadata
{"sonic":{"tags":["Shopify","E-commerce","Commerce","API","GraphQL"],"related_skills":["airtable","xurl"],"homepage":"https://shopify.dev/docs/api/admin-graphql"}}
# Shopify — Admin & Storefront GraphQL APIs Work with Shopify stores directly through `curl`: list products, manage inventory, pull orders, update customers, read metafields. No SDK, no app framework — just the GraphQL endpoint and a custom-app access token. The REST Admin API is legacy since 2024-04 and only receives security fixes. **Use GraphQL Admin** for all admin work. Use **Storefront GraphQL** for read-only customer-facing queries (products, collections, cart). ## Prerequisites 1. In Shopify admin: **Settings → Apps and sales channels → Develop apps → Create an app**. 2. Click **Configure Admin API scopes**, select what you need (examples below), save. 3. **Install app** → the Admin API access token appears ONCE. Copy it immediately — Shopify will never show it again. Tokens start with `shpat_`. 4. Save to `${SONIC_HOME:-~/.sonic}/.env`: ``` SHOPIFY_ACCESS_TOKEN=shpat_xxxxxxxxxxxxxxxxxxxx SHOPIFY_STORE_DOMAIN=my-store.myshopify.com SHOPIFY_API_VERSION=2026-01 ``` > **Heads up:** As of January 1, 2026, new "legacy custom apps" created in the Shopify admin are gone. New setups should use the **Dev Dashboard** (`shopify.dev/docs/apps/build/dev-dashboard`). Existing admin-created apps keep working. If the user's shop has no existing custom app and it's after 2026-01-01, direct them to Dev Dashboard instead of the admin flow. Common scopes by task: - Products / collections: `read_products`, `write_products` - Inventory: `read_inventory`, `write_inventory`, `read_locations` - Orders: `read_orders`, `write_orders` (30 most recent without `read_all_orders`) - Customers: `read_customers`, `write_customers` - Draft orders: `read_draft_orders`, `write_draft_orders` - Fulfillments: `read_fulfillments`, `write_fulfillments` - Metafields / metaobjects: covered by the matching resource scopes ## API Basics - **Endpoint:** `https://$SHOPIFY_STORE_DOMAIN/admin/api/$SHOPIFY_API_VERSION/graphql.json` - **Auth header:** `X-Shopify-Access-Token: $SHOPIFY_ACCESS_TOKEN` (NOT `Authorization: Bearer`) - **Method:** always `POST`, always `Content-Type: application/json`, body is `{"query": "...", "variables": {...}}` - **HTTP 200 does not mean success.** GraphQL returns errors in a top-level `errors` array and per-field `userErrors`. Always check both. - **IDs are GID strings:** `gid://shopify/Product/10079467700516`, `gid://shopify/Variant/...`, `gid://shopify/Order/...`. Pass these verbatim — don't strip the prefix. - **Rate limit:** calculated via query cost (leaky bucket). Each response has `extensions.cost` with `requestedQueryCost`, `actualQueryCost`, `throttleStatus.{currentlyAvailable, maximumAvailable, restoreRate}`. Back off when `currentlyAvailable` drops below your next query's cost. Standard shops = 100 points bucket, 50/s restore; Plus = 1000/100. Base curl pattern (reusable): ```bash shop_gql() { local query="$1" local variables="${2:-{}}" curl -sS -X POST \ "https://${SHOPIFY_STORE_DOMAIN}/admin/api/${SHOPIFY_API_VERSION:-2026-01}/graphql.json" \ -H "Content-Type: application/json" \ -H "X-Shopify-Access-Token: ${SHOPIFY_ACCESS_TOKEN}" \ --data "$(jq -nc --arg q "$query" --argjson v "$variables" '{query: $q, variables: $v}')" } ``` Pipe through `jq` for readable output. `-sS` keeps errors visible but hides the progress bar. ## Discovery ### Shop info + current API version ```bash shop_gql '{ shop { name myshopifyDomain primaryDomain { url } currencyCode plan { displayName } } }' | jq ``` ### List all supported API versions ```bash shop_gql '{ publicApiVersions { handle supported } }' | jq '.data.publicApiVersions[] | select(.supported)' ``` ## Products ### Search products (first 20 matching query) ```bash shop_gql ' query($q: String!) { products(first: 20, query: $q) { edges { node { id title handle status totalInventory variants(first: 5) { edges { node { id sku price inventoryQuantity } } } } } pageInfo { hasNextPage endCursor } } }' '{"q":"hoodie status:active"}' | jq ``` Query syntax supports `title:`, `sku:`, `vendor:`, `product_type:`, `status:active`, `tag:`, `created_at:>2025-01-01`. Full grammar: https://shopify.dev/docs/api/usage/search-syntax ### Paginate products (cursor) ```bash shop_gql ' query($cursor: String) { products(first: 100, after: $cursor) { edges { cursor node { id handle } } pageInfo { hasNextPage endCursor } } }' '{"cursor":null}' # subsequent calls: pass the previous endCursor ``` ### Get a product with variants + metafields ```bash shop_gql ' query($id: ID!) { product(id: $id) { id title handle descriptionHtml tags status variants(first: 20) { edges { node { id sku price compareAtPrice inventoryQuantity selectedOptions { name value } } } } metafields(first: 20) { edges { node { namespace key type value } } } } }' '{"id":"gid://shopify/Product/10079467700516"}' | jq ``` ### Create a product with one variant ```bash shop_gql ' mutation($input: ProductCreateInput!) { productCreate(product: $input) { product { id handle } userErrors { field message } } }' '{"input":{"title":"Test Hoodie","status":"DRAFT","vendor":"Sonic","productType":"Apparel","tags":["test"]}}' ``` Variants now have their own mutations in recent versions: ```bash # Add variants after creating the product shop_gql ' mutation($productId: ID!, $variants: [ProductVariantsBulkInput!]!) { productVariantsBulkCreate(productId: $productId, variants: $variants) { productVariants { id sku price } userErrors { field message } } }' '{"productId":"gid://shopify/Product/...","variants":[{"optionValues":[{"optionName":"Size","name":"M"}],"price":"49.00","inventoryItem":{"sku":"HD-M","tracked":true}}]}' ``` ### Update price / SKU ```bash shop_gql ' mutation($productId: ID!, $variants: [ProductVariantsBulkInput!]!) { productVariantsBulkUpdate(productId: $productId, variants: $variants) { productVariants { id sku price } userErrors { field message } } }' '{"productId":"gid://shopify/Product/...","variants":[{"id":"gid://shopify/ProductVariant/...","price":"55.00"}]}' ``` ## Orders ### List recent orders (last 30 by default without `read_all_orders`) ```bash shop_gql ' { orders(first: 20, reverse: true, query: "financial_status:paid") { edges { node { id name createdAt displayFinancialStatus displayFulfillmentStatus totalPriceSet { shopMoney { amount currencyCode } } customer { id displayName email } lineItems(first: 10) { edges { node { title quantity sku } } } } } } }' | jq ``` Useful order query filters: `financial_status:paid|pending|refunded`, `fulfillment_status:unfulfilled|fulfilled`, `created_at:>2025-01-01`, `tag:gift`, `email:foo@example.com`. ### Fetch a single order with shipping address ```bash shop_gql ' query($id: ID!) { order(id: $id) { id name email shippingAddress { name address1 address2 city province country zip phone } lineItems(first: 50) { edges { node { title quantity variant { sku } originalUnitPriceSet { shopMoney { amount currencyCode } } } } } transactions { id kind status amountSet { shopMoney { amount currencyCode } } } } }' '{"id":"gid://shopify/Order/...."}' | jq ``` ## Customers ```bash # Search shop_gql ' { customers(first: 10, query: "email:*@example.com") { edges { node { id email displayName numberOfOrders amountSpent { amount currencyCode } } } } }' # Create shop_gql ' mutation($input: CustomerInput!) { customerCreate(input: $input) { customer { id email } userErrors { field message } } }' '{"input":{"email":"test@example.com","firstName":"Test","lastName":"User","tags":["api-created"]}}' ``` ## Inventory Inventory lives on **inventory items** tied to variants, quantities tracked per **location**. ```bash # Get inventory for a variant across all locations shop_gql ' query($id: ID!) { productVariant(id: $id) { id sku inventoryItem { id tracked inventoryLevels(first: 10) { edges { node { location { id name } quantities(names: ["available","on_hand","committed"]) { name quantity } } } } } } }' '{"id":"gid://shopify/ProductVariant/..."}' ``` Adjust stock (delta) — uses `inventoryAdjustQuantities`: ```bash shop_gql ' mutation($input: InventoryAdjustQuantitiesInput!) { inventoryAdjustQuantities(input: $input) { inventoryAdjustmentGroup { reason changes { name delta } } userErrors { field message } } }' '{ "input": { "reason": "correction", "name": "available", "changes": [{"delta": 5, "inventoryItemId": "gid://shopify/InventoryItem/...", "locationId": "gid://shopify/Location/..."}] } }' ``` Set absolute stock (not delta) — `inventorySetQuantities`: ```bash shop_gql ' mutation($input: InventorySetQuantitiesInput!) { inventorySetQuantities(input: $input) { inventoryAdjustmentGroup { id } userErrors { field message } } }' '{"input":{"reason":"correction","name":"available","ignoreCompareQuantity":true,"quantities":[{"inventoryItemId":"gid://shopify/InventoryItem/...","locationId":"gid://shopify/Location/...","quantity":100}]}}' ``` ## Metafields & Metaobjects Metafields attach custom data to resources (products, customers, orders, shop). ```bash # Read shop_gql ' query($id: ID!) { product(id: $id) { metafields(first: 10, namespace: "custom") { edges { node { key type value } } } } }' '{"id":"gid://shopify/Product/..."}' # Write (works for any owner type) shop_gql ' mutation($metafields: [MetafieldsSetInput!]!) { metafieldsSet(metafields: $metafields) { metafields { id key namespace } userErrors { field message code } } }' '{"metafields":[{"ownerId":"gid://shopify/Product/...","namespace":"custom","key":"care_instructions","type":"multi_line_text_field","value":"Wash cold. Tumble dry low."}]}' ``` ## Storefront API (public read-only) Different endpoint, different token, used for customer-facing apps/hydrogen-style headless setups. Headers differ: - **Endpoint:** `https://$SHOPIFY_STORE_DOMAIN/api/$SHOPIFY_API_VERSION/graphql.json` - **Auth header (public):** `X-Shopify-Storefront-Access-Token: <public token>` — embeddable in browser - **Auth header (private):** `Shopify-Storefront-Private-Token: <private token>` — server-only ```bash curl -sS -X POST \
Voir sur GitHub
Ce SKILL.md est tres volumineux, SkillsMP affiche donc ici seulement la premiere section. Voir sur GitHub