Presence API
Endpoints for presence tracking, user search, and AI integration in chat rooms.
Overview
Presence tracking keeps track of which users are currently active in which rooms. The AI endpoint allows users to get AI-generated responses within chat rooms.
Endpoint Summary
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| POST | /api/presence/switch | Switch rooms (presence tracking) | Yes |
| POST | /api/presence/heartbeat | Refresh global online presence | Yes |
| GET | /api/presence/heartbeat | List globally online users | Yes |
| GET | /api/users?search=... | Search users | Yes |
| POST | /api/ai/ryo-reply | Generate Ryo AI reply | Yes |
| POST | /api/pusher/auth | Authorize a private/presence Pusher channel | Yes |
| POST | /api/realtime/ticket | Mint a local WebSocket realtime ticket | Yes |
Presence
Switch Rooms
Update presence when a user switches between rooms. This is used for real-time "who's online" functionality.
POST /api/presence/switch
Authorization: Bearer {token}
X-Username: alice
Content-Type: application/json
{
"previousRoomId": "general",
"nextRoomId": "random",
"username": "alice"
}
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
previousRoomId | string | No | Room the user is leaving (null if first room) |
nextRoomId | string | No | Room the user is entering (null if leaving all) |
username | string | Yes | User's username |
{
"success": true
}
Use Cases:
- User opens chat app →
previousRoomId: null, nextRoomId: "general"
- User switches rooms →
previousRoomId: "general", nextRoomId: "random" - User closes chat app →
previousRoomId: "random", nextRoomId: null
Global Presence Heartbeat
Track which users are globally online (independent of any specific room). Both methods require authentication.
POST records a heartbeat for the authenticated user (kept in an online sorted-set with a 90-second TTL) and broadcasts a user-heartbeat event on the global presence channel:
POST /api/presence/heartbeat
Authorization: Bearer {token}
X-Username: alice
Response (200):
{
"success": true
}
GET returns the list of currently-online usernames (stale entries older than 90 seconds are pruned):
GET /api/presence/heartbeat
Authorization: Bearer {token}
X-Username: alice
Response (200):
{
"users": ["alice", "bob"]
}
User Search
Search Users
Search for users by username prefix.
GET /api/users?search=ali
Authorization: Bearer {token}
X-Username: alice
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
search | string | Yes | Username search string (minimum 2 chars; shorter queries return 400) |
Requires a valid Authorization token and X-Username pair. User search is rate-limited per authenticated user and can return 429 when the search bucket is exhausted.
{
"users": [
{
"username": "alice",
"lastActive": 1704067200000
},
{
"username": "alicia",
"lastActive": 1704000000000
}
]
}
AI Integration
Ryo Reply
Generate an AI response from Ryo within a chat room. This is triggered when users mention @ryo in their messages.
POST /api/ai/ryo-reply
Authorization: Bearer {token}
X-Username: alice
Content-Type: application/json
{
"roomId": "general",
"prompt": "what's up?",
"systemState": {
"chatRoomContext": {
"recentMessages": "alice: hey everyone\nbob: hi alice\nalice: @ryo what's up?",
"mentionedMessage": "@ryo what's up?"
}
}
}
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
roomId | string | Yes | Room where the mention occurred |
prompt | string | Yes | The user's message/question |
systemState.chatRoomContext.recentMessages | string | No | Recent chat history |
systemState.chatRoomContext.mentionedMessage | string | No | Message that mentioned @ryo |
{
"message": {
"id": "msg_123",
"roomId": "general",
"username": "ryo",
"content": "hey, what's up",
"timestamp": 1704067320000
}
}
Rate Limits
| User Type | Limit | Window |
|---|---|---|
| Authenticated | 5 requests | 1 minute |
AI Behavior
When mentioned in chat rooms, Ryo:
- Considers recent chat context
- Responds in a casual, friendly tone
- Can answer questions, provide information, or just chat
- Respects the room's conversation flow
Realtime Authorization
ryOS supports two realtime providers. The active provider is set by REALTIME_PROVIDER; each authorization endpoint only works for its matching provider (the other returns 400).
Pusher Channel Auth
Authorizes a subscription to an authorization-requiring Pusher channel (private-…, presence-…). The server verifies the authenticated user may access the requested channel before signing. Used with the Pusher provider.
POST /api/pusher/auth
Authorization: Bearer {token}
X-Username: alice
Content-Type: application/json
{
"socket_id": "123.456",
"channel_name": "private-sync-alice"
}
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
socket_id | string | Yes | Pusher socket ID |
channel_name | string | Yes | Channel being subscribed to |
{ "auth": "key:signature" }; presence channels also include channel_data). Returns 403 when the user is not allowed on the channel.
Realtime Ticket (Local Provider)
Mints a short-lived, single-use ticket for authenticating a self-hosted WebSocket connection. The HttpOnly auth cookie is scoped to /api and unreadable from JS, so the WebSocket (on a different path) presents this ticket instead. Only relevant for the local realtime provider.
POST /api/realtime/ticket
Authorization: Bearer {token}
X-Username: alice
Response (200):
{
"ticket": "..."
}
Real-time Updates
Presence changes and AI replies trigger Pusher broadcasts to connected clients:
| Event | Channel | Payload |
|---|---|---|
room-updated | chats-public / chats-{username} | { room } |
room-message | room-{roomId} | { roomId, message } |
Error Responses
| Status | Error | Description |
|---|---|---|
| 400 | Invalid request | Missing or invalid parameters |
| 401 | Authentication required | Token missing (for AI reply) |
| 403 | Unauthorized | Origin not allowed |
| 404 | Room not found | Room ID doesn't exist |
| 429 | Rate limit exceeded | Too many AI requests |
| 500 | Failed to generate reply | AI service error |
Related
- Rooms API - Room endpoints
- Messages API - Message endpoints
- Chat API - Main AI chat endpoint (different from room @mentions)
- AI System - AI providers and capabilities