← Back to Blog
Guides10 min read

Implementing Real-Time Activity Tracking

Build live presence indicators using Xbox's RTA WebSocket system for instant updates.

Real-Time Activity (RTA) is Xbox Live's WebSocket-based system for receiving instant updates about player activity. Unlike polling the /presence endpoint, RTA pushes changes to you the moment they happen. This guide shows you how to connect and subscribe to events.

RTA vs Presence Endpoint

The /api/v2/presence endpoint is great for one-off lookups, but it requires polling. RTA is different: you establish a persistent WebSocket connection and Xbox pushes updates to you instantly when something changes.

Use RTA when you need real-time updates (Discord bots, live dashboards). Use the presence endpoint for simple lookups or when WebSockets aren't practical.

Step 1: Get Your RTA Nonce

First, request a connection nonce from OpenXBL. This is a one-time token that authenticates your WebSocket connection:

curl -X GET "https://xbl.io/api/v2/rta" \
  -H "X-Authorization: YOUR_API_KEY"

The response contains a nonce string you'll use to connect. Nonces expire quickly, so connect immediately after obtaining one.

Step 2: Connect to the WebSocket

Connect to Xbox's RTA WebSocket using the nonce. Note the specific protocol string required:

const nonce = 'YOUR_NONCE_FROM_API';
const socket = new WebSocket(
  'wss://rta.xboxlive.com/connect?nonce=' + nonce,
  'rta.xboxlive.com.V2'
);

socket.onopen = function(e) {
  console.log('Connected to RTA');
  // Now subscribe to events (see below)
};

socket.onmessage = function(event) {
  const message = JSON.parse(event.data);
  console.log('RTA event:', message);
};

socket.onclose = function(event) {
  console.log('RTA connection closed:', event.code, event.reason);
};

socket.onerror = function(error) {
  console.log('RTA error:', error);
};

Step 3: Subscribe to Events

Once connected, subscribe to the events you want. Subscriptions use a simple format: [1, subscriptionId, "resourceUrl"]

Important: Subscribe to other players' XUIDs, not your own. The system is designed for tracking friends and other users.

// Subscribe to rich presence (what game they're playing)
socket.send('[1,0,"https://userpresence.xboxlive.com/users/xuid(FRIEND_XUID)/richpresence"]');

// Subscribe to party details
socket.send('[1,1,"http://sessiondirectory.xboxlive.com/users/xuid(FRIEND_XUID)/partydetails"]');

// Subscribe to multiplayer activity
socket.send('[1,2,"https://multiplayeractivity.xboxlive.com/users/xuid(FRIEND_XUID)"]');

// Subscribe to friends list changes
socket.send('[1,3,"http://social.xboxlive.com/users/xuid(FRIEND_XUID)/friends"]');

Available Subscription Types

Here are the main event types you can subscribe to:

  • Rich Presence: Game title, activity text, and online state
  • Party Details: Party membership and session info
  • Multiplayer Activity: Game session joins and invites
  • Friends: When someone adds/removes friends

Handling Webhook-Style Updates

If you need to forward RTA events to your backend (webhook-style), set up a simple relay server:

// Node.js example - relay RTA to your webhook
socket.onmessage = async function(event) {
  const message = JSON.parse(event.data);

  await fetch('https://your-server.com/webhook/xbox-rta', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      type: 'rta_event',
      data: message,
      timestamp: new Date().toISOString()
    })
  });
};

Connection Management

RTA connections can drop for various reasons. Implement reconnection logic:

let reconnectAttempts = 0;

socket.onclose = async function(event) {
  if (reconnectAttempts < 5) {
    reconnectAttempts++;
    console.log('Reconnecting...', reconnectAttempts);

    // Get a fresh nonce and reconnect
    const response = await fetch('https://xbl.io/api/v2/rta', {
      headers: { 'X-Authorization': 'YOUR_API_KEY' }
    });
    const { nonce } = await response.json();

    // Reconnect after a short delay
    setTimeout(() => connectRTA(nonce), 1000 * reconnectAttempts);
  }
};

Rate Limits and Best Practices

RTA connections are long-lived and don't count against your hourly rate limit. However, fetching new nonces does use API calls. Best practices:

  • Maintain a single connection and multiplex subscriptions
  • Don't subscribe to more XUIDs than you need
  • Implement exponential backoff for reconnections
  • Handle connection drops gracefully