Core WebSocket API
WebSocket API contracts and events for the Core service.
Core WebSocket API
All events follow the CloudEvents v1.0 envelope. Every event that originates from a user action includes sourceClientId at the envelope root — the originating client discards events where sourceClientId matches its own X-Client-Id.
EntityChangedEvent (Server → Client)
Cache-invalidation signal. Clients re-fetch the affected entity via REST on receipt.
{
"specversion": "1.0",
"id": "<uuid>",
"source": "wordloop-core/ws",
"type": "com.wordloop.entity.changed.v1",
"time": "<ISO8601>",
"sourceClientId": "<client-uuid>",
"data": {
"entity": "meeting | person | task | note | transcript_segment | talking_point",
"action": "created | updated | deleted",
"id": "<entity-uuid>"
}
}TranscriptSegmentEvent (Server → Client)
Live transcript segment during recording. Carries the full segment payload inline.
{
"specversion": "1.0",
"id": "<uuid>",
"source": "wordloop-core/ws",
"type": "com.wordloop.transcript.segment.v1",
"time": "<ISO8601>",
"data": {
"meeting_id": "<uuid>",
"segment": {
"id": "<uuid>",
"speaker_label": "Speaker A",
"person_id": "<uuid | null>",
"text": "string",
"start_ms": 1200,
"end_ms": 2400,
"confidence": 0.96,
"is_final": true
}
}
}TalkingPointEvent (Server → Client)
Streamed per finalised segment during live recording. Carries the full payload inline.
{
"specversion": "1.0",
"id": "<uuid>",
"source": "wordloop-core/ws",
"type": "com.wordloop.meeting.talking_point.v1",
"time": "<ISO8601>",
"sourceClientId": "<client-uuid>",
"data": {
"meeting_id": "<uuid>",
"talking_point": {
"id": "<uuid>",
"content": "string",
"is_final": true,
"segments": ["<segment-uuid>"]
}
}
}TaskEvent (Server → Client)
Streamed in batches (~60s) during live recording.
{
"specversion": "1.0",
"id": "<uuid>",
"source": "wordloop-core/ws",
"type": "com.wordloop.meeting.task.v1",
"time": "<ISO8601>",
"sourceClientId": "<client-uuid>",
"data": {
"meeting_id": "<uuid>",
"task": {
"id": "<uuid>",
"content": "string",
"source": "system"
}
}
}RecordingStartedEvent (Server → Client)
{
"specversion": "1.0",
"id": "<uuid>",
"source": "wordloop-core/ws",
"type": "com.wordloop.recording.started.v1",
"time": "<ISO8601>",
"data": { "meeting_id": "<uuid>", "session_id": "<opaque-session-id>" }
}RecordingStoppedEvent (Server → Client)
{
"specversion": "1.0",
"id": "<uuid>",
"source": "wordloop-core/ws",
"type": "com.wordloop.recording.stopped.v1",
"time": "<ISO8601>",
"data": { "meeting_id": "<uuid>" }
}RecordingDegradedEvent (Server → Client)
{
"specversion": "1.0",
"id": "<uuid>",
"source": "wordloop-core/ws",
"type": "com.wordloop.recording.degraded.v1",
"time": "<ISO8601>",
"data": { "meeting_id": "<uuid>", "reason": "string" }
}StartRecordingCommand (Client → Server)
{
"specversion": "1.0",
"id": "<uuid>",
"source": "wordloop-app/ws",
"type": "com.wordloop.recording.start.v1",
"time": "<ISO8601>",
"data": {
"meeting_id": "<uuid>",
"audio_config": { "encoding": "pcm16 | webm | mp3", "sample_rate": 16000, "channels": 1 }
}
}StopRecordingCommand (Client → Server)
{
"specversion": "1.0",
"id": "<uuid>",
"source": "wordloop-app/ws",
"type": "com.wordloop.recording.stop.v1",
"time": "<ISO8601>",
"data": { "meeting_id": "<uuid>" }
}