Refresh Tokens
Refresh tokens enable partners to maintain long-term access to Ring user data by obtaining new access tokens when the current ones expire.
Overview
- Access tokens have limited validity (typically 4 hours / 14400 seconds)
- Refresh tokens are valid for approximately 30 days
- Partners must refresh tokens proactively before they expire — an expired refresh token cannot be recovered and requires the Ring user to re-link their account through the Ring App
- Partners should store refresh tokens securely for continuous access
Authorization: Bearer headers. You MUST exchange them for an access token first using the POST https://oauth.ring.com/oauth/token endpoint described below. Placing a refresh token in the Authorization: Bearer header will result in 401 Unauthorized errors.Quick Start: Exchanging a Refresh Token
HTTP Request
POST https://oauth.ring.com/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&refresh_token=<your_refresh_token>&client_id=<your_client_id>&client_secret=<your_client_secret>
Python Example
import requests
OAUTH_TOKEN_URL = "https://oauth.ring.com/oauth/token"
def exchange_refresh_token(refresh_token, client_id, client_secret):
"""Exchange a refresh token for a new access token."""
response = requests.post(OAUTH_TOKEN_URL, data={
"grant_type": "refresh_token",
"refresh_token": refresh_token,
"client_id": client_id,
"client_secret": client_secret,
})
response.raise_for_status()
tokens = response.json()
# tokens contains: access_token, refresh_token, expires_in, token_type, scope
return tokens
# Usage
tokens = exchange_refresh_token(
refresh_token="your_refresh_token_here",
client_id="your_client_id_here",
client_secret="your_client_secret_here",
)
# Now use the access token for API calls
headers = {"Authorization": f"Bearer {tokens['access_token']}"}
JavaScript Example
async function exchangeRefreshToken(refreshToken, clientId, clientSecret) {
const response = await fetch("https://oauth.ring.com/oauth/token", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "refresh_token",
refresh_token: refreshToken,
client_id: clientId,
client_secret: clientSecret,
}),
});
if (!response.ok) throw new Error(`Token exchange failed: ${response.status}`);
return await response.json();
}
When to Refresh
Ring recommends refreshing tokens in these scenarios:
- Proactive refresh: Based on the
expires_invalue from the token response - Reactive refresh: When receiving HTTP 401 responses from Ring endpoints
Refresh Token Exchange
POST https://oauth.ring.com/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token
refresh_token=<refresh_token>
client_id=<client_id>
client_secret=<client_secret>
Response:
{
"access_token": "xxxxx",
"refresh_token": "yyyyy",
"scope": "<scope>",
"expires_in": 14400,
"token_type": "Bearer"
}
Implementation Best Practices
Token Storage
- Store refresh tokens securely (encrypted at rest)
- Associate tokens with the correct user accounts
- Implement proper access controls
Proactive Refresh Strategy
To prevent refresh token expiry, implement a background job that refreshes tokens before they expire:
import time
# Recommended: refresh tokens every 24 hours to maintain a healthy margin
REFRESH_INTERVAL_SECONDS = 86400 # 24 hours
def background_token_refresh():
"""Background job to proactively refresh all stored tokens."""
for token_record in get_all_active_tokens():
try:
new_tokens = refresh_access_token(token_record.refresh_token)
update_stored_tokens(token_record.account_id, new_tokens)
except Exception as e:
# Alert on refresh failures — may indicate approaching expiry
alert_token_refresh_failure(token_record.account_id, e)
Security Considerations
- Refresh tokens are sensitive credentials
- Rotate refresh tokens regularly (they are updated with each exchange)
- Monitor for tokens approaching the 30-day expiry window
- Implement alerting for failed refresh attempts
- Implement rate limiting to prevent abuse
Related Documentation
- Access Tokens — How to use access tokens in API requests
- Account Linking — How the initial token exchange works

