Presence
Online status and real-time presence updates
The presence system tracks user online status across sessions. Each user session has its own presence state, and friends can see aggregated presence.
Presence States
Detected Presence
Automatically determined based on client activity:
| State | Description |
|---|---|
online |
User is active |
idle |
No recent activity (5+ minutes) |
offline |
Disconnected |
Presence Override
User-configurable status that modifies detected presence:
| Override | Effect |
|---|---|
detect |
Use detected presence (default) |
idle |
Always show as idle |
dnd |
Do Not Disturb - show as busy |
invisible |
Appear offline to friends |
Effective Presence
What friends actually see, computed from override + detected:
- If override is
invisible→offline - If override is
dnd→dnd - If override is
idle→idle - Otherwise → detected presence
Get Friends Presence
Bulk fetch presence for all friends.
GET /v1/presence/friends
Authorization: Bearer sess_...
Response:
{
"data": {
"friends": [
{
"user_id": 123,
"display_name": "Friend1",
"presence": "online",
"status_text": "Playing OCVR",
"last_seen": 1703523600
},
{
"user_id": 456,
"display_name": "Friend2",
"presence": "offline",
"status_text": null,
"last_seen": 1703500000
}
]
}
}
Get User Presence
Get detailed per-session presence for a specific user (must be friends).
GET /v1/users/{userID}/presence
Authorization: Bearer sess_...
Response:
{
"data": {
"user_id": 123,
"sessions": [
{
"session_id": "sess_abc...",
"presence": "online",
"last_heartbeat": 1703523600
}
],
"effective_presence": "online"
}
}
Update Session Presence
Update presence override for a specific session.
PUT /v1/sessions/{sessionID}/presence
Authorization: Bearer sess_...
{
"override": "dnd"
}
Update Current Session Presence
PUT /v1/sessions/current/presence
Authorization: Bearer sess_...
{
"override": "invisible"
}
Update All Sessions Presence
Set the same override for all active sessions.
PUT /v1/sessions/all/presence
Authorization: Bearer sess_...
{
"override": "detect"
}
Graceful Offline Beacon
Called when client is closing to immediately mark as offline (instead of waiting for heartbeat timeout).
POST /v1/presence/offline
Authorization: Bearer sess_...
This is typically called using navigator.sendBeacon() on page unload.
WebSocket Presence
For real-time presence updates, connect to the WebSocket and subscribe to presence events. See WebSocket Protocol for details.
Presence changes are pushed to friends via WebSocket:
{
"type": "presence_update",
"data": {
"user_id": 123,
"presence": "idle",
"status_text": "AFK"
}
}