Shopify Admin GraphQL
A comprehensive skill for interacting with Shopify's GraphQL Admin API. This skill enables Claude to query and manage all aspects of Shopify store data including products, orders, customers, inventory, marketing, discounts, translations, fulfillments, and more.
Prerequisites
- A Shopify store with Admin API access
- An Admin API access token with appropriate scopes
- Environment variables configured:
SHOPIFY_STORE_URL- Your store URL (e.g.,my-store.myshopify.com)SHOPIFY_ACCESS_TOKEN- Admin API access token
Quick Start
Basic Product Query
query {
products(first: 10) {
nodes {
id
title
status
}
}
}
Create a Product
mutation CreateProduct($product: ProductCreateInput!) {
productCreate(product: $product) {
product {
id
title
}
userErrors {
field
message
}
}
}
Variables:
{
"product": {
"title": "New Product",
"status": "DRAFT"
}
}
Instructions
When working with Shopify GraphQL:
- Always use the
shopify_graphqltool to execute queries and mutations - Check for errors in responses:
errorsarray indicates GraphQL/syntax issuesuserErrorsin mutations indicate validation/business logic issues
- Use pagination for large result sets with
first/aftercursors - Format IDs correctly - All Shopify IDs are global:
gid://shopify/Resource/123
Critical Operations & Permissions
IMPORTANT: Before executing any of the following operations, you MUST ask for explicit user permission. These operations are irreversible or have significant business impact.
Immediately Dangerous Operations
- Refunds: Create refunds (permanent financial transactions, cannot be undone)
- Order Cancellations: Cancel orders (may trigger automatic refunds)
- Gift Card Deactivation: Permanently disable gift cards (irreversible)
- Gift Card Balance Changes: Credit or debit gift card balances (affects customer funds)
- Inventory Adjustments: Modify stock levels (affects product availability)
State-Changing Operations
- Activate/Deactivate Discounts: Change discount status (immediately affects customer pricing)
- Product Status Changes: Publish products (makes them visible to customers)
- Complete Draft Orders: Convert draft orders to real orders (commits the transaction)
- Fulfillment Creation: Create fulfillments (triggers shipping notifications to customers)
- Fulfillment Cancellation: Cancel fulfillments (may confuse customers)
- Hold/Release Fulfillment Orders: Pause or resume order processing
Deletion Operations
- Delete Products/Variants: Permanent removal (cannot be recovered)
- Delete Discounts: Permanent removal (customers can no longer use codes)
- Delete Draft Orders: Permanent removal
- Delete Webhooks: Stops event notifications (may break integrations)
- Bulk Delete Operations: Delete multiple items at once (high-impact)
Permission Protocol
When Claude encounters any critical operation:
- Describe the operation and its specific impact
- Show what will be changed/deleted (IDs, names, values)
- Wait for explicit user confirmation before proceeding
- Only proceed after receiving "yes", "confirm", "proceed", or equivalent affirmative response
- Never assume permission even if the user's request seems clear
Example:
WARNING: This will permanently deactivate gift card gid://shopify/GiftCard/123
with a balance of $50.00. This action cannot be undone.
Do you want to proceed? (yes/no)
Capabilities
This skill provides comprehensive patterns for all major Shopify domains:
Core Commerce
| Domain | Operations | File |
|---|---|---|
| Products | List, get, search, create, update, delete products and variants | products.md |
| Orders | List, get details, fulfill, cancel orders | orders.md |
| Customers | List, get, create, update customers | customers.md |
| Inventory | Check levels, adjust quantities, manage locations | inventory.md |
| Collections | List collections, manage products in collections | collections.md |
Marketing & Promotions
| Domain | Operations | File |
|---|---|---|
| Discounts | Code/automatic discounts, BXGY, free shipping | discounts.md |
| Marketing | Marketing activities, events, consent | marketing.md |
| Segments | Customer segments for targeting | segments.md |
International
| Domain | Operations | File |
|---|---|---|
| Translations | Translate products, pages, content | translations.md |
| Markets | Multi-market setup, localized content | markets.md |
Content & Storefront
| Domain | Operations | File |
|---|---|---|
| Pages | Create/update store pages | pages.md |
| Blogs | Blogs and articles | blogs.md |
| Menus | Navigation menus | menus.md |
| Files | File uploads, media library | files.md |
| Metafields | Custom data, metaobjects | metafields.md |
Fulfillment & Shipping
| Domain | Operations | File |
|---|---|---|
| Fulfillments | Create fulfillments, tracking | fulfillments.md |
| Shipping | Delivery profiles, zones, rates | shipping.md |
| Locations | Manage inventory locations | locations.md |
Financial
| Domain | Operations | File |
|---|---|---|
| Draft Orders | Create orders on behalf of customers | draft-orders.md |
| Refunds | Process refunds, restocking | refunds.md |
| Gift Cards | Create, credit, debit gift cards | gift-cards.md |
| Subscriptions | Subscription contracts, billing | subscriptions.md |
Store Management
| Domain | Operations | File |
|---|---|---|
| Shop | Store info, settings, ShopifyQL | shop.md |
| Webhooks | Event subscriptions | webhooks.md |
| Bulk Operations | Large async queries/mutations | bulk-operations.md |
Common Patterns
ID Format
All Shopify GraphQL IDs are globally unique:
gid://shopify/Product/123
gid://shopify/Order/456
gid://shopify/Customer/789
Pagination
Use cursor-based pagination for large datasets:
query($first: Int!, $after: String) {
products(first: $first, after: $after) {
pageInfo {
hasNextPage
endCursor
}
nodes {
id
title
}
}
}
Money Fields
Prices return as MoneyV2 objects:
totalPriceSet {
shopMoney {
amount
currencyCode
}
}
Mutations Always Return userErrors
Always request and check userErrors:
mutation {
productCreate(product: $product) {
product { id }
userErrors {
field
message
}
}
}
Search Syntax
Filter queries use Shopify's search syntax:
products(first: 10, query: "title:*shirt* AND status:ACTIVE")
API Scopes Required
Core Scopes
read_products,write_products- Products and variantsread_orders,write_orders- Orders and fulfillmentsread_customers,write_customers- Customer dataread_inventory,write_inventory- Inventory levels
Marketing & Discounts
read_discounts,write_discounts- Discount codesread_marketing_events,write_marketing_events- Marketing activities
Content
read_content,write_content- Pages, blogs, articlesread_online_store_navigation,write_online_store_navigation- Menusread_files,write_files- File uploadsread_metafields,write_metafields- Metafieldsread_metaobjects,write_metaobjects- Metaobjects
International
read_translations,write_translations- Translationsread_markets,write_markets- Marketsread_locales,write_locales- Locales
Fulfillment
read_shipping,write_shipping- Shipping settingsread_locations- Location dataread_assigned_fulfillment_orders,write_assigned_fulfillment_orders- For fulfillment services
Financial
read_draft_orders,write_draft_orders- Draft ordersread_gift_cards,write_gift_cards- Gift cardsread_own_subscription_contracts,write_own_subscription_contracts- Subscriptions
Troubleshooting
| Error | Solution |
|---|---|
Access denied | Check API token has required scopes |
Invalid ID | Ensure ID format is gid://shopify/Resource/123 |
userErrors returned | Check field-specific validation messages |
Throttled | Reduce request rate, use bulk operations for large updates |
Resource not found | Verify the ID exists and you have read access |
Examples
List Recent Orders with Customer Info
query RecentOrders {
orders(first: 10, sortKey: CREATED_AT, reverse: true) {
nodes {
id
name
createdAt
displayFinancialStatus
totalPriceSet {
shopMoney {
amount
currencyCode
}
}
customer {
displayName
defaultEmailAddress {
emailAddress
}
}
}
}
}
Search Products by Title
query SearchProducts($query: String!) {
products(first: 20, query: $query) {
nodes {
id
title
status
vendor
}
}
}
Variables: { "query": "title:*shirt* AND status:ACTIVE" }
Update Inventory
mutation AdjustInventory($input: InventoryAdjustQuantitiesInput!) {
inventoryAdjustQuantities(input: $input) {
inventoryAdjustmentGroup {
reason
changes {
name
delta
}
}
userErrors {
field
message
}
}
}
Create Discount Code
mutation CreateDiscount($basicCodeDiscount: DiscountCodeBasicInput!) {
discountCodeBasicCreate(basicCodeDiscount: $basicCodeDiscount) {
codeDiscountNode {
id
}
userErrors {
field
message
}
}
}
Best Practices
- Use bulk operations for large data exports/imports
- Implement pagination for lists that may grow
- Check userErrors in all mutation responses
- Request only needed fields to optimize response size
- Use webhooks instead of polling for real-time updates
- Cache when appropriate to reduce API calls
- Handle rate limits with exponential backoff