# Shopify rejects non-expiring offline access tokens from public apps on 2027-01-01

- **Provider:** Shopify
- **Endpoint:** `POST /admin/api/{version}/graphql.json`
- **Effective:** 2027-01-01
- **Severity:** critical
- **Change:** auth
- **Status:** verified

## What changed

Starting January 1, 2027, every public app (including ones created before April 1, 2026) must use expiring offline access tokens to call the Admin API. Shopify enforces this on GraphQL Admin API requests: a request with a non-expiring token gets 403 Forbidden with "Non-expiring access tokens are no longer accepted for the Admin API", and merchants lose access until they re-authenticate. Custom apps and merchant-created apps are not affected.

## What to do

Exchange each stored non-expiring token for an expiring one with POST /admin/oauth/access_token (grant_type=urn:ietf:params:oauth:grant-type:token-exchange, subject_token_type and requested_token_type urn:shopify:params:oauth:token-type:offline-access-token, expiring=1), store the access token, refresh token and expiry, and refresh before expiry; on the official app templates set future.expiringOfflineAccessTokens: true and redeploy. Check API Health in the Dev Dashboard to confirm the app is migrated.

## Sources

- Provider notice (2026-05-20): https://shopify.dev/changelog/posts/expiring-offline-access-tokens-required-for-all-public-apps-as-of-january-1-2027
- https://shopify.dev/docs/apps/build/authentication-authorization/migrate-to-expiring-offline-access-tokens

## Machine-readable

- Advisory: https://github.com/SriVarshini09/shapi-advisories/blob/main/advisories/shopify-non-expiring-offline-tokens-rejected.json
- OSV: https://shapi.dev/osv/shopify-non-expiring-offline-tokens-rejected.json
