WordloopWordloop
WorkDeliveredLive CaptureTechnical DesignContractsCore

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>" }
}

On this page