Access denied for storefrontAccessTokenCreate field

storefrontAccessTokenCreate returns ACCESS_DENIED despite unauthenticated scopes being granted

Problem

We are trying to call storefrontAccessTokenCreate via the Admin API to generate a Storefront Access Token so we can use cartNoteUpdate and cartAttributesUpdate mutations on the Storefront API. Despite having the required unauthenticated_* scopes granted, we are still getting ACCESS_DENIED.


Step 1 — Confirmed granted scopes via appInstallation.accessScopes

Request:

curl -X POST "https://<store>.myshopify.com/admin/api/2026-01/graphql.json" \
  -H "X-Shopify-Access-Token: <token>" \
  -H "Content-Type: application/json" \
  -d '{"query": "{ appInstallation { accessScopes { handle } } }"}'

Response (relevant scopes only):

{
  "data": {
    "appInstallation": {
      "accessScopes": [
        {"handle": "unauthenticated_write_checkouts"},
        {"handle": "unauthenticated_read_checkouts"}
      ]
    }
  }
}

The unauthenticated_write_checkouts and unauthenticated_read_checkouts scopes are confirmed as granted.


Step 2 — Called storefrontAccessTokenCreate with the same token

Request:

curl -X POST "https://<store>.myshopify.com/admin/api/2026-01/graphql.json" \
  -H "X-Shopify-Access-Token: <token>" \
  -H "Content-Type: application/json" \
  -d '{"query": "mutation { storefrontAccessTokenCreate(input: { title: \\"Cart Metafields\\" }) { storefrontAccessToken { accessToken title } userErrors { field message } } }"}'

Response:

{
  "errors": [
    {
      "message": "Access denied for storefrontAccessTokenCreate field.",
      "extensions": {
        "code": "ACCESS_DENIED",
        "documentation": "https://shopify.dev/api/usage/access-scopes"
      }
    }
  ],
  "data": {
    "storefrontAccessTokenCreate": null
  }
}

What we’ve tried

  • Added unauthenticated_write_checkouts and unauthenticated_read_checkouts to the app’s scopes in shopify.app.toml and deployed
  • Verified scopes are reflected in appInstallation.accessScopes
  • The token used is an offline Admin API access token obtained via standard OAuth flow
  • The Partner Dashboard shows no “Storefront API” or “Unauthenticated access scopes” section for this app

Question

Why does storefrontAccessTokenCreate return ACCESS_DENIED even though unauthenticated_write_checkouts is granted? Is there an additional requirement (e.g. Sales Channel flag, specific app type) that is not documented?

Hi @Mehmet_Talha_Seker! The storefrontAccessTokenCreate mutation requires the app to have at least one unauthenticated scope, and you have two, so that check passes.

Can you share a bit more about how your app was created and how it’s installed?

  • Was it created in the Shopify Admin, Partner Dashboard, the Dev Dashboard (dev.shopify.com/dashboard), or via shopify app init with the CLI?

  • Is it a public app or a custom app?

  • How did you obtain the Admin access token you’re using? Specifically, is this through authorization code grant, token exchange, or client credentials grant?

If your app is a partner/public app and you need Storefront API access, you may need to configure it as a sales channel. This was discussed in detail here and here.

One other thing to confirm is that the token you’re using is an offline token (not an online/session token), since online tokens are also blocked from this mutation. If you can also grab the x-request-id response header from a denied request, that would help us look into it further on our end.

Hi @Donal-Shopify, thanks for the follow-up!

To answer your questions:

  • The app is a public app created via the Partner Dashboard.
  • The Admin access token is obtained via token exchange using grant_type: urn:ietf:params:oauth:grant-type:token-exchange and requested_token_type: urn:shopify:params:oauth:token-type:offline-access-token. So it is confirmed to be an offline token.

Here is the x-request-id from a denied request: 99d5889a-4f46-47a1-9f94-4e29f8d97f36-1774946984

Regarding the sales channel requirement: our use case is simply writing cart notes and attributes during checkout (cartNoteUpdate / cartAttributesUpdate). We’d prefer not to go through the sales channel approval process just for this. Is there truly no way to use storefrontAccessTokenCreate from a non-sales-channel public app with unauthenticated_write_checkouts granted?

Thanks @Mehmet_Talha_Seker! I took a closer look at the request you shared and your scopes are confirmed present on the installation, so this isn’t a missing-scope issue in the traditional sense.

The behavior you’re seeing is tied to how Shopify determines whether an app is eligible for Storefront API token creation. The storefrontAccessTokenCreate mutation requires Storefront API availability to be enabled at the app level, and Shopify only considers required scopes (the ones in the scopes field of your app config) when making that determination. If your unauthenticated scopes are declared as optional scopes rather than required, Shopify will treat the app as not having Storefront API access, and the mutation will return ACCESS_DENIED even though the scopes show up as granted on the installation.

Check your shopify.app.toml and make sure unauthenticated_write_checkouts (and any other unauthenticated scopes you need) are in the main scopes field, not just in optional_scopes. After updating, deploy a new version and reinstall on the store so the change takes effect. This was a similar issue to what was resolved here and here, where the fix came down to getting the right unauthenticated scopes into the required set plus using an offline token.

Let me know if the error persists after that change.

Hey folks, just want to say that I saw an error popup yesterday, that looks to be the same. We definitely have the correct scopes

This specific issue has been occurring infrequently, and randomly for us since 2024:

It seems these scopes weren’t sufficient on their own:

  • unauthenticated_write_checkouts

  • unauthenticated_read_checkouts

Adding unauthenticated_read_product_listings resolved the issue for me.

Thanks to everyone who contributed, especially “Gavin M” from the Shopify team!

1 Like