as

Settings
Sign out
Notifications
Alexa
Amazon Appstore
Ring
AWS
Documentation
Support
Contact Us
My Cases
Ring

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

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:

  1. Proactive refresh: Based on the expires_in value from the token response
  2. 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