little-king-41579
03/02/2026, 10:30 AMtall-airline-16756
03/02/2026, 10:31 AMtall-airline-16756
03/02/2026, 10:31 AMidentity is audible to Praneeth and agent-AJ_zthLaCfmrbCs in room room-claim_status_verification-1772446764419 (project [ecs]).
Two things must be true:
• identity can publish audio.
• Praneeth and agent-AJ_zthLaCfmrbCs can subscribe to `identity`'s tracks.
If your CLI is lk (LiveKit CLI), you can update these participant permissions with the following commands.
1) Ensure identity can publish audio (and data if desired):
lk room update participant "room-claim_status_verification-1772446764419" "identity" \
--can-publish=true \
--can-publish-data=true \
--metadata="allow-audio-publish"
2) Ensure Praneeth and agent-AJ_zthLaCfmrbCs can subscribe:
lk room update participant "room-claim_status_verification-1772446764419" "Praneeth" \
--can-subscribe=true
lk room update participant "room-claim_status_verification-1772446764419" "agent-AJ_zthLaCfmrbCs" \
--can-subscribe=true
Follow-up checks if audio still isn’t heard:
• Confirm `identity`'s audio track is actually publishing (you mentioned they have 1 track — verify it’s an audio track).
• Confirm Praneeth and agent-AJ_zthLaCfmrbCs are subscribed to that track (client-side may need to subscribe or enable auto-subscribe).
• If you use any server-side subscription filters or participant-level restrictions, ensure they aren’t blocking identity.
If you want, tell me:
• Which command you ran (if any) and the CLI output, or
• Whether the identity track is audio vs. video (I can give next steps to verify or force-subscribe if needed). Sources: Server-side | livekit/livekit_composite | DeepWiki | server-sdk-go | livekit/livekit_composite | DeepWikilittle-king-41579
03/02/2026, 10:56 AMtall-airline-16756
03/02/2026, 10:57 AMroom-claim_status_verification-1772446764419.
Important context first:
• The definitive way to know whether a participant can subscribe is to check the canSubscribe grant that was set when their access token was generated. LiveKit does not expose another participant’s original token grants from the server API unless you stored them in your backend.
• If you don’t have stored grants, you can infer "listening" by checking room state: whether the other participant is publishing an audio track and whether the subscriber is currently subscribed to that track.
Below are two clear Python helpers. Pick the one that matches your setup.
1) Recommended — check stored grants (accurate)
• Requires that your backend stored the token grants (e.g., {"can_subscribe": True}) when creating tokens.
from typing import Callable, Dict
def check_by_stored_grants(
identity_a: str,
identity_b: str,
get_stored_grants: Callable[[str], Dict]
) -> Dict[str, bool]:
"""
Check if identity_a can listen to identity_b and vice versa using stored token grants.
get_stored_grants(identity) should return a dict containing at least {"can_subscribe": bool}.
Returns:
{
"a_can_listen_to_b": bool,
"b_can_listen_to_a": bool
}
"""
grants_a = get_stored_grants(identity_a) or {}
grants_b = get_stored_grants(identity_b) or {}
a_can_subscribe = bool(grants_a.get("can_subscribe"))
b_can_subscribe = bool(grants_b.get("can_subscribe"))
return {
"a_can_listen_to_b": a_can_subscribe,
"b_can_listen_to_a": b_can_subscribe,
}
2) Inference via room state (no stored grants required)
• Uses the LiveKit server API to see who is publishing audio and whether subscribers are currently subscribed to those audio tracks.
• This infers actual subscription state; it is accurate for whether the subscriber is currently receiving audio, but it does not prove the original token grant.
Example using a generic LiveKit server client — adapt imports/field names to the Python LiveKit server SDK you have:
import asyncio
from typing import Dict
# Replace these imports/usage with your actual LiveKit server SDK.
# Example names below are illustrative and may need adjusting.
from livekit import LiveKitServerSdk # replace with actual SDK import
async def check_by_room_state(
room_name: str,
identity_a: str,
identity_b: str,
livekit_url: str,
api_key: str,
api_secret: str,
) -> Dict[str, bool]:
"""
Infer whether A can listen to B and B can listen to A by:
- checking that publisher publishes an audio track, and
- checking that subscriber has a subscription to that track.
Returns:
{
"a_can_listen_to_b": bool,
"b_can_listen_to_a": bool,
"error": optional str
}
"""
client = LiveKitServerSdk(url=livekit_url, api_key=api_key, api_secret=api_secret)
# Adjust API call names to your SDK:
room = await client.get_room(room_name)
participants = room.participants # list of participant objects
pmap = {p.identity: p for p in participants}
if identity_a not in pmap or identity_b not in pmap:
return {
"a_can_listen_to_b": False,
"b_can_listen_to_a": False,
"error": "one_or_both_participants_not_in_room"
}
pa = pmap[identity_a]
pb = pmap[identity_b]
def publishes_audio(participant) -> bool:
for t in getattr(participant, "tracks", []):
if getattr(t, "kind", "").lower() == "audio":
return True
return False
def is_subscribed(subscriber, publisher) -> bool:
# Find publisher audio track SIDs
pub_audio_sids = {
getattr(t, "sid") for t in getattr(publisher, "tracks", [])
if getattr(t, "kind", "").lower() == "audio" and getattr(t, "sid", None)
}
if not pub_audio_sids:
return False
# Check subscriber's subscribed tracks (field names vary by SDK)
for sub in getattr(subscriber, "subscribed_tracks", []):
if getattr(sub, "track_sid", None) in pub_audio_sids:
return True
return False
a_can_listen_to_b = publishes_audio(pb) and is_subscribed(pa, pb)
b_can_listen_to_a = publishes_audio(pa) and is_subscribed(pb, pa)
return {
"a_can_listen_to_b": a_can_listen_to_b,
"b_can_listen_to_a": b_can_listen_to_a
}
Quick troubleshooting checklist if inference shows "not subscribed" but permissions should allow it:
• Ensure the subscriber’s token had canSubscribe = true.
• Check client-side auto-subscribe settings (if auto-subscribe is disabled, the client must manually subscribe).
• Confirm the publisher actually has an audio track (not a video track).
• Confirm the client isn’t muted or using wrong audio output.
If you want, I can:
• Provide a version of the room-state function tailored to the exact Python LiveKit server SDK/package and version you use (tell me the SDK name/version).
• Add an example get_stored_grants implementation that reads grants from a simple backend store (e.g., Redis or a database). Sources: server-sdk-kotlin | livekit/livekit_composite | DeepWiki | Python SDKs | livekit/livekit_composite | DeepWiki