Chat
The Chat API provides real-time messaging between hosts and their clients. Messages are delivered via WebSocket for instant delivery and persisted via REST endpoints. All chat endpoints require authentication.
GET /v1/chat/conversations
Section titled “GET /v1/chat/conversations”List the authenticated user’s conversations, ordered by most recent activity.
Authentication: Bearer token required.
Request
Section titled “Request”GET /v1/chat/conversations?page=1&per_page=20Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...| Query Parameter | Type | Description |
|---|---|---|
page | integer | Page number (default: 1) |
per_page | integer | Results per page (default: 20) |
Response
Section titled “Response”{ "success": true, "data": [ { "id": "01JN2XA0B1C2D3E4F5G6H7I8J9", "participant": { "id": "01JN2X4K8M3F7QPZRVWT6YBHCE", "display_name": "Jane Smith", "avatar_url": "https://cdn.vidivo.app/avatars/01JN2X4K.jpg" }, "last_message": { "body": "See you tomorrow at 2pm!", "type": "text", "sent_at": "2026-03-15T13:45:00Z" }, "unread_count": 2, "updated_at": "2026-03-15T13:45:00Z" } ], "pagination": { "page": 1, "per_page": 20, "total": 5, "total_pages": 1 }}POST /v1/chat/conversations
Section titled “POST /v1/chat/conversations”Get or create a direct conversation with another user. If a conversation already exists between the two users, it is returned.
Authentication: Bearer token required.
Request
Section titled “Request”POST /v1/chat/conversationsAuthorization: Bearer eyJhbGciOiJSUzI1NiJ9...Content-Type: application/json{ "user_id": "01JN2X4K8M3F7QPZRVWT6YBHCE"}| Field | Type | Required | Description |
|---|---|---|---|
user_id | string (UUID) | Yes | The other participant’s user ID |
Response
Section titled “Response”HTTP/1.1 201 Created{ "id": "01JN2XA0B1C2D3E4F5G6H7I8J9", "participant": { "id": "01JN2X4K8M3F7QPZRVWT6YBHCE", "display_name": "Jane Smith" }, "unread_count": 0, "created_at": "2026-03-15T13:00:00Z"}GET /v1/chat/conversations/:id/messages
Section titled “GET /v1/chat/conversations/:id/messages”Retrieve messages in a conversation, newest first. The caller must be a participant.
Authentication: Bearer token required.
Request
Section titled “Request”GET /v1/chat/conversations/01JN2XA0B1C2D3E4F5G6H7I8J9/messages?page=1&per_page=50Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...Response
Section titled “Response”{ "success": true, "data": [ { "id": "01JN2XB1C2D3E4F5G6H7I8J9K0", "conversation_id": "01JN2XA0B1C2D3E4F5G6H7I8J9", "sender_id": "01JN2X4K8M3F7QPZRVWT6YBHCE", "body": "See you tomorrow at 2pm!", "type": "text", "file_url": null, "file_name": null, "file_size": null, "file_type": null, "created_at": "2026-03-15T13:45:00Z" } ], "pagination": { "page": 1, "per_page": 50, "total": 12, "total_pages": 1 }}Errors
Section titled “Errors”| Code | Status | Description |
|---|---|---|
forbidden | 403 | Caller is not a participant in this conversation |
not_found | 404 | Conversation does not exist |
POST /v1/chat/conversations/:id/messages
Section titled “POST /v1/chat/conversations/:id/messages”Send a message in a conversation. Supports text messages and file attachments.
Authentication: Bearer token required.
Request (text message)
Section titled “Request (text message)”POST /v1/chat/conversations/01JN2XA0B1C2D3E4F5G6H7I8J9/messagesAuthorization: Bearer eyJhbGciOiJSUzI1NiJ9...Content-Type: application/json{ "body": "Hello! Ready for our session?", "type": "text"}Request (file message)
Section titled “Request (file message)”{ "body": "Here is the document I mentioned", "type": "file", "file_url": "https://cdn.vidivo.app/files/doc.pdf", "file_name": "session-notes.pdf", "file_size": 245760, "file_type": "application/pdf"}| Field | Type | Required | Description |
|---|---|---|---|
body | string | Yes | Message text content |
type | string | No | text (default) or file |
file_url | string | No | URL to the uploaded file (required for file type) |
file_name | string | No | Original file name |
file_size | integer | No | File size in bytes |
file_type | string | No | MIME type of the file |
Response
Section titled “Response”HTTP/1.1 201 CreatedReturns the created message object.
Errors
Section titled “Errors”| Code | Status | Description |
|---|---|---|
forbidden | 403 | User cannot send messages (no active call) |
not_found | 404 | Conversation does not exist |
PUT /v1/chat/conversations/:id/read
Section titled “PUT /v1/chat/conversations/:id/read”Mark all messages in a conversation as read for the authenticated user.
Authentication: Bearer token required.
PUT /v1/chat/conversations/01JN2XA0B1C2D3E4F5G6H7I8J9/readAuthorization: Bearer eyJhbGciOiJSUzI1NiJ9...Returns 204 No Content on success.
POST /v1/chat/broadcast
Section titled “POST /v1/chat/broadcast”Send a message from a host to all of their followers. Creates individual conversations as needed.
Authentication: Bearer token required (role: host or admin).
Request
Section titled “Request”POST /v1/chat/broadcastAuthorization: Bearer eyJhbGciOiJSUzI1NiJ9...Content-Type: application/json{ "body": "I'm available for coaching sessions this afternoon! Book a slot now."}| Field | Type | Required | Description |
|---|---|---|---|
body | string | Yes | Broadcast message text |
Response
Section titled “Response”HTTP/1.1 201 CreatedWebSocket Real-Time Delivery
Section titled “WebSocket Real-Time Delivery”Connection
Section titled “Connection”wss://api.vidivo.app/v1/chat/ws?token=<access_token>Pass a valid JWT access token as the token query parameter.
Client-to-Server Messages
Section titled “Client-to-Server Messages”{ "type": "message", "conversation_id": "01JN2XA0B1C2D3E4F5G6H7I8J9", "body": "Hello!"}{ "type": "typing", "conversation_id": "01JN2XA0B1C2D3E4F5G6H7I8J9"}{ "type": "read", "conversation_id": "01JN2XA0B1C2D3E4F5G6H7I8J9"}Server-to-Client Messages
Section titled “Server-to-Client Messages”{ "type": "new_message", "message": { "id": "01JN2XB1C2D3E4F5G6H7I8J9K0", "conversation_id": "01JN2XA0B1C2D3E4F5G6H7I8J9", "sender_id": "01JN2X4K8M3F7QPZRVWT6YBHCE", "body": "Hello!", "type": "text", "created_at": "2026-03-15T13:45:00Z" }}{ "type": "typing", "conversation_id": "01JN2XA0B1C2D3E4F5G6H7I8J9", "user_id": "01JN2X4K8M3F7QPZRVWT6YBHCE"}{ "type": "read_receipt", "conversation_id": "01JN2XA0B1C2D3E4F5G6H7I8J9", "user_id": "01JN2X4K8M3F7QPZRVWT6YBHCE"}| Type | Direction | Description |
|---|---|---|
message | Client to Server | Send a message |
typing | Both | Typing indicator |
read | Client to Server | Mark conversation as read |
new_message | Server to Client | New message delivered |
read_receipt | Server to Client | Other user read the conversation |
Code Examples
Section titled “Code Examples”# List conversationscurl "https://api.vidivo.app/v1/chat/conversations" \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9..."
# Send a messagecurl -X POST "https://api.vidivo.app/v1/chat/conversations/01JN2XA0/messages" \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9..." \ -H "Content-Type: application/json" \ -d '{"body":"Hello!","type":"text"}'
# Broadcast to followerscurl -X POST "https://api.vidivo.app/v1/chat/broadcast" \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9..." \ -H "Content-Type: application/json" \ -d '{"body":"Available for sessions this afternoon!"}'const API = 'https://api.vidivo.app/v1';
// Connect WebSocket for real-time messagesconst chatWs = new WebSocket( `wss://api.vidivo.app/v1/chat/ws?token=${accessToken}`);
chatWs.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type === 'new_message') { console.log(`New message: ${msg.message.body}`); }};
// Send a message via WebSocketchatWs.send(JSON.stringify({ type: 'message', conversation_id: '01JN2XA0B1C2D3E4F5G6H7I8J9', body: 'Hello!',}));
// Send typing indicatorchatWs.send(JSON.stringify({ type: 'typing', conversation_id: '01JN2XA0B1C2D3E4F5G6H7I8J9',}));