Claude
Skills
Sign in
Back

shopify-api

Included with Lifetime
$97 forever

Complete API integration guide for Shopify including GraphQL Admin API, REST Admin API, Storefront API, Ajax API, OAuth authentication, rate limiting, and webhooks. Use when making API calls to Shopify, authenticating apps, fetching product/order/customer data programmatically, implementing cart operations, handling webhooks, or working with API version 2025-10. Requires fetch or axios for JavaScript implementations.

Backend & APIs

What this skill does


# Shopify API Integration

Expert guidance for all Shopify APIs including GraphQL Admin API, REST Admin API, Storefront API, Ajax API, authentication, and webhooks.

## When to Use This Skill

Invoke this skill when:

- Making GraphQL or REST API calls to Shopify
- Implementing OAuth 2.0 authentication for apps
- Fetching product, collection, order, or customer data programmatically
- Using Storefront API for headless commerce
- Implementing Ajax cart operations in themes
- Setting up webhooks for event handling
- Working with API version 2025-10
- Handling rate limiting and API errors
- Building custom integrations with Shopify
- Using Shopify Admin API from Node.js, Python, or other languages

## Core Capabilities

### 1. GraphQL Admin API

Modern API for Shopify Admin operations with efficient data fetching.

**Endpoint:**
```
POST https://{store}.myshopify.com/admin/api/2025-10/graphql.json
```

**Headers:**
```javascript
{
  'X-Shopify-Access-Token': 'shpat_...',
  'Content-Type': 'application/json'
}
```

**Basic Query:**
```graphql
query GetProducts($first: Int!) {
  products(first: $first) {
    edges {
      node {
        id
        title
        handle
        status
        vendor
        productType

        # Pricing
        priceRange {
          minVariantPrice { amount currencyCode }
          maxVariantPrice { amount currencyCode }
        }

        # Images
        images(first: 5) {
          edges {
            node {
              id
              url
              altText
            }
          }
        }

        # Variants
        variants(first: 10) {
          edges {
            node {
              id
              title
              sku
              price
              inventoryQuantity
              available: availableForSale
            }
          }
        }
      }
    }

    pageInfo {
      hasNextPage
      hasPreviousPage
      startCursor
      endCursor
    }
  }
}
```

**Variables:**
```json
{
  "first": 10
}
```

**JavaScript Example:**
```javascript
async function getProducts(accessToken, store, limit = 10) {
  const query = `
    query GetProducts($first: Int!) {
      products(first: $first) {
        edges {
          node {
            id
            title
            handle
            priceRange {
              minVariantPrice { amount currencyCode }
            }
          }
        }
        pageInfo {
          hasNextPage
          endCursor
        }
      }
    }
  `;

  const response = await fetch(
    `https://${store}.myshopify.com/admin/api/2025-10/graphql.json`,
    {
      method: 'POST',
      headers: {
        'X-Shopify-Access-Token': accessToken,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        query,
        variables: { first: limit },
      }),
    }
  );

  const { data, errors } = await response.json();

  if (errors) {
    console.error('GraphQL Errors:', errors);
    throw new Error(errors[0].message);
  }

  return data.products;
}
```

**Common Mutations:**

Create product:
```graphql
mutation CreateProduct($input: ProductInput!) {
  productCreate(input: $input) {
    product {
      id
      title
      handle
    }
    userErrors {
      field
      message
    }
  }
}
```

Update product:
```graphql
mutation UpdateProduct($input: ProductInput!) {
  productUpdate(input: $input) {
    product {
      id
      title
      status
    }
    userErrors {
      field
      message
    }
  }
}
```

Set metafield:
```graphql
mutation SetMetafield($input: MetafieldInput!) {
  metafieldSet(input: $input) {
    metafield {
      id
      namespace
      key
      value
      type
    }
    userErrors {
      field
      message
    }
  }
}
```

### 2. REST Admin API

Traditional REST API for Shopify Admin operations.

**Base URL:**
```
https://{store}.myshopify.com/admin/api/2025-10/
```

**Authentication:**
```javascript
headers: {
  'X-Shopify-Access-Token': 'shpat_...'
}
```

**Common Endpoints:**

Get products:
```javascript
GET /admin/api/2025-10/products.json?limit=50&status=active

// JavaScript
const response = await fetch(
  `https://${store}.myshopify.com/admin/api/2025-10/products.json?limit=50`,
  {
    headers: {
      'X-Shopify-Access-Token': accessToken,
    },
  }
);

const { products } = await response.json();
```

Get single product:
```javascript
GET /admin/api/2025-10/products/{product_id}.json
```

Create product:
```javascript
POST /admin/api/2025-10/products.json

// Body
{
  "product": {
    "title": "New Product",
    "body_html": "<p>Description</p>",
    "vendor": "My Vendor",
    "product_type": "Shoes",
    "status": "draft"
  }
}
```

Update product:
```javascript
PUT /admin/api/2025-10/products/{product_id}.json

// Body
{
  "product": {
    "id": 123456789,
    "title": "Updated Title"
  }
}
```

Get orders:
```javascript
GET /admin/api/2025-10/orders.json?status=any&limit=50
```

Get customers:
```javascript
GET /admin/api/2025-10/customers.json?limit=50
```

### 3. OAuth 2.0 Authentication

Complete OAuth flow for custom apps.

**Step 1: Authorization Request**
```
GET https://{shop}.myshopify.com/admin/oauth/authorize?
  client_id={api_key}&
  redirect_uri={redirect_uri}&
  scope={scopes}&
  state={random_state}
```

**Scopes:**
```javascript
const scopes = [
  'read_products',
  'write_products',
  'read_orders',
  'write_orders',
  'read_customers',
  'write_customers',
  'read_inventory',
  'write_inventory',
  'read_metafields',
  'write_metafields',
].join(',');
```

**Step 2: Handle Callback**
```javascript
// User approves, Shopify redirects to:
GET {redirect_uri}?code={auth_code}&state={state}&hmac={hmac}&shop={shop}

// Verify HMAC for security
function verifyHmac(query, secret) {
  const { hmac, ...params } = query;

  const message = Object.keys(params)
    .sort()
    .map(key => `${key}=${params[key]}`)
    .join('&');

  const hash = crypto
    .createHmac('sha256', secret)
    .update(message)
    .digest('hex');

  return hash === hmac;
}
```

**Step 3: Exchange Code for Token**
```javascript
POST https://{shop}.myshopify.com/admin/oauth/access_token

// Body
{
  "client_id": "{api_key}",
  "client_secret": "{api_secret}",
  "code": "{auth_code}"
}

// Response
{
  "access_token": "shpat_...",
  "scope": "write_products,read_orders"
}

// Node.js example
async function getAccessToken(shop, code, apiKey, apiSecret) {
  const response = await fetch(
    `https://${shop}/admin/oauth/access_token`,
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        client_id: apiKey,
        client_secret: apiSecret,
        code,
      }),
    }
  );

  const { access_token, scope } = await response.json();
  return { access_token, scope };
}
```

### 4. Rate Limiting

GraphQL uses points-based rate limiting.

**Rate Limits:**
- 50 cost points per second maximum
- Bucket refills at 50 points/second
- Each query has a calculated cost

**Check Rate Limit:**
```javascript
const response = await fetch(graphqlEndpoint, options);

const rateLimitHeader = response.headers.get('X-Shopify-GraphQL-Admin-Api-Call-Limit');
// Example: "42/50" (42 points used, 50 max)

const [used, limit] = rateLimitHeader.split('/').map(Number);

if (used > 40) {
  // Approaching limit, slow down
  await delay(1000);
}
```

**Implement Retry Logic:**
```javascript
async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const response = await fetch(url, options);

    if (response.status === 429) {
      // Rate limited
      const retryAfter = response.headers.get('Retry-After') || 2;
      await delay(retryAfter * 1000 * Math.pow(2, i)); // Exponential backoff
      continue;
    }

    return response;
  }

  throw new Error('Max retries exceeded');
}

function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}
```

### 5. Storefront API

Public API for headless/custom storefronts.

**Endpoi

Related in Backend & APIs