FluxyChat

Core SDK

Voice messages

Upload voice clips to a room with optional transcription.

FluxyChat supports async voice messages (record → upload → optional AI transcription). There is no useHuddle hook in @fluxy-chat/react today — live WebRTC huddles are not part of the public SDK.

Enable the feature on the Worker:

FEATURE_VOICE_MESSAGES=true

Bind R2 for attachments (ATTACHMENTS in wrangler.toml).

Upload from the client

POST /messages/voice accepts multipart form data with a member JWT (same auth as POST /messages):

const form = new FormData();
form.append("audio", blob, "recording.webm");
form.append("roomId", roomId);
form.append("durationMs", String(durationMs));

const res = await fetch(`${baseUrl}/messages/voice`, {
  method: "POST",
  headers: { Authorization: `Bearer ${token}` },
  body: form,
});

const { messageId, audioUrl, transcriptionStatus } = await res.json();
// transcriptionStatus: "pending" → later "ready" via message_updated WS event

Supported formats: webm, ogg, mp3, m4a, wav. Size and duration limits return 413 when exceeded.

Realtime updates

After upload, the Worker broadcasts a message_updated event when transcription completes. Subscribe via the room WebSocket or poll message history if the socket is down.

Rate limits and quotas

Voice uploads consume message quota and respect RATE_LIMIT_VOICE_MESSAGES_PER_MINUTE (default 10/min per user).

Live voice / huddles

joinVoiceStage / leaveVoiceStage on useChat is stage signaling (speaker vs listener on the room WebSocket). Scaffold: --example voice-stage.

It is not WebRTC audio. Console: /voice-ai. Media for huddles is LiveKit. Voice AI latency: load report and GET /admin/voice-ai/stats. Product SLO P95 ≤ 300ms is a target; treat tables as unit-bench until stats are populated. Async clips remain POST /messages/voice.

On this page