Talk Shop
Home
Learn More
About Us
Follow Us
Blog
Tools
Newsletter
Join Discord
Join

Community

  • Developers
  • Growth
  • Entrepreneurs
  • Support
  • Experts
  • Tools

Location

123 Mars, Crater City, Red Planet

(WiFi may be spotty)

Hours

Who has time for breaks? We're here 24/7!

Contact

hello@letstalkshop.com

Talk Shop
Talk Shop

Built for real builders. Not affiliated with Shopify Inc.

Home
Privacy
Terms
  1. Home
  2. >Blog
  3. >Headless & Hydrogen
  4. >Shopify Storefront API Getting Started Guide
Headless & Hydrogen10 min read

Shopify Storefront API Getting Started Guide

A comprehensive getting started guide for the Shopify Storefront API. Covers authentication, GraphQL queries, product data, cart mutations, checkout flow, rate limits, and real-world implementation patterns.

Talk Shop

Talk Shop

Mar 26, 2026

Shopify Storefront API Getting Started Guide

In this article

  • What the Storefront API Unlocks for Developers
  • Setting Up API Access
  • Your First Query: Fetching Products
  • Querying Collections and Navigation
  • Building the Cart with Mutations
  • Handling Checkout and Payments
  • Customer Account API Integration
  • Rate Limits and Performance Best Practices
  • Search and Predictive Search
  • Internationalization and Multi-Currency
  • Common Mistakes and How to Avoid Them
  • Building a Complete Storefront: Putting It All Together

What the Storefront API Unlocks for Developers

The Shopify Storefront API is the GraphQL interface that powers every headless Shopify storefront. Whether you are building with Hydrogen, Next.js, a mobile app, or even an in-store kiosk, this API is how your frontend reads product data, manages carts, and initiates checkout.

Unlike Shopify's Admin API (which manages the backend — products, orders, fulfillment), the Storefront API is designed for customer-facing experiences. It is optimized for speed, has no rate limits on read requests, and supports both public and private access patterns. Every custom storefront built on Shopify in 2026 runs on this API.

This Shopify Storefront API getting started guide walks you from zero to a working integration. By the end, you will be able to query products, build a cart, and send customers to checkout — the three fundamental operations that make a headless storefront functional. If you are exploring the broader headless and Hydrogen ecosystem, this API is the foundation everything else builds on.

Setting Up API Access

Before making your first query, you need access tokens. Shopify provides two access paths, each designed for different use cases.

Install the Headless Sales Channel

  1. Log in to your Shopify admin
  2. Navigate to Settings > Apps and sales channels > Shopify App Store
  3. Search for and install the Headless sales channel
  4. Click Create storefront to generate your access tokens

This gives you two tokens:

  • Public access token — safe to embed in browser-side JavaScript. Limited to read operations and cart mutations.
  • Private access token — for server-side use only. Provides access to all Storefront API features including customer operations.

Authentication Headers

For public (client-side) requests:

texttext
X-Shopify-Storefront-Access-Token: your-public-token
Content-Type: application/json

For private (server-side) requests:

texttext
Shopify-Storefront-Private-Token: your-private-token
Content-Type: application/json

Critical: When making server-side requests, always include the Shopify-Storefront-Buyer-IP header with the customer's real IP address. This allows Shopify to enforce bot protection accurately and prevents your server from being flagged as malicious traffic. The Shopify API authentication documentation covers all header requirements.

API Endpoint and Versioning

The Storefront API endpoint follows this pattern:

texttext
https://{your-store}.myshopify.com/api/{version}/graphql.json

Shopify releases new API versions quarterly. As of March 2026, the current stable version is 2026-01. Always pin your integration to a specific version:

texttext
https://your-store.myshopify.com/api/2026-01/graphql.json
VersionRelease DateSupported Until
2026-01January 2026January 2027
2025-10October 2025October 2026
2025-07July 2025July 2026

Your First Query: Fetching Products

Isometric view of digital storefront architecture with light paths.

The most common Storefront API operation is reading product data. Here is a complete working example.

Basic Product Query

graphqlgraphql
query GetProducts {
  products(first: 12) {
    edges {
      node {
        id
        title
        handle
        description
        priceRange {
          minVariantPrice {
            amount
            currencyCode
          }
          maxVariantPrice {
            amount
            currencyCode
          }
        }
        images(first: 1) {
          edges {
            node {
              url
              altText
              width
              height
            }
          }
        }
        variants(first: 10) {
          edges {
            node {
              id
              title
              availableForSale
              price {
                amount
                currencyCode
              }
            }
          }
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

Making the Request (JavaScript)

javascriptjavascript
const STOREFRONT_API_URL = 'https://your-store.myshopify.com/api/2026-01/graphql.json';
const STOREFRONT_ACCESS_TOKEN = 'your-public-token';

async function fetchProducts() {
  const response = await fetch(STOREFRONT_API_URL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Shopify-Storefront-Access-Token': STOREFRONT_ACCESS_TOKEN,
    },
    body: JSON.stringify({
      query: `
        query GetProducts {
          products(first: 12) {
            edges {
              node {
                id
                title
                handle
                priceRange {
                  minVariantPrice {
                    amount
                    currencyCode
                  }
                }
              }
            }
          }
        }
      `,
    }),
  });

  const { data } = await response.json();
  return data.products.edges.map(edge => edge.node);
}

Understanding Connections and Edges

The Storefront API uses Relay-style pagination. Every list query returns a connection with edges and pageInfo:

  • `edges` — array of results, each containing a node (the actual data) and a cursor (pagination position)
  • `pageInfo` — contains hasNextPage, hasPreviousPage, startCursor, and endCursor

This pattern is consistent across products, collections, variants, images, and every other list type in the API. The Shopify Storefront API reference documents every available connection.

Querying Collections and Navigation

Glowing stacked blocks representing nested collection navigation.

Collections are how Shopify organizes products. Your headless storefront needs to fetch collection data for category pages and navigation menus.

Fetch a Single Collection with Products

graphqlgraphql
query GetCollection($handle: String!) {
  collection(handle: $handle) {
    id
    title
    description
    image {
      url
      altText
    }
    products(first: 24, sortKey: BEST_SELLING) {
      edges {
        node {
          id
          title
          handle
          priceRange {
            minVariantPrice {
              amount
              currencyCode
            }
          }
          images(first: 1) {
            edges {
              node {
                url
                altText
              }
            }
          }
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
}

Product Sorting Options

The Storefront API supports these sort keys for products within collections:

Sort KeyDescription
BEST_SELLINGHighest sales volume first
CREATED_ATNewest first
PRICELowest price first (use reverse: true for highest)
TITLEAlphabetical
COLLECTION_DEFAULTThe order set in Shopify admin
RELEVANCESearch relevance (only for search queries)

Product Filtering

The Storefront API supports server-side product filtering within collections:

graphqlgraphql
query FilteredCollection($handle: String!, $filters: [ProductFilter!]) {
  collection(handle: $handle) {
    products(first: 24, filters: $filters) {
      filters {
        id
        label
        type
        values {
          id
          label
          count
        }
      }
      edges {
        node {
          id
          title
          handle
        }
      }
    }
  }
}

Available filter types include price range, availability, product type, vendor, variant options (size, color), and tag. Understanding how to build filtered collection pages is essential for any Shopify theme or storefront development.

Building the Cart with Mutations

The Cart API is the write side of the Storefront API. Every add-to-cart click, quantity change, and discount code application is a cart mutation.

Create a Cart

graphqlgraphql
mutation CreateCart($input: CartInput!) {
  cartCreate(input: $input) {
    cart {
      id
      checkoutUrl
      lines(first: 10) {
        edges {
          node {
            id
            quantity
            merchandise {
              ... on ProductVariant {
                id
                title
                price {
                  amount
                  currencyCode
                }
              }
            }
          }
        }
      }
      cost {
        totalAmount {
          amount
          currencyCode
        }
        subtotalAmount {
          amount
          currencyCode
        }
      }
    }
    userErrors {
      field
      message
    }
  }
}

Variables:

jsonjson
{
  "input": {
    "lines": [
      {
        "merchandiseId": "gid://shopify/ProductVariant/12345678",
        "quantity": 1
      }
    ]
  }
}

Add Items to an Existing Cart

graphqlgraphql
mutation AddToCart($cartId: ID!, $lines: [CartLineInput!]!) {
  cartLinesAdd(cartId: $cartId, lines: $lines) {
    cart {
      id
      totalQuantity
      lines(first: 50) {
        edges {
          node {
            id
            quantity
            merchandise {
              ... on ProductVariant {
                id
                title
              }
            }
          }
        }
      }
      cost {
        totalAmount {
          amount
          currencyCode
        }
      }
    }
    userErrors {
      field
      message
    }
  }
}

Update and Remove Items

graphqlgraphql
# Update quantity
mutation UpdateCartLine($cartId: ID!, $lines: [CartLineUpdateInput!]!) {
  cartLinesUpdate(cartId: $cartId, lines: $lines) {
    cart {
      id
      totalQuantity
    }
    userErrors {
      field
      message
    }
  }
}

# Remove items
mutation RemoveCartLine($cartId: ID!, $lineIds: [ID!]!) {
  cartLinesRemove(cartId: $cartId, lineIds: $lineIds) {
    cart {
      id
      totalQuantity
    }
    userErrors {
      field
      message
    }
  }
}

Apply Discount Codes

graphqlgraphql
mutation ApplyDiscount($cartId: ID!, $discountCodes: [String!]!) {
  cartDiscountCodesUpdate(cartId: $cartId, discountCodes: $discountCodes) {
    cart {
      id
      discountCodes {
        code
        applicable
      }
      cost {
        totalAmount {
          amount
          currencyCode
        }
      }
    }
    userErrors {
      field
      message
    }
  }
}

Important: The Checkout API was deprecated in April 2025. All new headless builds must use the Cart API for cart management and checkout URL generation. The DigitalSuits migration guide covers the transition from the old Checkout API to the Cart API.

Handling Checkout and Payments

A payment terminal and tablet side-by-side with cinematic lighting.

The checkout flow in a headless Shopify storefront is straightforward because Shopify handles it entirely.

The Checkout Redirect Pattern

Every cart object includes a checkoutUrl field. When the customer clicks "Checkout," you redirect them to this URL:

javascriptjavascript
async function redirectToCheckout(cartId) {
  const cart = await fetchCart(cartId);
  window.location.href = cart.checkoutUrl;
}

The customer completes checkout on Shopify's hosted checkout page (checkout.shopify.com or your custom domain on Shopify Plus). After payment, they return to your storefront via the thank-you page URL configured in Shopify settings.

Buyer Identity

For returning customers, attach their identity to the cart for personalized pricing and saved addresses:

graphqlgraphql
mutation UpdateBuyerIdentity($cartId: ID!, $buyerIdentity: CartBuyerIdentityInput!) {
  cartBuyerIdentityUpdate(cartId: $cartId, buyerIdentity: $buyerIdentity) {
    cart {
      id
      buyerIdentity {
        email
        countryCode
      }
    }
    userErrors {
      field
      message
    }
  }
}

Checkout Customization Options

PlanCustomization Level
Basic / Shopify / AdvancedShopify standard checkout (branding only)
Shopify PlusCheckout extensions (custom UI, logic, and payment methods)

For most merchants, Shopify's standard checkout converts well and requires no customization. If you are on Shopify Plus and need custom checkout flows, checkout extensions use a separate API surface. Our guide to Shopify headless commerce covers checkout architecture in greater depth.

Customer Account API Integration

If your storefront supports customer accounts, the Storefront API provides endpoints for authentication and account management.

Customer Access Tokens

Authenticate customers and create access tokens:

graphqlgraphql
mutation CustomerAccessTokenCreate($input: CustomerAccessTokenCreateInput!) {
  customerAccessTokenCreate(input: $input) {
    customerAccessToken {
      accessToken
      expiresAt
    }
    customerUserErrors {
      code
      field
      message
    }
  }
}

Variables:

jsonjson
{
  "input": {
    "email": "customer@example.com",
    "password": "customer-password"
  }
}

Fetch Customer Data

With an access token, query the customer's profile, order history, and addresses:

graphqlgraphql
query GetCustomer($customerAccessToken: String!) {
  customer(customerAccessToken: $customerAccessToken) {
    id
    firstName
    lastName
    email
    orders(first: 10) {
      edges {
        node {
          id
          orderNumber
          totalPrice {
            amount
            currencyCode
          }
          processedAt
          fulfillmentStatus
        }
      }
    }
    addresses(first: 5) {
      edges {
        node {
          id
          address1
          city
          province
          country
          zip
        }
      }
    }
  }
}

Account Management Mutations

OperationMutationPurpose
RegistercustomerCreateCreate new customer account
LogincustomerAccessTokenCreateGenerate session token
Password resetcustomerRecoverSend reset email
Update profilecustomerUpdateChange name, email, password
Add addresscustomerAddressCreateAdd shipping address
Update addresscustomerAddressUpdateModify existing address

The Shopify Storefront API Learning Kit on GitHub provides complete working examples for customer account flows.

Rate Limits and Performance Best Practices

A dark dashboard monitor showing performance analytics and graphs.

One of the Storefront API's biggest advantages is its generous rate limiting — or lack thereof for most operations.

Rate Limit Structure

  • Read queries (products, collections, pages) — no rate limit. You can query as frequently as needed.
  • Mutations (cart operations, customer actions) — throttled per shop, with additional per-IP throttling for authenticated requests.
  • Checkout creation — limited per minute to prevent abuse.
  • Bot protection — if Shopify's systems detect malicious traffic patterns, requests receive a 430 Security Rejection response.

Query Cost and Complexity

While there are no request-count rate limits on reads, the Storefront API does enforce query complexity limits. Every field in your query has a cost, and the total cost per query is capped.

Best practices to stay within complexity limits:

  • Request only the fields you actually use
  • Limit first and last arguments to the minimum necessary
  • Avoid deeply nested connections (3+ levels deep)
  • Use separate queries for different page sections rather than one massive query

Caching Strategy

Data TypeCache DurationRationale
Product catalog5-15 minutesChanges infrequently
Collection listings5-15 minutesChanges infrequently
Inventory/availability30-60 secondsChanges with purchases
Cart dataNever cacheAlways personalized
Customer dataNever cacheAlways personalized
Navigation/menus1 hourRarely changes

Optimizing Query Performance

According to Shopify's API rate limits documentation, the key to fast Storefront API queries is minimizing the data you request:

  • Use fragments — define reusable field sets for products, variants, and images
  • Implement pagination — never request first: 250 when you only display 12 items
  • Prefetch on hover — load the next page's data when a user hovers over a link
  • Batch queries — combine related queries into a single request where possible

Search and Predictive Search

The Storefront API includes built-in search functionality that powers product discovery on headless storefronts.

Full Search Query

graphqlgraphql
query Search($query: String!) {
  search(query: $query, first: 20, types: [PRODUCT, ARTICLE, PAGE]) {
    edges {
      node {
        ... on Product {
          id
          title
          handle
          priceRange {
            minVariantPrice {
              amount
              currencyCode
            }
          }
        }
        ... on Article {
          id
          title
          handle
        }
        ... on Page {
          id
          title
          handle
        }
      }
    }
    totalCount
  }
}

Predictive Search

For instant search-as-you-type experiences:

graphqlgraphql
query PredictiveSearch($query: String!) {
  predictiveSearch(query: $query, limit: 5, types: [PRODUCT, COLLECTION, QUERY]) {
    products {
      id
      title
      handle
      variants(first: 1) {
        edges {
          node {
            price {
              amount
              currencyCode
            }
          }
        }
      }
    }
    collections {
      id
      title
      handle
    }
    queries {
      text
      styledText
    }
  }
}

Predictive search results are lightweight and fast — designed for the sub-200ms response times that search-as-you-type demands. If you are building search into an existing Shopify app, the Storefront API search provides a solid foundation.

Internationalization and Multi-Currency

The Storefront API supports international commerce through context — localization parameters that affect pricing, availability, and language.

Setting the Buyer's Context

Pass a @inContext directive to get localized data:

graphqlgraphql
query GetLocalizedProducts @inContext(country: CA, language: FR) {
  products(first: 10) {
    edges {
      node {
        title
        priceRange {
          minVariantPrice {
            amount
            currencyCode
          }
        }
      }
    }
  }
}

Supported Context Parameters

ParameterValuesEffect
countryISO 3166-1 alpha-2 codes (US, CA, GB, etc.)Localizes pricing and availability
languageISO 639-1 codes (EN, FR, ES, etc.)Translates content

Multi-Currency Pricing

When you set the country context, product prices automatically return in the local currency configured in your Shopify Markets settings. This means:

  • A product priced at $50 USD returns as ~$68 CAD when queried with country: CA
  • Currency conversion uses the rates configured in your Shopify admin
  • Fixed local pricing (if configured) overrides automatic conversion

The HelloBizMia Shopify API guide provides additional context on how the internationalization features interact with Shopify Markets configuration.

Common Mistakes and How to Avoid Them

These are the errors that trip up most developers when first working with the Shopify Storefront API.

Exposing the Private Token Client-Side

The private access token grants elevated access to the API. If embedded in client-side JavaScript, anyone can extract it from your page source.

Fix: Use the public token for all browser-side requests. Reserve the private token for server-side code only. Never include it in your frontend bundle.

Not Handling userErrors

Every mutation returns a userErrors array. Ignoring it means silent failures — items not added to cart, discounts not applied, customers not created.

Fix: Always check userErrors after every mutation:

javascriptjavascript
const { data } = await cartLinesAdd(cartId, lines);
if (data.cartLinesAdd.userErrors.length > 0) {
  // Handle the error — show message to user
  console.error(data.cartLinesAdd.userErrors);
  return;
}
// Proceed with success flow

Over-Fetching Data

Requesting every field on every product when you only need titles and prices wastes bandwidth and increases query cost.

Fix: Request only the fields you display. Use GraphQL fragments to standardize your field selections across components.

Ignoring API Versioning

Queries that work on 2025-07 might break on 2026-01 due to field deprecations or breaking changes.

Fix: Pin your integration to a specific API version. Subscribe to Shopify's developer changelog. Test against new versions before upgrading.

Not Forwarding Buyer IP Addresses

Server-side requests without the Shopify-Storefront-Buyer-IP header can trigger Shopify's bot protection, causing legitimate customer requests to be blocked.

Fix: Always extract the customer's IP from the incoming request and forward it in your API calls.

MistakeRisk LevelFix
Private token in client codeCriticalUse public token for browser requests
Ignoring userErrorsHighCheck after every mutation
Over-fetching dataMediumRequest only needed fields
No API version pinningMediumPin to a specific version
Missing buyer IP headerHighForward IP on all server requests

Building a Complete Storefront: Putting It All Together

Diverse devices on geometric platforms linked by blue light trails.

Here is the query architecture for a complete headless storefront, showing which API operations power each page.

Page-to-Query Map

PagePrimary QueryMutations
Homepageproducts (featured), collections (featured)None
Collection pagecollection with products (filtered, sorted, paginated)None
Product pageproduct by handle (with variants, images, metafields)cartCreate, cartLinesAdd
Cart pagecart by IDcartLinesUpdate, cartLinesRemove, cartDiscountCodesUpdate
Search resultssearch or predictiveSearchNone
Customer loginNonecustomerAccessTokenCreate
Customer accountcustomer (orders, addresses)customerUpdate, customerAddressCreate

Architecture Pattern

texttext
Browser (React/Next.js/Hydrogen)
  → Server-side loader (fetch data with private token)
    → Storefront API (GraphQL)
  ← Render HTML with data
  → Client-side mutations (cart actions with public token)
    → Storefront API (GraphQL)
  ← Update UI optimistically

This pattern keeps sensitive operations on the server while allowing fast client-side interactions for cart management. The headless Shopify with Webflow guide shows how this same API powers no-code headless builds.

The Shopify Storefront API is the foundation of every headless Shopify experience. Master the product queries, cart mutations, and checkout redirect pattern, and you can build any custom commerce experience on any platform. Start with the basics covered in this guide, test in Shopify's GraphiQL explorer, and expand from there.

For more developer resources and community support, visit the Talk Shop blog or join the Shopify developer community to connect with other builders.

What are you building with the Storefront API? Share your project in the community.

Headless & HydrogenShopify DevelopmentApps & Integrations
Talk Shop

About Talk Shop

The Talk Shop team — insights from our community of Shopify developers, merchants, and experts.

Related Insights

Related

Best Shopify SEO Apps: 10 Tools Ranked for 2026

Related

Shopify Admin API: A Developer's Guide to Building Custom Integrations

The ecommerce newsletter that's actually useful.

Daily trends, teardowns, and tactics from the top 1% of ecommerce brands. Delivered every morning.

No spam. Unsubscribe anytime. · Learn more

New

Business Name Generator

Generate unique, brandable business names with AI. Check domain availability instantly.

Generate Names

Talk Shop Daily

Daily ecommerce news, teardowns, and tactics.

No spam. Unsubscribe anytime. · Learn more

Try our Business Name Generator