Shopify Development13 min read

Shopify GraphQL Admin API: Practical Patterns for Developers

Pagination with cursors, bulk operations, cost-based rate limits, and mutation patterns — the things the Shopify GraphQL docs don't explain clearly.

  • GraphQL
  • Admin API
  • Shopify Development

The Shopify Admin API moved to GraphQL in 2019. In 2026, it's the only way to access most platform features — the REST API is in maintenance mode for most endpoints. Here's what you actually need to know to use it effectively.

01Cost-based rate limiting

Shopify doesn't rate-limit by requests per second — it uses a points-based system. Each query costs points based on the fields and connections you request. You get 50 points per second, with a bucket capacity of 1,000.

graphql
# Each extensions.cost field tells you the actual cost
{
  products(first: 10) {
    edges {
      node {
        id
        title
        variants(first: 10) { # each nested connection adds cost
          edges { node { id price } }
        }
      }
    }
  }
}
# Use the throttleStatus to monitor your bucket
extensions {
  cost {
    requestedQueryCost
    actualQueryCost
    throttleStatus {
      maximumAvailable
      currentlyAvailable
      restoreRate
    }
  }
}

02Cursor-based pagination

Shopify uses cursor-based pagination — not offset pagination. There's no page=2. You get a cursor from the last item in each response and pass it as the after argument in the next query.

03Bulk operations for large datasets

If you need to fetch thousands of records (products, orders, customers), use the Bulk Operations API. It processes the query asynchronously and delivers the results as a JSONL file via a URL.

graphql
mutation {
  bulkOperationRunQuery(
    query: """
    {
      products {
        edges {
          node {
            id title
            variants {
              edges { node { id sku price } }
            }
          }
        }
      }
    }
    """
  ) {
    bulkOperation { id status }
    userErrors { field message }
  }
}

04Mutation error handling

Shopify mutations never return HTTP error codes for business logic errors — they always return 200 with a userErrors array. Always check userErrors before treating a mutation as successful.

A 200 response from a Shopify mutation does not mean success. Check the userErrors array — it will contain validation errors, permission errors, and business rule violations.

All articles →
Shopify Development · 13 min readShopify Selling Plans API: Building Native Subscriptions Without Third-Party AppsShopify Development · 9 min readShopify Functions vs Apps: When to Use EachShopify Development · 10 min readShopify Metafields vs Metaobjects: Structured Content Without an App