Summary
There is no way to make a voice call in a DM (1:1 or group DM). Voice is currently a space-only feature, and the server actively rejects voice on DM channels. This is the blocking dependency for DM calling in the Flutter client (DaccordProject/daccord).
Current behaviour
POST /channels/{id}/voice/join (src/routes/voice.rs) hard-fails before issuing LiveKit credentials:
if channel.channel_type != "voice" {
return Err(AppError::BadRequest("channel_not_voice"));
}
let space_id = channel.space_id.as_deref()
.ok_or_else(|| AppError::BadRequest("channel_has_no_space"))?;
A DM channel is type: "dm" / "group_dm" with space_id = NULL, so it fails both guards.
There is also no call signaling of any kind:
- Gateway voice events (
gateway/intents.rs) are presence-only: voice.state_update, voice.server_update, voice.signal.
voice.state_update is broadcast to the space, not to individual recipients — there is no path to notify DM participants.
- No
call / ring / incoming / accept / decline concept exists anywhere in the codebase.
What needs to happen (server)
Context
Investigated alongside the client. The accordkit SDK's client.voice.join(channelId) is already channel-agnostic, so once the server allows it the SDK needs little/no change — but signaling is net-new on both sides.
Client-side tracking issue: DaccordProject/daccord (linked).
Summary
There is no way to make a voice call in a DM (1:1 or group DM). Voice is currently a space-only feature, and the server actively rejects voice on DM channels. This is the blocking dependency for DM calling in the Flutter client (DaccordProject/daccord).
Current behaviour
POST /channels/{id}/voice/join(src/routes/voice.rs) hard-fails before issuing LiveKit credentials:A DM channel is
type: "dm"/"group_dm"withspace_id = NULL, so it fails both guards.There is also no call signaling of any kind:
gateway/intents.rs) are presence-only:voice.state_update,voice.server_update,voice.signal.voice.state_updateis broadcast to the space, not to individual recipients — there is no path to notify DM participants.call/ring/incoming/ accept / decline concept exists anywhere in the codebase.What needs to happen (server)
dm/group_dmchannels — relax thechannel_type != "voice"andspace_idguards for DM channels, gated byrequire_dm_access()participant check instead of space permissions.channel_idinsrc/voice/livekit.rs, sochannel_{dm_id}works).call.ring,call.accept,call.decline,call.end) or an extension of the voice events.voice.state_updateevents to DM participants rather than a space.Context
Investigated alongside the client. The accordkit SDK's
client.voice.join(channelId)is already channel-agnostic, so once the server allows it the SDK needs little/no change — but signaling is net-new on both sides.Client-side tracking issue: DaccordProject/daccord (linked).