Storefront API Generation of delegate access token Shopify-Storefront-Private-Token

Topic summary

Developers are unable to properly generate and use delegate access tokens for the Shopify Storefront API’s Shopify-Storefront-Private-Token header, which is critical for server-side Hydrogen and headless storefronts to avoid rate limiting.

Core Issue:

  • Documentation instructs using delegate access tokens with the Shopify-Storefront-Private-Token header for server-to-server requests
  • The storefrontAccessTokenCreate mutation generates tokens, but they return 403 errors when used in the intended header
  • This blocks deployment of high-traffic Hydrogen sites

Resolution:
Shopify staff (_JCC) confirmed incremental rollout, initially limited to Hydrogen on Oxygen for Plus merchants. The feature is now live with updated documentation.

Working Solution:
Use the delegateAccessTokenCreate mutation (not storefrontAccessTokenCreate) with unauthenticated scopes like unauthenticated_read_product_listings, unauthenticated_write_checkouts, etc.

Important Notes:

  • The app generating the delegate token must already possess the requested scopes
  • Cannot execute the mutation via Shopify’s GraphiQL App; requires external tools (Postman/cURL) with proper admin API access token
  • Scope requirements differ from initial documentation examples
Summarized with AI on November 25. AI used: claude-sonnet-4-5-20250929.

Hi JCC

Thanks for letting us know the new documentation is up. It looks as if this has been revised a little in the last day or so. But for those looking I’ve managed to successfully create a token!

What the documentation doesn’t make clear is what has changed. It is now possible to create a delegate access token with various unauthenticated scopes.

Below is the GraphQL admin API mutation required to create a delegate token with the correct access scopes to be used in the Shopify-Storefront-Private-Token header. The access scope list used is identical to that of a token created using the storefrontAccessTokenCreate mutation.

mutation {
  delegateAccessTokenCreate(input: { delegateAccessScope: [
    "unauthenticated_read_content",
    "unauthenticated_read_customer_tags",
    "unauthenticated_read_product_tags",
    "unauthenticated_read_product_inventory",
    "unauthenticated_read_product_listings",
    "unauthenticated_write_checkouts",
    "unauthenticated_read_checkouts",
    "unauthenticated_write_customers",
    "unauthenticated_read_customers",
    "unauthenticated_read_selling_plans",
    "unauthenticated_read_product_pickup_locations"
   ] 
  })
  {
    delegateAccessToken {
      accessToken
    }
    shop {
      id
    }
    userErrors {
      field
      message
    }
  }
}

It would be great if we could see the delegate access token documentation updated with a list of valid scope strings and perhaps even an example like the above :blush:

2 Likes