Skip to content
SSalesShiftDocs
API reference

Messaging and calls

Rooms, messages, attachments, polls, scheduled messages, guest invitations, and call recording and intelligence.

57 endpoints· 10 called live· 5 not exercised here· verified against http://127.0.0.1:8741

57 endpoints

GET/api/v1/messaging/attachments/{attachment_id}/fileVerified in sessionDownload a message attachment, if the caller is a member of its room.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
binary

Path parameters

NameTypeRequiredNotes
attachment_idstringrequiredAttachment ID

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/attachments/{attachment_id}/file' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

FileResponse of the stored attachment.

Errors

Statusdetail
404Attachment not found
404Attachment file not found
500Internal server error
#get-api-v1-messaging-attachments-attachment-id-filemessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:2962The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
GET/api/v1/messaging/bookmarksCalled liveThe caller's saved messages.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Query parameters

NameTypeRequiredNotes
limitintegeroptionalDefault 100. max 300.

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/bookmarks' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "bookmarks": [
    "<empty list>"
  ]
}
Observed on 2026-08-06 — keys are real, values are the types that came back.

Errors

Statusdetail
500Failed to list saved messages
#get-api-v1-messaging-bookmarksmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:3818Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
GET/api/v1/messaging/calls/{call_id}/intelligenceKnown unprovenOne read for the whole post-call record.

One read for the whole post-call record. `transcript` is null when nothing was ever recorded — which the UI must render as "not recorded", not as a failure. When a recording exists but no key does, `transcript.status` is 'unavailable' and `transcript.error` is the sentence explaining exactly which setting is missing.

Known unproven. Call transcription and summary have never run with real data. No org has an AI provider key, so every recording ends at status='unavailable'.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
call_idstringrequiredCall ID

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/calls/{call_id}/intelligence' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "call_id": "…",
  "duration_seconds": "…",
  "mode": "…",
  "recorded": "…",
  "recording": "…",
  "room_id": "…",
  "room_name": "…",
  "transcript": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
503Database is unavailable
#get-api-v1-messaging-calls-call-id-intelligencecall_intelligence · vxcloud_fastapiclient/app/services/messaging/call_intelligence.py:1075Call transcription and summary have never run with real data. No org has an AI provider key, so every recording ends at status='unavailable'.
POST/api/v1/messaging/calls/{call_id}/recording/chunksKnown unprovenAppend one MediaRecorder blob to the in-progress upload.

Append one MediaRecorder blob to the in-progress upload. Chunks arrive DURING the call, not after: a dropped tab at minute 58 then costs 58 seconds of audio instead of 58 minutes. The file is opened in append mode, so an index that already landed must be a no-op rather than a second append — appending it twice puts duplicate frames in the middle of the container and every decoder reads garbage from there on. Replaying it as a no-op (not a 4xx) is deliberate: the case that actually happens is the server receiving a chunk and the RESPONSE being lost, and answering the retry with an error would make the recorder discard a recording whose bytes are already safely on disk.

Known unproven. Call transcription and summary have never run with real data. No org has an AI provider key, so every recording ends at status='unavailable'.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
call_idstringrequiredCall ID

Request body (required) — Body_upload_recording_chunk_api_v1_messaging_calls__call_id__recording_chunks_post

FieldTypeRequiredNotes
upload_idstringrequiredClient-minted uuid4 hex for this upload
chunk_indexintegerrequired
chunkstringrequired

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/calls/{call_id}/recording/chunks' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "upload_id": "<string>", "chunk_index": 0, "chunk": "<string>" }'

Response · 200

Top-level keys
{
  "bytes_received": "…",
  "chunk_index": "…",
  "duplicate": "…",
  "upload_id": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
400Empty chunk
413Chunk is too large
413Recording exceeds the maximum size
#post-api-v1-messaging-calls-call-id-recording-chunkscall_intelligence · vxcloud_fastapiclient/app/services/messaging/call_intelligence.py:873Call transcription and summary have never run with real data. No org has an AI provider key, so every recording ends at status='unavailable'.
POST/api/v1/messaging/calls/{call_id}/recording/finalizeKnown unprovenSeal the upload into a recording row — IF it was ever announced.

Seal the upload into a recording row — IF it was ever announced. This is the consent gate, and it is a hard one: `announcement` comes from messaging_call.metadata->'recordings', which only calls.py::announce_recording writes, and that function is the same code path that broadcast the indicator to every peer, rang every participant's lobby socket, and posted the "started recording" system message. A client that recorded silently has no announcement to point at and gets a 409. There is no override.

Known unproven. Call transcription and summary have never run with real data. No org has an AI provider key, so every recording ends at status='unavailable'.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
call_idstringrequiredCall ID

Request body (required) — FinalizeRequest

FieldTypeRequiredNotes
upload_idstringrequired
mimestringoptionalDefault "audio/webm".
duration_secondsintegeroptionalDefault 0.
consent_acksobject[]?optional

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/calls/{call_id}/recording/finalize' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "upload_id": "<string>", "mime": "audio/webm", "duration_seconds": 0, "consent_acks": [ "<object>" ] }'

Response · 200

Top-level keys
{
  "bytes": "…",
  "call_id": "…",
  "consent_shown_to": "…",
  "duration_seconds": "…",
  "mime": "…",
  "recording_id": "…",
  "room_id": "…",
  "transcript_status": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
404No uploaded chunks for that upload id
409This recording was never announced to the call's participants, so it cannot be stored. Recording must start with call-recording-start, which shows every participant a recording indicator.
403Only the participant who announced this recording can upload it.
415Only audio or video recordings are accepted
503Database is unavailable
#post-api-v1-messaging-calls-call-id-recording-finalizecall_intelligence · vxcloud_fastapiclient/app/services/messaging/call_intelligence.py:952Call transcription and summary have never run with real data. No org has an AI provider key, so every recording ends at status='unavailable'.
GET/api/v1/messaging/calls/{call_id}/recordings/{recording_id}/fileKnown unprovenMembership-checked stream.

Membership-checked stream. Never a static mount — a recording is the most sensitive artifact this product holds, and an unauthenticated URL for it is a breach waiting for a search engine.

Known unproven. Call transcription and summary have never run with real data. No org has an AI provider key, so every recording ends at status='unavailable'.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
binary

Path parameters

NameTypeRequiredNotes
call_idstringrequired
recording_idstringrequired

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/calls/{call_id}/recordings/{recording_id}/file' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

FileResponse of the stored recording (media type from the row, default audio/webm).

Errors

Statusdetail
503Database is unavailable
404Recording not found
404Recording file is missing from storage
#get-api-v1-messaging-calls-call-id-recordings-recording-id-filecall_intelligence · vxcloud_fastapiclient/app/services/messaging/call_intelligence.py:1170Call transcription and summary have never run with real data. No org has an AI provider key, so every recording ends at status='unavailable'.
POST/api/v1/messaging/calls/{call_id}/transcribeKnown unprovenFor the common case: the recording landed before anyone configured a key.

For the common case: the recording landed before anyone configured a key. Idempotent — run_intelligence upserts on recording_id, so this replaces the 'unavailable' row rather than stacking a second transcript beside it.

Known unproven. Call transcription and summary have never run with real data. No org has an AI provider key, so every recording ends at status='unavailable'.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
call_idstringrequired

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/calls/{call_id}/transcribe' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "call_id": "…",
  "recording_id": "…",
  "status": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
503Database is unavailable
404This call has no stored recording
#post-api-v1-messaging-calls-call-id-transcribecall_intelligence · vxcloud_fastapiclient/app/services/messaging/call_intelligence.py:1206Call transcription and summary have never run with real data. No org has an AI provider key, so every recording ends at status='unavailable'.
GET/api/v1/messaging/calls/activeCalled liveDrives the rooms-rail 'live' pills on first paint, before the lobby socket is up.

Drives the rooms-rail 'live' pills on first paint, before the lobby socket is up.

Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/calls/active' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "calls": [
    "<empty list>"
  ],
  "count": "int"
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-messaging-calls-activemessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:3123Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
GET/api/v1/messaging/chat-invitations/{token}url-secret-onlyVerified in sessionPublic lookup of a guest invitation by token.
Auth
no dependency
Scope
url-secret-only
Success
200 · application/json
Envelope
bare-object

The guest invitation token is the credential.

Path parameters

NameTypeRequiredNotes
tokenstringrequired

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/chat-invitations/{token}'

Response · 200

Top-level keys
{
  "display_name": "…",
  "email": "…",
  "expired": "…",
  "expires_at": "…",
  "invited_by": "…",
  "message": "…",
  "organization_name": "…",
  "room_name": "…",
  "status": "…",
  "token": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
503Database unavailable
404Invitation not found
#get-api-v1-messaging-chat-invitations-tokenguest_invites · vxcloud_fastapiclient/app/services/messaging/guest_invites.py:642The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
POST/api/v1/messaging/chat-invitations/{token}/accepturl-secret-onlyVerified in sessionPublic accept of a guest invitation; provisions the guest user and room membership.
Auth
no dependency
Scope
url-secret-only
Success
200 · application/json
Envelope
bare-object

The guest invitation token is the credential.

Path parameters

NameTypeRequiredNotes
tokenstringrequired

Request body (optional) — GuestAcceptRequest

FieldTypeRequiredNotes
display_namestring?optional
passwordstring?optional

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/chat-invitations/{token}/accept' \
  -H 'Content-Type: application/json' \
  -d '{ "display_name": "<string>", "password": "<string>" }'

Response · 200

Top-level keys
{
  "access": "…",
  "display_name": "…",
  "email": "…",
  "refresh": "…",
  "room_id": "…",
  "room_name": "…",
  "user_id": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
503Database unavailable
404Invitation not found
409This invitation was revoked
409This invitation was declined
410This invitation has expired
409This email now belongs to a SalesShift account. Sign in and open the room from your inbox instead.
#post-api-v1-messaging-chat-invitations-token-acceptguest_invites · vxcloud_fastapiclient/app/services/messaging/guest_invites.py:691The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
POST/api/v1/messaging/chat-invitations/{token}/declineurl-secret-onlyVerified in sessionPublic decline of a guest invitation.
Auth
no dependency
Scope
url-secret-only
Success
200 · application/json
Envelope
bare-object

The guest invitation token is the credential.

Path parameters

NameTypeRequiredNotes
tokenstringrequired

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/chat-invitations/{token}/decline'

Response · 200

Top-level keys
{
  "status": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
404Invitation not found
409This invitation was already accepted
#post-api-v1-messaging-chat-invitations-token-declineguest_invites · vxcloud_fastapiclient/app/services/messaging/guest_invites.py:787The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
DELETE/api/v1/messaging/guest-invitations/{invitation_id}Verified in sessionRevoke a guest's access.
Auth
get_current_user
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
invitation_idstringrequired

Request

curl
curl -X DELETE 'https://api.vxcloud.io/api/v1/messaging/guest-invitations/{invitation_id}' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "id": "…",
  "status": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
403Access denied
404Invitation not found
#delete-api-v1-messaging-guest-invitations-invitation-idguest_invites · vxcloud_fastapiclient/app/services/messaging/guest_invites.py:587The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
GET/api/v1/messaging/healthopenCalled liveLive health for the messaging plane.

Live health for the messaging plane. Reports the realtime path (Postgres + Redis Pub/Sub + WebSocket sessions), the durability path (transactional outbox processor + queue depth), the async fanout (Celery worker reachability), and the analytics fan-out (Kafka producer state). Anything `degraded` is non-fatal — the realtime path keeps working — but should be visible.

Auth
no dependency
Scope
open
Success
200 · application/json
Envelope
bare-object

Anonymous health check. No credential of any kind.

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/health'

Response · 200

Observed shape
{
  "status": "str",
  "services": {
    "database": "str",
    "redis": "str",
    "celery": {
      "reachable": "bool",
      "workers": "int"
    },
    "kafka": {
      "enabled": "bool",
      "available": "bool",
      "topic": "null"
    },
    "outbox": {
      "processor_running": "bool",
      "pending": "int",
      "failed": "int"
    }
  },
  "active_connections": "int",
  "timestamp": "str"
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-messaging-healthmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:3194Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
POST/api/v1/messaging/hooks/{token}url-secret-onlyVerified in sessionPost a message into a room from an incoming webhook; the token is the only credential.
Auth
no dependency
Scope
url-secret-only
Success
200 · application/json
Envelope
bare-object

The token IS the credential — the route's own summary says so. Tokens shorter than 32 characters are rejected.

Path parameters

NameTypeRequiredNotes
tokenstringrequired

Request body (required) — WebhookPost

FieldTypeRequiredNotes
textstringrequired
usernamestring?optional

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/hooks/{token}' \
  -H 'Content-Type: application/json' \
  -d '{ "text": "<string>", "username": "<string>" }'

Response · 200

Top-level keys
{
  "message_id": "…",
  "ok": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
422text required
404Unknown webhook
500Failed to post webhook message
500Webhook lookup failed
#post-api-v1-messaging-hooks-tokenmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:4363The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
GET/api/v1/messaging/invitationsCalled liveThe caller's pending room invitations.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/invitations' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "invitations": [
    "<empty list>"
  ]
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-messaging-invitationsmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:4260Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
POST/api/v1/messaging/invitations/{invitation_id}/respondVerified in sessionAccept or decline a room invitation.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
invitation_idstringrequired

Query parameters

NameTypeRequiredNotes
acceptbooleanrequired

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/invitations/{invitation_id}/respond?accept=<boolean>' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "id": "…",
  "room_id": "…",
  "status": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
404Invitation not found
500Failed to respond to invitation
409computed at runtime: 'Invitation already %s' % inv['status']
#post-api-v1-messaging-invitations-invitation-id-respondmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:4284The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
GET/api/v1/messaging/mentionsCalled liveThe caller's mention inbox.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Query parameters

NameTypeRequiredNotes
unread_onlybooleanoptionalDefault false.
limitintegeroptionalDefault 50. max 200.

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/mentions' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "mentions": [
    {
      "id": "str",
      "is_read": "bool",
      "message_id": "str",
      "room_id": "str",
      "room_name": "str",
      "sender_id": "int",
      "content": "str",
      "created_at": "str"
    },
    "...x2"
  ]
}
Observed on 2026-08-06 — keys are real, values are the types that came back.

Errors

Statusdetail
400Invalid user
500Failed to list mentions
#get-api-v1-messaging-mentionsmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:3710Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
POST/api/v1/messaging/mentions/readVerified in sessionMark a set of mentions read.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Request body (required) — MentionsReadRequest

FieldTypeRequiredNotes
message_idsstring[]required

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/mentions/read' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "message_ids": [ "<string>" ] }'

Response · 200

Top-level keys
{
  "updated": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
500Failed to mark mentions read
#post-api-v1-messaging-mentions-readmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:3747The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
POST/api/v1/messaging/messages/{message_id}/ackVerified in sessionAcknowledge a priority message.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
message_idstringrequired

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/messages/{message_id}/ack' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

The acknowledgement payload object.

Errors

Statusdetail
404Message not found
500Failed to acknowledge
#post-api-v1-messaging-messages-message-id-ackmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:3990The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
GET/api/v1/messaging/messages/{message_id}/acksVerified in sessionWho has acknowledged a message.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
message_idstringrequired

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/messages/{message_id}/acks' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "acks": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
404Message not found
#get-api-v1-messaging-messages-message-id-acksmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:4026The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
POST/api/v1/messaging/messages/{message_id}/bookmarkVerified in sessionSave a message to the caller's bookmarks.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
message_idstringrequired

Request body (required) — BookmarkRequest

FieldTypeRequiredNotes
notestring?optional
tagsstring[]?optional

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/messages/{message_id}/bookmark' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "note": "<string>", "tags": [ "<string>" ] }'

Response · 200

Top-level keys
{
  "message_id": "…",
  "saved": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
404Message not found
500Failed to save message
#post-api-v1-messaging-messages-message-id-bookmarkmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:3771The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
DELETE/api/v1/messaging/messages/{message_id}/bookmarkVerified in sessionRemove a message from the caller's bookmarks.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
message_idstringrequired

Request

curl
curl -X DELETE 'https://api.vxcloud.io/api/v1/messaging/messages/{message_id}/bookmark' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "message_id": "…",
  "saved": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
500Failed to unsave message
#delete-api-v1-messaging-messages-message-id-bookmarkmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:3801The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
POST/api/v1/messaging/polls/{poll_id}/voteVerified in sessionVote on a poll.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
poll_idstringrequired

Request body (required) — PollVoteRequest

FieldTypeRequiredNotes
option_idsstring[]required

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/polls/{poll_id}/vote' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "option_ids": [ "<string>" ] }'

Response · 200

The poll snapshot object after the vote.

Errors

Statusdetail
404Poll not found
500Failed to vote
409Poll is closed
422No valid options selected
#post-api-v1-messaging-polls-poll-id-votemessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:3919The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
GET/api/v1/messaging/roomsCalled liveRooms the caller belongs to; guests see only their own rooms.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/rooms' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
[
  {
    "id": "str",
    "name": "str",
    "description": "str",
    "room_type": "str",
    "is_active": "bool",
    "is_public": "bool",
    "is_global": "bool",
    "created_at": "str",
    "updated_at": "str",
    "last_activity": "str",
    "settings": "null",
    "max_participants": "int",
    "created_by_id": "int",
    "participant_count": "int",
    "participant_ids": [
      "str",
      "...x2"
    ],
    "other_user_id": "str",
    "my_settings": {
      "is_muted": "bool",
      "is_favorite": "bool",
      "added_to_list": "str"
    },
    "other_user": {
      "id": "str",
      "name": "str",
      "username": "str",
      "email": "str",
      "role": "str",
      "avatar": "null",
      "avatar_color": "str",
      "organization_id": "str",
      "status": "str",
      "last_seen": "str"
    }
  },
  "...x19"
]
Observed on 2026-08-06 — keys are real, values are the types that came back.

Errors

Statusdetail
500Internal server error
#get-api-v1-messaging-roomsmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:2549Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
POST/api/v1/messaging/roomsVerified in sessionCreate a chat room; cross-organization rooms are superuser-only and guests may not create rooms.
Auth
get_current_user
Scope
user
Success
200 · application/json
Envelope
bare-object

Request body (required) — CreateRoomRequest

FieldTypeRequiredNotes
namestringrequired
typestringoptionalDefault "private".
descriptionstring?optional
participant_user_idsstring[]?optional
is_globalbooleanoptionalDefault false.

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/rooms' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "name": "<string>", "type": "private", "description": "<string>", "participant_user_ids": [ "<string>" ], "is_global": false }'

Response · 200

The created room object.

Errors

Statusdetail
500Failed to create room
500Internal server error
#post-api-v1-messaging-roomsmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:2390The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
GET/api/v1/messaging/rooms/{room_id}Verified in sessionOne room, if the caller is a member.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequiredRoom ID

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

The room object returned by _require_member.

Errors

Statusdetail
500Internal server error
#get-api-v1-messaging-rooms-room-idmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:2565The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
POST/api/v1/messaging/rooms/{room_id}/aiPartial`mode='ask'`: posts the question, then VxAI's answer, into the room.

`mode='ask'`: posts the question, then VxAI's answer, into the room. `mode='catchup'`: posts an AI summary of the recent conversation. Runs entirely against the LOCAL OpenClaw gateway — no external APIs.

Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequired

Request body (required) — RoomAiRequest

FieldTypeRequiredNotes
promptstring?optional
modestringoptionalDefault "ask".

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/ai' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "prompt": "<string>", "mode": "ask" }'

Response · 200

Top-level keys
{
  "mode": "…",
  "queued": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
422prompt required for mode='ask'
#post-api-v1-messaging-rooms-room-id-aimessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:4603The route is implemented and reachable, but it calls the organization's AI integration and the test org has no integration_type='ai' row, so no provider-backed result was produced here.
POST/api/v1/messaging/rooms/{room_id}/attachmentsVerified in sessionUpload an attachment and create a chat message that references it.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequiredRoom ID

Request body (required) — Body_upload_room_attachment_api_v1_messaging_rooms__room_id__attachments_post

FieldTypeRequiredNotes
filestringrequired
captionstringoptionalDefault "".

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/attachments' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "file": "<string>", "caption": "" }'

Response · 200

Top-level keys
{
  "attachments": "…",
  "content": "…",
  "created_at": "…",
  "id": "…",
  "is_deleted": "…",
  "is_edited": "…",
  "is_pinned": "…",
  "message_type": "…",
  "room_id": "…",
  "sender_id": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
400Attachment is empty
413Attachment is too large
500Failed to send attachment
500Internal server error
#post-api-v1-messaging-rooms-room-id-attachmentsmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:2888The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
GET/api/v1/messaging/rooms/{room_id}/callVerified in sessionThe live call in a room, if there is one.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequiredRoom ID

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/call' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "active": "…",
  "call": "…"
}
Top-level keys read from the handler's return statements.
#get-api-v1-messaging-rooms-room-id-callmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:3131The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
GET/api/v1/messaging/rooms/{room_id}/callsVerified in sessionPast calls in a room.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequiredRoom ID

Query parameters

NameTypeRequiredNotes
limitintegeroptionalDefault 50. min 1. max 200.

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/calls' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "calls": "…",
  "count": "…"
}
Top-level keys read from the handler's return statements.
#get-api-v1-messaging-rooms-room-id-callsmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:3141The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
GET/api/v1/messaging/rooms/{room_id}/guest-invitationsVerified in sessionGuest invitations issued for a room.
Auth
get_current_user
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequired

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/guest-invitations' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "invitations": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
403Access denied
#get-api-v1-messaging-rooms-room-id-guest-invitationsguest_invites · vxcloud_fastapiclient/app/services/messaging/guest_invites.py:567The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
POST/api/v1/messaging/rooms/{room_id}/guest-invitationsVerified in sessionInvite an external CRM contact into one room as a guest; guests may not invite guests.
Auth
get_current_user
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequiredRoom the guest will be confined to

Request body (required) — GuestInviteRequest

FieldTypeRequiredNotes
contact_idstring?optional
emailstring?optional
namestring?optional
messagestring?optional
sender_emailstring?optional

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/guest-invitations' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "contact_id": "<string>", "email": "<string>", "name": "<string>", "message": "<string>", "sender_email": "<string>" }'

Response · 200

Top-level keys
{
  "detail": "…",
  "display_name": "…",
  "email": "…",
  "email_error": "…",
  "email_sent": "…",
  "expires_at": "…",
  "guest_user_id": "…",
  "id": "…",
  "invite_endpoint": "…",
  "invite_url": "…",
  "mode": "…",
  "room_id": "…",
  "status": "…",
  "user_id": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
403Guests cannot invite others
400Only a user with an organization can invite a guest
400A guest cannot be invited into a global room — invite them into a private room instead
503Database unavailable
400A valid email address is required
404Contact not found
400That contact has no email address, so there is nowhere to send the invitation
400Invalid contact id
#post-api-v1-messaging-rooms-room-id-guest-invitationsguest_invites · vxcloud_fastapiclient/app/services/messaging/guest_invites.py:416The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
POST/api/v1/messaging/rooms/{room_id}/invitationsVerified in sessionInvite a platform user to a room.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequired

Request body (required) — InviteRequest

FieldTypeRequiredNotes
invited_user_idintegerrequired
rolestringoptionalDefault "member".
messagestring?optional

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/invitations' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "invited_user_id": 0, "role": "member", "message": "<string>" }'

Response · 200

Top-level keys
{
  "id": "…",
  "invited_user_id": "…",
  "room_id": "…",
  "status": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
409User is already a member
500Failed to create invitation
404User not found
409An invitation is already pending
#post-api-v1-messaging-rooms-room-id-invitationsmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:4218The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
POST/api/v1/messaging/rooms/{room_id}/joinVerified in sessionJoin a room.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequiredRoom ID to join

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/join' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "message": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
400Failed to join room
404Room not found
500Internal server error
403Room is not joinable
#post-api-v1-messaging-rooms-room-id-joinmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:2579The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
POST/api/v1/messaging/rooms/{room_id}/leaveVerified in sessionLeave a room.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequiredRoom ID to leave

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/leave' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "message": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
400Failed to leave room
404Room not found
500Internal server error
#post-api-v1-messaging-rooms-room-id-leavemessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:2641The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
GET/api/v1/messaging/rooms/{room_id}/messagesVerified in sessionMessage history for a room, paged backwards from a timestamp.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequiredRoom ID

Query parameters

NameTypeRequiredNotes
limitintegeroptionalNumber of messages to retrieve Default 50.
beforestring?optionalGet messages before this timestamp

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/messages' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

A JSON array of message objects (empty array when there are none).

Errors

Statusdetail
500Internal server error
#get-api-v1-messaging-rooms-room-id-messagesmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:2660The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
POST/api/v1/messaging/rooms/{room_id}/messagesVerified in sessionSend a message via REST API (fallback when WebSocket is not available)
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequiredRoom ID

Request body (required) — SendMessageRequest

FieldTypeRequiredNotes
contentstringrequired
message_typeMessageTypeoptionalDefault "text".
reply_tostring?optional
thread_rootstring?optional
attachmentsobject[]?optional
metadataobject?optional

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/messages' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "content": "<string>", "message_type": "text", "reply_to": "<string>", "thread_root": "<string>", "attachments": [ "<object>" ], "metadata": {} }'

Response · 200

Top-level keys
{
  "attachments": "…",
  "content": "…",
  "created_at": "…",
  "id": "…",
  "is_deleted": "…",
  "is_edited": "…",
  "is_pinned": "…",
  "message_type": "…",
  "room_id": "…",
  "sender_id": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
500Failed to send message
500Internal server error
#post-api-v1-messaging-rooms-room-id-messagesmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:2694The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
PUT/api/v1/messaging/rooms/{room_id}/messages/{message_id}Verified in sessionEdit your own message.

Edit your own message. Shows an 'edited' marker; no edit history (WhatsApp semantics).

Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequired
message_idstringrequired

Request body (required) — EditMessageRequest

FieldTypeRequiredNotes
contentstringrequired

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X PUT 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/messages/{message_id}' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "content": "<string>" }'

Response · 200

Top-level keys
{
  "content": "…",
  "edited_at": "…",
  "id": "…",
  "is_edited": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
404Message not found
403You can only edit your own messages
422Content cannot be empty
500Failed to edit message
#put-api-v1-messaging-rooms-room-id-messages-message-idmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:3505The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
DELETE/api/v1/messaging/rooms/{room_id}/messages/{message_id}Verified in sessionSoft-delete a single message ("delete for everyone").

Soft-delete a single message ("delete for everyone"). Only the original sender or the room creator may delete a message. The row is marked is_deleted=true (retained for audit; filtered out of history) and a `message_deleted` event is broadcast over Redis + the in-memory socket manager so every connected client removes the bubble live.

Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequiredRoom ID
message_idstringrequiredMessage ID

Request

curl
curl -X DELETE 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/messages/{message_id}' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "id": "…",
  "is_deleted": "…",
  "room_id": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
404Room not found
404Message not found
403You can only delete your own messages
500Failed to delete message
500Internal server error
#delete-api-v1-messaging-rooms-room-id-messages-message-idmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:2750The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
POST/api/v1/messaging/rooms/{room_id}/messages/{message_id}/forwardVerified in sessionForward to up to 5 rooms the caller belongs to (WhatsApp's anti-spam cap).
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequired
message_idstringrequired

Request body (required) — ForwardRequest

FieldTypeRequiredNotes
target_room_idsstring[]required

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/messages/{message_id}/forward' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "target_room_ids": [ "<string>" ] }'

Response · 200

Top-level keys
{
  "count": "…",
  "forwarded": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
404Message not found
422No valid target rooms
#post-api-v1-messaging-rooms-room-id-messages-message-id-forwardmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:3658The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
POST/api/v1/messaging/rooms/{room_id}/messages/{message_id}/pinVerified in sessionPin or unpin a message in a room.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequired
message_idstringrequired

Request body (required) — PinRequest

FieldTypeRequiredNotes
pinnedbooleanoptionalDefault true.

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/messages/{message_id}/pin' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "pinned": true }'

Response · 200

Top-level keys
{
  "id": "…",
  "is_pinned": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
404Message not found
500Failed to update pin
#post-api-v1-messaging-rooms-room-id-messages-message-id-pinmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:3552The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
GET/api/v1/messaging/rooms/{room_id}/messages/{root_id}/threadVerified in sessionRoot message + its replies, oldest first.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequired
root_idstringrequired

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/messages/{root_id}/thread' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "messages": "…",
  "root_id": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
404Thread not found
500Failed to load thread
#get-api-v1-messaging-rooms-room-id-messages-root-id-threadmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:4400The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
GET/api/v1/messaging/rooms/{room_id}/pinsVerified in sessionPinned messages in a room.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequired

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/pins' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "pins": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
500Failed to list pins
#get-api-v1-messaging-rooms-room-id-pinsmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:3582The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
GET/api/v1/messaging/rooms/{room_id}/pollsVerified in sessionPoll snapshots for a room.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequired

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/polls' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "polls": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
500Failed to list polls
#get-api-v1-messaging-rooms-room-id-pollsmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:3965The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
POST/api/v1/messaging/rooms/{room_id}/pollsVerified in sessionCreate a poll in a room (question plus 2-12 options).
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequired

Request body (required) — CreatePollRequest

FieldTypeRequiredNotes
questionstringrequired
optionsstring[]required
allows_multiplebooleanoptionalDefault false.

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/polls' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "question": "<string>", "options": [ "<string>" ], "allows_multiple": false }'

Response · 200

The poll snapshot object.

Errors

Statusdetail
422A poll needs a question and at least 2 options
500Failed to create poll message
500Failed to create poll
#post-api-v1-messaging-rooms-room-id-pollsmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:3880The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
POST/api/v1/messaging/rooms/{room_id}/readVerified in sessionRecord read receipts for every message from other senders in this room that the caller hasn't read yet, and broadcast so senders' ticks update.

Record read receipts for every message from other senders in this room that the caller hasn't read yet, and broadcast so senders' ticks update.

Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequired

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/read' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "marked": "…",
  "room_id": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
400Invalid user
500Failed to mark read
#post-api-v1-messaging-rooms-room-id-readmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:4443The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
POST/api/v1/messaging/rooms/{room_id}/scheduledVerified in sessionSchedule a message to be posted to a room later.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequired

Request body (required) — ScheduleMessageRequest

FieldTypeRequiredNotes
contentstringrequired
scheduled_forstringrequired
message_typestringoptionalDefault "text".
recurrenceobject?optional

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/scheduled' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "content": "<string>", "scheduled_for": "<string>", "message_type": "text", "recurrence": {} }'

Response · 200

Top-level keys
{
  "content": "…",
  "id": "…",
  "is_recurring": "…",
  "room_id": "…",
  "scheduled_for": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
422Content cannot be empty
422scheduled_for is in the past
422recurrence.interval_minutes must be an integer >= 5
422scheduled_for must be an ISO timestamp
500Failed to schedule message
#post-api-v1-messaging-rooms-room-id-scheduledmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:4091The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
GET/api/v1/messaging/rooms/{room_id}/settingsVerified in sessionReturn the caller's per-room flags (mute/favorite/blocked/etc.).
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequiredRoom ID

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/settings' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "room_id": "…",
  "settings": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
404Room not found
500Internal server error
#get-api-v1-messaging-rooms-room-id-settingsmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:2830The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
PUT/api/v1/messaging/rooms/{room_id}/settingsVerified in sessionPersist the caller's per-room flags.

Persist the caller's per-room flags. is_muted → column; the rest → notification_settings.vx_flags. Partial update (only sent fields change).

Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequiredRoom ID

Request body (required) — ParticipantSettingsRequest

FieldTypeRequiredNotes
is_mutedboolean?optional
is_favoriteboolean?optional
is_blockedboolean?optional
is_reportedboolean?optional
is_archivedboolean?optional
disappearing_messagesstring?optional
added_to_liststring?optional
cleared_atstring?optional

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X PUT 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/settings' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "is_muted": false, "is_favorite": false, "is_blocked": false, "is_reported": false, "is_archived": false, "disappearing_messages": "<string>", "added_to_list": "<string>", "cleared_at": "<string>" }'

Response · 200

Top-level keys
{
  "room_id": "…",
  "settings": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
404Room not found
403Not a participant of this room
500Internal server error
#put-api-v1-messaging-rooms-room-id-settingsmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:2849The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
GET/api/v1/messaging/rooms/{room_id}/usersVerified in sessionRoom participants with their presence state.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequiredRoom ID

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/users' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "count": "…",
  "users": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
500Internal server error
#get-api-v1-messaging-rooms-room-id-usersmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:2991The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
POST/api/v1/messaging/rooms/{room_id}/webhookVerified in sessionReturns a tokenized URL that external systems (CI, Grafana, vxalerts) can POST {"text": "..."} to.

Returns a tokenized URL that external systems (CI, Grafana, vxalerts) can POST {"text": "..."} to. Token is stored in chat_rooms.settings.

Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
room_idstringrequired

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/messaging/rooms/{room_id}/webhook' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "note": "…",
  "room_id": "…",
  "webhook_path": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
500Failed to create webhook
#post-api-v1-messaging-rooms-room-id-webhookmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:4328The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
GET/api/v1/messaging/rooms/discoverCalled liveList joinable rooms the caller isn't in yet — for the Browse Channels / Browse Groups UI.

List joinable rooms the caller isn't in yet — for the Browse Channels / Browse Groups UI. Groups are always tenant-scoped regardless of `scope`; channels honor the scope parameter.

Auth
get_current_user
Scope
user
Success
200 · application/json
Envelope
bare-object

Query parameters

NameTypeRequiredNotes
searchstring?optionalFilter by room name or description
limitintegeroptionalDefault 100. min 1. max 200.
scopestringoptional'organization' (default, same tenant) or 'all' (every public room) Default "organization".
room_typestringoptional'public' (channels, default) or 'group' (org squads — always tenant-scoped) Default "public".

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/rooms/discover' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "rooms": [
    {
      "id": "str",
      "name": "str",
      "description": "str",
      "room_type": "str",
      "is_active": "bool",
      "is_public": "bool",
      "is_global": "bool",
      "created_at": "str",
      "updated_at": "str",
      "last_activity": "str",
      "created_by_id": "int",
      "participant_count": "int"
    },
    "...x1"
  ],
  "count": "int"
}
Observed on 2026-08-06 — keys are real, values are the types that came back.

Errors

Statusdetail
500Internal server error
#get-api-v1-messaging-rooms-discovermessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:2441Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
GET/api/v1/messaging/rtc/iceCalled liveSTUN/TURN config + the mesh caps the server will actually enforce.

STUN/TURN config + the mesh caps the server will actually enforce. `turn_configured` is false on this deployment and `warning` says why: with no relay, symmetric-NAT peers never connect. The client is expected to show that as a real error rather than an endless 'connecting…'.

Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/rtc/ice' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "ice_servers": [
    {
      "urls": [
        "...",
        "...x1"
      ]
    },
    "...x1"
  ],
  "max_mesh": {
    "audio": "int",
    "video": "int"
  },
  "turn_configured": "bool",
  "ring_timeout_seconds": "int",
  "ring_fanout_max": "int",
  "warning": "str"
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-messaging-rtc-icemessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:3025Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
GET/api/v1/messaging/scheduledCalled liveThe caller's scheduled messages.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/scheduled' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "scheduled": [
    "<empty list>"
  ]
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-messaging-scheduledmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:4134Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
DELETE/api/v1/messaging/scheduled/{scheduled_id}Verified in sessionCancel one of the caller's scheduled messages.
Auth
get_current_user_id
Scope
user
Success
200 · application/json
Envelope
bare-object

Path parameters

NameTypeRequiredNotes
scheduled_idstringrequired

Request

curl
curl -X DELETE 'https://api.vxcloud.io/api/v1/messaging/scheduled/{scheduled_id}' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "cancelled": "…"
}
Top-level keys read from the handler's return statements.
#delete-api-v1-messaging-scheduled-scheduled-idmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:4156The messaging feature was verified working against the live system in the session that produced this inventory. This specific route was not re-called during the inventory run.
GET/api/v1/messaging/usersCalled liveList active users available to start a direct message with.

List active users available to start a direct message with. ALWAYS scoped to the caller's organization. `scope=all` used to return every active user on the platform — id, name, username, email and organization_id — to anyone with a valid token, which is a cross-tenant directory dump and, with guests in the picture, one an external customer could ask for. It is now honored only for platform superusers; everyone else is silently org-scoped, which is what the UI wanted anyway. Excludes the caller. Augments each row with a live presence status from Redis when available; otherwise reports 'offline'.

Auth
get_current_user
Scope
user
Success
200 · application/json
Envelope
bare-object

Query parameters

NameTypeRequiredNotes
searchstring?optionalFilter by name, email, username, or @username
limitintegeroptionalMax users to return Default 200. min 1. max 500.
scopestringoptional'organization' (default, same tenant). 'all' is honored for platform superusers only — every other caller is org-scoped. Default "organization".

Request

curl
curl 'https://api.vxcloud.io/api/v1/messaging/users' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "users": [
    {
      "id": "str",
      "name": "str",
      "username": "str",
      "email": "str",
      "role": "str",
      "avatar": "null",
      "avatar_color": "str",
      "organization_id": "str",
      "status": "str",
      "last_seen": "str"
    },
    "...x4"
  ],
  "count": "int"
}
Observed on 2026-08-06 — keys are real, values are the types that came back.

Errors

Statusdetail
500Internal server error
#get-api-v1-messaging-usersmessaging_services_router · vxcloud_fastapiclient/app/services/messaging/messaging_services_router.py:2485Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.