{ accessToken, expiresAt, scopes } — never a refreshToken, Google
doesn't rotate it — or null when the grant was revoked or expired
(invalid_grant). Any other failure (network, 5xx, quota) throws so a
caller counting consecutive failures doesn't mistake an outage for a
revocation.
Trades a refresh token for a new access token.