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 invisibleoffline
  • If override is dnddnd
  • If override is idleidle
  • 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"
  }
}
-- ---