Kuhrt.Codes Shopify

Expiring offline access tokens required

Upcoming

Expiring offline tokens required for all public apps · 82 days

From 2027-01-01 Shopify rejects non-expiring offline access tokens on Admin API requests from public apps, so every public app must migrate to expiring tokens.

Timeline

  1. Not reachedExpiring offline tokens required for all public apps

Who's affected

  • App developers

Public apps must use expiring offline access tokens. This has been required for newly created public apps since 2026-04-01. On 2027-01-01 it becomes required for every public app, including ones created before that date.

Custom apps, including merchant-created apps from the Dev Dashboard or the admin, are not affected. Per the migration guide, enforcement applies to GraphQL Admin API requests.

What breaks

After 2027-01-01, Shopify rejects Admin API requests that use a non-expiring offline token. The response is a 403 Forbidden with the message "Non-expiring access tokens are no longer accepted for the Admin API". Until the app re-authenticates with an expiring token, that merchant's data stops syncing and any feature that calls the Admin API fails.

A missing access scope also returns a 403, so match on the message text before concluding it is this change.

How to check

  • Is the app public? If it is a custom app, nothing changes.
  • Do you store and use offline tokens that came back without expires_in? A token response that includes expires_in is an expiring token.
  • Check your auth code path. Apps that never opted in still receive non-expiring tokens.

The migration guide does not describe a status endpoint that tells you which stored tokens are which, so audit your own token storage.

Check whether your store is affected with the store checker.

How to fix

Apps on Shopify's template (@shopify/shopify-app-remix or the React Router template). Turn on the expiringOfflineAccessTokens future flag in shopifyApp(), then run shopify app deploy.

Token exchange. Add expiring=1 to the ID token exchange request.

Authorization code grant. Add expiring=1 to the request.

Tokens you already store. Exchange each stored token for an expiring one. Send a token exchange request with your client credentials, pass the stored token as subject_token, and set requested_token_type and expiring=1. Note:

  • The migration permanently invalidates the old token.
  • If the response is lost, you can retry within 7 days of the first exchange.
  • Merchants do not need to reinstall the app.

Store and refresh. Save access_token, refresh_token, expires_in and refresh_token_expires_in. Refresh before the access token expires, and store the new refresh token every time, because each refresh returns a new one. Shopify's changelog describes the access token window as 60 minutes.

Need this migration handled?

I audit your store or app, build the replacement and ship it before the cutoff.

Work with me

Sources

Get alerts about Shopify deadlines