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.
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.
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.
| Item | Before | Now |
|---|---|---|
| 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 |
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.
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.
A refresh token's inherent lifetime is still 90 days. This change does not extend a token's life.
The new behavior applies automatically. No new API version, setting change, or opt-in is required.
No impact. The changelog says nothing further about them.
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.
Serialize refresh operations per shop. Never run concurrent refreshes.
Persist the returned access token and refresh token ina single transaction.
For subsequent refreshes, use the latest refresh token . Never mix the older one back into normal operation.
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.
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.
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.
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.
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.
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.