How to handle single-use refresh tokens
How to handle single-use refresh tokens
Calendly is updating its OAuth 2.1 implementation to better protect against token replay and abuse. The main change is in how refresh tokens behave when you call the POST /oauth/token endpoint.
This guide explains what’s changing and shows the correct way to implement refresh token rotation so your integration keeps working smoothly.
What’s Changing
Previously, a refresh token could be successfully reused multiple times, and was only revoked indirectly after an access token created from it was used.
Going forward, Calendly will use single-use refresh tokens with rotation, aligned with OAuth 2.1 best practices:
- A refresh token is revoked immediately after a successful
POST /oauth/tokencall. - Each successful response from
POST /oauth/tokenwill still return a new access token and a new refresh token. - Access token behavior (lifetime, scopes, etc.) does not change.
If your integration tries to reuse a refresh token that has already been used, the request will fail after this change.
How Your Integration Should Handle Refresh Tokens
Calendly recommends that your OAuth client:
- Treats refresh tokens as single-use.
- Immediately overwrites the stored refresh token with the new
refresh_tokenfrom every successfulPOST /oauth/tokenresponse. - Does not keep or reuse older refresh token values.
In practice, your logic should be:
- Call
POST /oauth/tokenwith the current authorization code or refresh token. - On success, update your storage with the new
access_tokenandrefresh_tokenfrom the response. - Only ever use the most recently stored refresh token for future refreshes.
If you already overwrite the stored refresh token on each successful refresh today, you should not need to change your integration.
Example: Correct Refresh Token Rotation
Handling a Token Response
Refreshing an Access Token Safely
This approach ensures:
- Each refresh token is used once and rotated away.
- On refresh failure (e.g., 400/401), you clear tokens and ask the user to re-authorize instead of retrying endlessly.
- Refresh tokens are handled only on the server side, in secure storage.
Next Steps, Timeline, and Support
The deadline for updating your refresh token behavior is August 31, 2026. Before then, we recommend:
- Reviewing your token storage and rotation logic.
- Confirming you overwrite refresh tokens on each successful refresh.
- Verifying that your error handling cleanly falls back to a new authorization when a refresh fails.
If you have questions or need help updating your integration, please contact Calendly developer support.
FAQs
Q: What changed with Calendly’s OAuth refresh tokens?
Calendly is updating its OAuth implementation to use single-use refresh tokens with rotation, per OAuth 2.1 guidelines. Previously, a refresh token could be reused multiple times to get new access tokens. Going forward, each refresh token can only be used once — when you use it to refresh, that refresh token becomes invalid and you’ll get a new refresh token in the response. This means your integration needs to update the stored refresh token every time you refresh the access token. The access tokens themselves and their lifespans haven’t changed, but refresh tokens now rotate on each use for improved security.
Q: Why is Calendly making this change?
This change is to improve security and align with OAuth 2.1 best practices. Single-use (rotating) refresh tokens help protect against token replay attacks and abuse. OAuth 2.1 formalizes an approach to make integrations more secure.
Q: What do I need to update in my integration?
You need to ensure your OAuth client code handles refresh tokens as single-use and implements refresh token rotation. In practice, this means: after calling POST /oauth/token, take the new refresh_token returned in the response and save it (replace the old one). Do not reuse the old refresh token again. Most OAuth libraries already have support for this — double-check your library’s docs. If you implemented the flow manually, add logic to update the stored token. Also, make sure your error handling is ready: if you use an outdated refresh token, the API will return an invalid_grant error.
Q: Will my existing refresh tokens stop working? Do users need to re-authenticate right now?
There’s no immediate hard cut-off that invalidates all refresh tokens, but behavior is changing once the feature rolls out. Existing refresh tokens will still work, but only for one use each once rotation is enforced. End-users do not have to re-authenticate immediately if your integration is updated to handle rotation.
Q: How will I know if I’ve implemented refresh token rotation correctly?
Go through a token refresh cycle twice in a row. Use refresh token R1 to get a new token (response gives you R2). Any attempt to reuse R1 should be rejected. Use R2 to get another token (yields R3). If your integration always uses the latest refresh token and that flow works continuously, you’ve implemented it correctly.
Q: What error will I get if I don’t update my code?
If your code reuses an old refresh token, the Calendly API will respond with HTTP 400 or 401 and the JSON error invalid_grant. This means the token was already used and is now revoked.
Q: Is there a deadline for making these changes?
The enforcement deadline is August 31, 2026. It’s highly recommended to update your integration now rather than waiting.
Q: My app was working fine, why fix it if it isn’t broken?
While your integration might appear fine today, the change is about to be in effect or already active for new apps. If your app is older, Calendly provided a grace period, but that will end. Think of this like deprecation of an old API method — it might still work for now, but it will break once enforcement begins. Adopting the new logic now is beneficial for security and prevents future emergencies when the old behavior is turned off.