Guide

OAuth Refresh Token Management for Email

Every OAuth integration breaks the same way: the access token expires, nobody refreshed it, and the cron job that worked yesterday returns 401 today. Access tokens are short-lived by design; refresh tokens mint new ones without bothering the user. This guide explains how the refresh flow works, what silently invalidates a refresh token, and how Nylas runs the refresh loop for you so a long-running email job doesn't fall over an hour after it starts.

Written by Prem Keshari Senior SRE

VerifiedCLI 3.1.16 · Gmail, Outlook · last tested June 8, 2026

Command references used in this guide: nylas auth login, nylas auth status, and nylas auth whoami.

What is a refresh token?

A refresh token is a long-lived credential that exchanges for new access tokens without asking the user to log in again. OAuth 2.0 issues two tokens at consent: a short-lived access token for API calls and a refresh token your app stores to mint replacements. The flow is defined in RFC 6749, section 6.

The split exists for security. A leaked access token is dangerous for only its short lifetime, while the refresh token — the more sensitive secret — stays on your server and is presented only to the token endpoint. That's why access tokens expire fast and refresh tokens are guarded: the design limits the blast radius of any single stolen token.

Why do access tokens expire so quickly?

Access tokens expire quickly to bound the damage of a leak. Google's access tokens default to a 3,600-second (one-hour) lifetime, and Microsoft's sit in a similar range. After that, the token is dead and any API call returns a 401, which is the exact moment unmanaged integrations break — the script that authenticated this morning fails this afternoon with no code change.

The fix is to refresh before or upon expiry: present the refresh token to the token endpoint and receive a fresh access token, then retry the call. Done right, expiry is invisible. Done wrong — or not at all — it's the single most common cause of “it worked yesterday” OAuth failures in cron jobs and background workers.

# The raw refresh exchange every OAuth integration must implement:
curl -s -X POST https://oauth2.googleapis.com/token \
  -d client_id=$CLIENT_ID \
  -d client_secret=$CLIENT_SECRET \
  -d refresh_token=$REFRESH_TOKEN \
  -d grant_type=refresh_token
# Returns a new access_token valid ~3600s. You must store, schedule,
# and retry this — per user, per provider — or the integration dies hourly.

How does Nylas manage refresh for you?

Nylas stores the refresh token behind the grant and exchanges it for new access tokens as needed, so your code never runs the refresh loop. A command like nylas email list works whether it's the first call after login or the thousandth call days later — the platform has kept the token current. That's the difference between a one-hour demo and a job that runs for months.

Because refresh is handled per grant, a long-running script or an AI agent that polls an inbox doesn't accumulate token-management code. Check a grant's health with nylas auth status; if a token genuinely can't be refreshed — because it was revoked or the password changed — the status reflects it and the fix is to reconnect.

# No refresh code needed — the grant stays current
nylas auth login --provider google      # once
nylas email list --json --limit 10      # works now and in a week

# Inspect grant health if a call starts failing
nylas auth status

What revokes or breaks a refresh token?

A refresh token stops working for a handful of specific reasons: the user revokes the app's access in their account settings, the user changes their password (which Google and Microsoft treat as a revocation event), the token goes unused past the provider's inactivity window, or an admin removes the user or the app. When any of these happens, the next refresh fails with invalid_grant, and no amount of retrying helps.

The only fix for a revoked refresh token is fresh user consent — there's no programmatic recovery, by design. Detect the failed grant (its status will show the problem), prompt the user, and reconnect with nylas auth login. For the specific error and its causes, see the invalid_grant troubleshooting guide.

Next steps