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