The realtime layer of the Workforce Intelligence OS combines a persistent WebSocket channel with REST endpoints that write to and read from that same event pipeline. Every connected client receives server-initiated events — new messages, meeting invites, presence changes, notification counts — without polling. All REST paths are prefixed withDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/Paramount-Intelligence/HR_Monitoring_System/llms.txt
Use this file to discover all available pages before exploring further.
/api/v1. The WebSocket endpoint lives at /api/v1/ws.
The WebSocket endpoint does not accept a JWT via query string. Direct
?token= usage is rejected with close code 1008 (Policy Violation). You must first exchange a JWT for a short-lived WS ticket and pass that instead.Obtaining a WebSocket Ticket
Before opening a WebSocket connection, the client must call the ticket-issuance endpoint with its JWT.POST /api/v1/auth/ws-ticket
Issues a single-use, short-lived WebSocket connection ticket (TTL: 60 seconds).
Auth: Any authenticated user (Authorization: Bearer <token>).
A URL-safe random string (32 bytes, base64-encoded). Pass this as the
ticket query parameter when upgrading to WebSocket.Seconds until the ticket expires. Always
60.Example Request
Example Response
WebSocket Connection
GET /api/v1/ws
Upgrades the HTTP connection to a WebSocket session. Authentication is performed server-side by consuming the ticket before accepting the socket.
Query Parameters:
Single-use WS ticket obtained from
POST /api/v1/auth/ws-ticket.Client platform hint. Accepted values:
web (default), mobile. Any other value is normalised to web.- Server validates and consumes the ticket.
- On success, the user is marked online via
OnlinePresenceService. - Server sends an immediate
connectedevent. - Server sends a
pingevery 30 seconds — the client should respond with apongmessage. - On disconnect, the user’s presence record is updated to reflect the connection closure.
| Code | Reason |
|---|---|
1008 | Missing ticket, invalid ticket, expired ticket, inactive user |
1011 | Internal server error during connection setup |
JavaScript Connection Example
Realtime Event Shape
All events delivered over the WebSocket follow theRealtimeEvent schema:
Event type identifier, e.g.
connected, ping, new_message, notification_created.UUID assigned to this event instance (useful for deduplication).
ISO-8601 UTC timestamp of event emission.
Event-specific data dictionary.
UUID of the user who triggered the event, if applicable.
Associated conversation UUID, if applicable.
Type of related entity, e.g.
"meeting", "call", "task".UUID of the related entity.
| Event Type | Description |
|---|---|
connected | Sent immediately after a successful WS handshake |
ping | Server heartbeat — respond with { "type": "pong" } |
pong | Server response to a client-initiated ping |
new_message | A new message was sent to one of the user’s conversations |
message_updated | An existing message was edited |
message_deleted | A message was soft-deleted |
conversation_updated | A conversation’s metadata (title, settings) changed |
conversation_participants_added | New members were added to a group/channel |
conversation_read | A participant marked a conversation as read |
notification_created | A new in-app notification was created for this user |
notifications_count_updated | The unread notification count changed |
notification_read | A specific notification was marked as read |
announcement_created | A new announcement was published matching the user’s audience |
meeting_created | The user was invited to a new meeting |
meeting_updated | A meeting the user is part of was updated |
meeting_deleted | A meeting was cancelled |
meeting_rsvp_updated | A participant RSVP status changed |
call_incoming | An inbound voice/video call is ringing |
call_accepted | The other party accepted the call |
call_declined | The other party declined the call |
call_missed | The call timed out before being answered |
call_ended | The call session was terminated |
call_signal | WebRTC ICE candidate / offer / answer signal |
Presence
The presence system tracks whether a user isonline, away, or offline. Presence state is maintained per-device and expires automatically. The default TTL for an online heartbeat is 90 seconds (configurable via ONLINE_PRESENCE_TTL_SECONDS).
POST /api/v1/presence/heartbeat
Refreshes the caller’s online presence state. Clients should call this on a regular interval (recommended: every 30–60 seconds) while the application is in the foreground.
Auth: Any authenticated user.
Stable device or browser identifier (8–128 characters).
Must be
"web" or "mobile".Optional foreground/background hint (max 32 chars), e.g.
"active" or "background".UUID of the caller.
online, away, or offline.ISO-8601 UTC timestamp.
List of platform strings (
"web", "mobile") currently active for this user.Example Request Body
Example Response
POST /api/v1/presence/offline
Explicitly marks a specific device session as offline. Call this on intentional logout or app backgrounding.
Auth: Any authenticated user.
The device ID to go offline for.
"web" or "mobile".Will be
"offline" after a successful call.Always
false.User-set status label.
ISO-8601 UTC timestamp of the final heartbeat.
Remaining active platforms after this device goes offline.
GET /api/v1/presence/users
Batch-fetches the online presence state for a set of users by UUID. Useful for rendering online indicators in conversation lists.
Auth: Any authenticated user.
Comma-separated list of user UUIDs, e.g.
ids=uuid1,uuid2,uuid3.Map of
user_id (string) → OnlinePresenceRead.Presence state uses a 90-second TTL by default. A user with no heartbeat in the last 90 seconds transitions to
away; beyond a further configurable threshold they become offline.Notifications
In-app notifications are lightweight inbox items for each user. They are also emitted asnotification_created WebSocket events when first written.
GET /api/v1/notifications
Returns up to limit notifications for the authenticated user, ordered newest-first.
Auth: Any authenticated user.
Maximum notifications to return. Defaults to
50.Array of
NotificationRead objects.GET /api/v1/notifications/unread-count
Returns the count of unread notifications for the authenticated user.
Auth: Any authenticated user.
Number of unread notifications.
PATCH /api/v1/notifications/read-all
Marks all unread notifications for the authenticated user as read and emits a notifications_count_updated WebSocket event.
Auth: Any authenticated user.
Confirmation message.
PATCH /api/v1/notifications/{notification_id}/read
Marks a specific notification as read and emits a notification_read WebSocket event.
Auth: The notification’s owner only.
UUID of the notification.
Always
true after a successful call.ISO-8601 UTC timestamp set at read time.
Notification Preferences & Push Delivery
The notification preferences system allows users to control which notification categories they receive and via which channels (in-app, email, web push, mobile push).GET /api/v1/notifications/preferences
Returns the authenticated user’s notification preferences.
Auth: Any authenticated user.
UUID of the user.
Whether email delivery is enabled.
Whether push delivery is enabled.
PATCH /api/v1/notifications/preferences
Update the authenticated user’s notification preferences. Only provided fields are changed.
Auth: Any authenticated user.
Enable or disable email notification delivery.
Enable or disable push notification delivery.
GET /api/v1/notifications/push-public-key
Returns the server’s VAPID public key for Web Push subscription registration.
Auth: None required.
VAPID public key string, or
null if Web Push is not configured on this server.Whether VAPID credentials are configured on the server.
POST /api/v1/notifications/push-subscriptions
Registers a browser Web Push subscription for the authenticated user. If a subscription with the same endpoint already exists it is updated in place.
Auth: Any authenticated user.
Browser Push Service endpoint URL.
Client public key for payload encryption.
Auth secret for payload encryption.
Optional browser user-agent string for identification.
Confirmation —
"Push subscription registered." or "Push subscription updated."Returns
503 Service Unavailable if VAPID credentials are not configured on the server.DELETE /api/v1/notifications/push-subscriptions
Revokes (soft-deletes) a Web Push subscription. The request body uses the same schema as the registration endpoint.
Auth: Any authenticated user.
Endpoint URL of the subscription to revoke.
Client public key.
Auth secret.
Always
"Push subscription removed." on success.POST /api/v1/notifications/push/test
Sends a test Web Push notification to all active browser subscriptions for the authenticated user.
Auth: Any authenticated user.
Whether VAPID is configured.
Human-readable outcome description.
Number of active subscriptions found.
Number of push attempts made.
Number of successful deliveries.
Number of failed deliveries.
Mobile Push Device Tokens
POST /api/v1/notifications/device-tokens
Registers or refreshes the current user’s Expo push token for mobile push delivery. If the token is already registered to another user it is reassigned.
Auth: Any authenticated user.
Expo push token string in
ExponentPushToken[...] or ExpoPushToken[...] format."android" or "ios". Any other value is stored as "unknown".Human-readable device name.
Stable device identifier.
App version string.
App build number.
One of
development, preview, production. Defaults to development.UUID of the device token record.
Always
true after successful registration.DELETE /api/v1/notifications/device-tokens/current
Deactivates the current user’s active device token(s) on logout. If expo_push_token is provided in the body, only that specific token is revoked; otherwise all active tokens for the user are revoked.
Auth: Any authenticated user.
Specific token to revoke. Omit to revoke all active tokens for the user.
Always
"Device token unregistered." on success.DELETE /api/v1/notifications/device-tokens/{token_id}
Deactivates a specific device token by UUID. The token must be owned by the authenticated user.
Auth: Any authenticated user. Must own the token.
UUID of the device token record to revoke.
Always
"Device token unregistered." on success.Messaging
Conversations support direct (1-to-1), group, channel, and context-thread types (task, project, meeting, support, EOD, approval). All conversation-scoped actions require the caller to be a participant.GET /api/v1/messages/conversations
Returns conversations the authenticated user participates in, ordered by most recently updated.
Auth: Any authenticated user.
Filter by conversation type:
direct, group, channel, task_thread, etc.Title substring search.
When
true, returns only conversations with unread messages. Defaults to false.Maximum results. Defaults to
50, max 100.Pagination offset. Defaults to
0.Array of
ConversationRead objects including participant list, last message preview, and unread count.POST /api/v1/messages/conversations
Creates a new direct, group, or channel conversation. If a direct conversation between the same two users already exists, it is returned instead of creating a duplicate.
Auth: Any authenticated user.
Conversation type:
direct, group, or channel.List of user UUIDs to include. For
direct conversations, provide exactly one other user ID.Required for
group and channel types. Auto-generated if omitted.GET /api/v1/messages/conversations/{conversation_id}
Fetch details of a single conversation including participants and last message.
Auth: Must be a participant.
GET /api/v1/messages/conversations/{conversation_id}/messages
Retrieves messages in a conversation in chronological order. Automatically marks fetched messages as delivered for the caller.
Auth: Must be a participant.
Defaults to
50, max 100.ISO-8601 datetime cursor — returns messages created before this timestamp (for pagination).
POST /api/v1/messages/conversations/{conversation_id}/messages
Sends a new message to a conversation. Triggers new_message and conversation_updated WebSocket events for all participants.
Auth: Must be a participant. Channel posts require OWNER or ADMIN participant role.
Plain-text message body. Required unless
attachment_ids is provided.Optional sanitised HTML body (rich text). Server-side sanitisation is applied.
List of user UUIDs to mention. Only users with access to the conversation can be mentioned.
UUID of the message being replied to — must belong to the same conversation.
UUIDs of pre-uploaded
MessageAttachment records to attach.Example Request Body
GET /api/v1/messages/unread-count
Returns the total number of unread conversations, unread messages, and unread mentions for the authenticated user.
Meetings
Meetings are calendar-style invitations with RSVP state. Creating a meeting automatically sendsmeeting_created WebSocket events and in-app notifications to all invited participants.
GET /api/v1/meetings
Returns meetings visible to the authenticated user — those they organise or are invited to.
Auth: Any authenticated user. Admins and HR may pass scope=all to view all organisation meetings.
Pass
all to retrieve all meetings (Admin/HR only).Array of
MeetingRead objects.POST /api/v1/meetings
Creates a new meeting and sends invitations to all specified participants. The organiser is automatically added as an accepted participant.
Auth: Any authenticated user.
Meeting title.
ISO-8601 UTC start datetime.
ISO-8601 UTC end datetime.
List of participant user UUIDs to invite. Inactive users are rejected with
400.Optional meeting agenda or description.
External video call URL.
Physical meeting location.
Example Request Body
Example Response
GET /api/v1/meetings/upcoming
Returns future scheduled meetings for the authenticated user, ordered by start time ascending.
Auth: Any authenticated user.
Array of
MeetingRead objects with status = "scheduled" and start_at >= now.GET /api/v1/meetings/today
Returns all meetings scheduled for today in the Asia/Karachi timezone.
Auth: Any authenticated user. Pass scope=all for Admin/HR to see all org meetings.
Pass
all to retrieve all org meetings today (Admin/HR only).GET /api/v1/meetings/{meeting_id}
Returns details of a single meeting. The caller must be the organiser, a participant, or an Admin/HR user.
Auth: Any authenticated user with access to the meeting.
UUID of the meeting.
UUID of the meeting.
ISO-8601 UTC datetime.
ISO-8601 UTC datetime.
scheduled or cancelled.POST /api/v1/meetings/{meeting_id}/cancel
Cancels a meeting, setting its status to "cancelled". Sends meeting_deleted WebSocket events and in-app notifications to all participants.
Auth: Meeting organiser or ADMIN role required.
UUID of the meeting to cancel.
Always
"cancelled" after a successful call.POST /api/v1/meetings/{meeting_id}/respond
RSVP to a meeting invitation.
Auth: Must be a participant.
UUID of the meeting.
One of:
accepted, declined, tentative.UUID of the updated meeting.
Meeting status (unchanged by RSVP).
Responding to a cancelled meeting returns
400 Bad Request. A meeting_rsvp_updated WebSocket event is emitted to the organiser on every RSVP update.Error Reference
| HTTP Status | Error Code | Reason |
|---|---|---|
401 | AUTH_ERROR | Missing or invalid JWT |
403 | PERMISSION_ERROR | Not a participant, not the organiser, or insufficient role |
404 | NOT_FOUND | Conversation, message, notification, or meeting not found |
503 | SERVICE_UNAVAILABLE | Web Push not configured (VAPID missing) |
1008 (WS) | — | WS ticket missing, invalid, expired, or user inactive |
1011 (WS) | — | Internal server error during WS setup |
