Developer Changelog / Auth & Tokens

Expiring offline access tokens
There is now a "recovery path" from a failed refresh

Even if you drop the refresh response, the refresh token you just used survives "until you start using the replacement token." Apps that missed the 60-minute grace window can now recover on their own, with no merchant reinstall. No migration work required.

On this page
  1. What actually changed (in 30 seconds)
  2. Diagram: when things go wrong, and the recovery path
  3. Old behavior vs. new behavior
  4. Three timelines (until the replacement is used / 30 days / 90 days)
  5. Which apps are affected, and which aren't
  6. What your app needs to do (no migration)
  7. 5 points developers should know
  8. 3 use cases you can put to work
  9. A one-line summary for your pitch

1What actually changed

Refreshing an expiring offline access token nowkeeps the refresh token you just used until your app starts using the replacement token.
Apps that lost or failed to save the refresh response can recover from that point.No migration required.

Before: a 60-minute hourglass

After using a refresh token, you could retry with that same token for up to 60 minutes. Past that window, the stored old refresh token was no longer usable. An app that dropped the response was stuck.

Now: valid "until the replacement is used"

The stored old refresh token can be retrieduntil your app starts using the replacement refresh token. The deadline is your app's state, not a clock.

A new API version, configuration changes, and opt-in are allunnecessary. It takes effect automatically as part of the rollout. That said, the responsibility to store the token pair atomically still sits with your app, just as before.

2Diagram: when things go wrong, and how to recover

① Normal flow App sends a refresh request Shopify processes it and returns a new token pair App stores the pair atomically Success: the new token is used from here on ② This is where it breaks (a drop before the save) Network blip / worker crash / DB write failure Shopify has processed it, the app hasn't saved it Old behavior: past 60 minutes, you're stuck Your refresh token was invalidated, and the merchant had to revisit the app New behavior: you can recover Retry with the stored old refresh token → get a fresh pair back You can retry "until you start using the replacement refresh token" — the moment you use it, the previous token is retired
The heart of the problem is "Shopify has processed the refresh, but the app hasn't saved the pair it got back" — a mismatch. That gap can open up anywhere: the network, the worker, or the DB. No amount of careful implementation drives it to zero, which is why the platform now provides a recovery path.

3Old behavior vs. new behavior

ItemBeforeNow
Can the old refresh token be retried? Up to 60 minutes Retryable only for a fixed window after use Until you use the replacement Determined by state, not by time
Behavior when the response is lost Past the window the old token is unusable → no way to recover Retry with the stored old token and get a new pair
Merchant action The merchant had to reopen the app None The app can recover on its own
When the old token is retired Elapsed time The moment the app uses thereplacement refresh token
Work required to adopt it None No API version update, setting change, or opt-in required
Overall token lifetime The usual 90 days is never extended

4Don't mix up the three timelines

First use Until the replacement is used ← Window in which the old token can still be retried (state-dependent) 30 days (from first use) ← Hard cap on the recovery window. Past this point, the recovery path is no longer available 90 days: the normal lifetime of a refresh token (this recovery behavior does not extend it) End of lifetime * The 30 days are counted from the first use of the original refresh token
State

Until the replacement is first used

The instant the app uses the replacement refresh token, the previous token is retired. In other words, the trigger that closes the recovery path is the app's own action.

Cap

30 days

The recovery window runs for up to 30 days from the first use of the original refresh token. Old tokens don't survive indefinitely just because they're left alone.

Unchanged

90 days

A refresh token's inherent lifetime is still 90 days. This change does not extend a token's life.

5Which apps are affected, and which aren't

Affected: apps that use expiring offline access tokens

The new behavior applies automatically. No new API version, setting change, or opt-in is required.

Not affected: apps that don't use expiring offline access tokens

No impact. The changelog says nothing further about them.

The rollout start and completion dates, which stores are covered, and any impact on online access tokens are not stated. Nothing is stated about changes to error codes or response formats either (only the behavior change is announced).

6What to do on the app side (no migration needed)

If you already use expiring offline access tokens, no migration is required. The four points below are called out as things you should continue to observe.

1

Serialize per shop

Serialize refresh operations per shop. Never run concurrent refreshes.

2

Store the pair atomically

Persist the returned access token and refresh token ina single transaction.

3

Always use the latest one

For subsequent refreshes, use the latest refresh token . Never mix the older one back into normal operation.

4

Strictly a recovery path

Do not treat it as a reason to keep using the old token once you have already stored the replacement. It is an emergency exit, not a door you walk through every day.

As long as atomic storage holds, this change quietly works as insurance that pays off if something goes wrong. Conversely, an implementation that saves the access token first and writes the refresh token later makes the post-incident state hard to reason about. In effect, this announcement is also a message to double-check your atomic storage.

75 key points for developers

1. Invalidation now depends on state, not time

The old behavior was a 60-minute window after use. The new behavior retires the old token once your app starts using the replacement token. If your tests or retry design carry assumptions based on the clock , now is the time to revisit them.

2. Atomic storage is still the app's responsibility

The platform has only added a recovery path; your obligation to write the access token and refresh token as a pair is unchanged. If a code path can still write just one of them, the state management that the recovery path assumes falls apart.

3. Per-shop serialization is a prerequisite

The announcement explicitly states that refreshes must be serialized per shop. If multiple workers hit refresh at the same time, determining which token is the latest breaks down. Mutual exclusion via a distributed lock or a queue is still required.

30d

4. The recovery window has limits (30 days / 90 days)

Recovery is only possible within 30 days of the original refresh token's first use, and the usual 90-day lifetime is not extended. A store left broken for months still cannot be saved, so detection and alerting for refresh failures remain necessary.

5. Zero adoption cost, but a good opportunity for a review

No new API version, configuration change, or opt-in is required, so you get the benefit without doing anything. That said, the continue to list in the announcement is itself an audit checklist for your existing implementation (per-shop serialization / atomic storage of the pair / using the latest token / never using the recovery path routinely). Checking whether you satisfy these four points is worth doing now.

83 practical use cases

!
USE CASE 1

Reduce authentication-expired support tickets for public apps

Challenge
For a tenant that dropped the refresh response, API calls keep failing, and merchants reach out saying that sync has stopped. Recovery required walking them through reopening the app.
Approach
When you detect a refresh failure, run a recovery job that retries with the stored refresh token (with this change, it succeeds as long as you have not started using the replacement). Also set up alerts to detect affected tenants.
Impact
Fewer recovery instructions that require merchant action. Lower support workload and less churn risk caused by expired authentication.
Technical note
Recovery is only possible within 30 days of the original token's first use. Tenants past that point cannot be saved, so run detection on a faster cycle than daily.
worker worker worker
USE CASE 2

Audit token refresh in multi-worker setups

Challenge
Background jobs run in parallel across multiple workers, so refreshes for the same shop can fire at the same time. Which token is the newest becomes situation-dependent and unreliable.
What to do
Turn the four "continue to" items in the announcement into an audit checklist: ① Are refreshes serialized per shop? ② Are the access/refresh tokens stored atomically? ③ Are you always using the latest token? ④ Are you routinely using stale tokens?
Impact
You can guarantee that this new recovery path actually works when you need it, and prevent recurring intermittent 401s caused by tokens.
Technical note
The old token is retired the moment you use the replacement token. If you want to keep the recovery path open, it pays to design so that the old token is not discarded between saving the new token and actually starting to use it.
Operations runbook
USE CASE 3

Add a "token recovery procedure" to your incident response runbook

Problem
When cleaning up after a failed DB write or a worker failure, the only way to recover a tenant with broken tokens was "ask the merchant to come back and reauthorize" — hard to write up as a procedure.
What to do
Add a section to the runbook: "identify the shops that ran a refresh during the incident window and retry with the stored refresh token." Spell out the recovery window as well (30 days from first use, and only while the replacement token is unused).
Impact
Post-incident cleanup becomes routine, cutting both response time and the number of times you have to contact merchants.
Technical note
This path is strictly for recovery. Shopify explicitly states that you must not make a habit of reusing the old token for shops that already have a replacement token stored.

9One-line summary you can use in a proposal

"Even if you drop the refresh response, the previous refresh token now stays aliveuntil you start using the replacement token— that's the new behavior.
Zero migration work, no API version bump, and you can recover from an expired auth state on your own, with no merchant action required.
There's exactly one thing to do: confirm that you store the token pair atomically and serialize refreshes per shop."