Conversations
Staff messaging — conversations, messages, and real-time events.
Conversations are participant-scoped: you only ever see conversations you are part of, regardless of role. All endpoints require a signed-in member with an active clinic.
| Method | Path | Purpose |
|---|---|---|
GET | /api/conversations | Your conversations, with last message and unread count |
GET | /api/conversations/members | Clinic members you can start a conversation with |
POST | /api/conversations | Create a conversation (or reuse an existing DM) |
GET | /api/conversations/{id}/messages | Message history |
POST | /api/conversations/{id}/messages | Send a message |
POST | /api/conversations/{id}/read | Mark the conversation read |
POST | /api/conversations/attachments | Upload a file, get its id back |
GET | /api/conversations/attachments/{id} | Download a file (clinic-scoped) |
Endpoints
Create a conversation
| Field | Type | Notes |
|---|---|---|
participantIds | string[] | Required. User ids to include (at least one) |
name | string | null | Optional group name (max 120 chars); DMs are unnamed |
curl -b cookies.txt -X POST http://localhost:4000/api/conversations \
-H "Content-Type: application/json" \
-d '{ "participantIds": ["usr_def456"] }'Creating a DM with someone you already have a DM with returns the existing conversation instead of a duplicate.
Send a message
| Field | Type | Notes |
|---|---|---|
body | string | Up to 5000 characters. Optional if attachments are present |
attachments | array | Optional. Up to 10 file refs / appointment snapshots |
curl -b cookies.txt -X POST http://localhost:4000/api/conversations/CONV_ID/messages \
-H "Content-Type: application/json" \
-d '{ "body": "Labs for 1042 are back — HbA1c improving." }'Each attachment is one of:
- File —
{ "kind": "file", "attachmentId", "fileName", "mimeType", "size" }(theattachmentIdcomes from the upload endpoint below). - Appointment —
{ "kind": "appointment", "appointment": { fileNumber, name, date, time, type, provider, status } }. The appointment is stored as a snapshot so the card renders without a refetch and survives the appointment later changing.
Attachments (files)
Files are uploaded separately, then referenced by id when sending. Bytes are stored clinic-scoped (base64), capped at 10MB.
# 1) Upload — returns { attachmentId, fileName, mimeType, size }
curl -b cookies.txt -X POST http://localhost:4000/api/conversations/attachments \
-H "Content-Type: application/json" \
-d '{ "fileName": "results.pdf", "mimeType": "application/pdf", "size": 12345,
"data": "<base64-without-data-prefix>" }'
# 2) Send a message that references it (see "attachments" above)
# 3) Download — authenticated, clinic-scoped
curl -b cookies.txt http://localhost:4000/api/conversations/attachments/ATTACHMENT_ID -o results.pdfReal-time delivery
Messages are also pushed live over Socket.io (same origin, authenticated by the
session cookie). Connected clients receive new-message events for their conversations
and notification:new events for record changes — the REST endpoints above are the
fallback and history source. The web app keeps both in sync automatically.