Skip to main content
Version: Next

Selective Subscriptions

In Fishjam, peers in a conferencing room automatically subscribe to every other peer by default.
Selective Subscriptions let you break from that — giving your backend the ability to decide who receives what.

In manual subscription mode, a peer or agent:

  • does not automatically receive any tracks, and
  • can explicitly subscribe to specific tracks from other peers.

When to use Selective Subscriptions

  • large-scale rooms with dozens or hundreds of peers,
  • “stage & audience” models (viewers only see speakers),
  • bandwidth optimization (e.g., audio-only dashboards, or delayed video activation).

Core idea

  • Peers have a subscribeMode — either auto or manual.
  • Peers in auto mode subscribe to everyone automatically (default behavior).
  • Peers in manual mode will not receive any media until you explicitly subscribe them using the Server SDK.
  • Peers in manual mode can subscribe to:
    • another peer (all of its tracks), or
    • specific tracks of another peer.

::: note Only connected peers can subscribe to others. :::


Step 1 — Create a peer with manual subscription mode

When creating a peer, set subscribeMode to "manual".
This peer will start with zero subscriptions — it will not receive anyone’s audio or video.

// Create a conference room const room = await fishjamClient.createRoom({ roomType: "conference", }); // Create a normal publisher const { peer: publisher } = await fishjamClient.createPeer(room.id, { subscribeMode: "auto", }); // Create a manual subscriber const { peer: viewer } = await fishjamClient.createPeer(room.id, { subscribeMode: "manual", });

Step 2 — Subscribe a peer to another peer

Use this when you want your manual subscriber to receive all tracks published by another peer.

// Subscribe viewer to everything published by publisher await fishjamClient.subscribePeer(room.id, subscriber.id, publisher.id);

This will make every current and future track of the publisher available to the subscriber.
It’s additive — the subscriber can listen to multiple publishers at once.


Step 3 — Subscribe to specific tracks

Sometimes you only want a subset of a publisher’s tracks, for example:

  • their screenshare, but not their camera,
  • only audio, without video.
// Get track IDs from your room state or webhook events const audioTrackId = "track_audio_abc" as TrackId; const screenTrackId = "track_screen_xyz" as TrackId; // Subscribe to a single track await fishjamClient.subscribeTracks(room.id, subscriber.id, [audioTrackId]); // Or multiple await fishjamClient.subscribeTracks(room.id, subscriber.id, [ audioTrackId, screenTrackId, ]);

📘 Track IDs are available from Fishjam’s events in your backend.


Step 4 — Combine multiple publishers

A manual peer can subscribe to several publishers at once.
Each call to subscribePeer adds more publishers — it doesn’t overwrite the previous ones.

const options = { subscribeMode: "manual" } satisfies PeerOptions; const { peer: subscriber } = await fishjamClient.createPeer(room.id, options); const { peer: publisherA } = await fishjamClient.createPeer(room.id, options); const { peer: publisherB } = await fishjamClient.createPeer(room.id, options); // Subscribe subscriber to two publishers await fishjamClient.subscribePeer(room.id, subscriber.id, publisherA.id); await fishjamClient.subscribePeer(room.id, subscriber.id, publisherB.id);

The subscriber now receives tracks from both publishers simultaneously.


Step 5 — Example: curated stage & audience

You can implement a “stage” system where:

  • speakers are in auto mode (they see/hear each other),
  • audience members are manual subscribers (they only see the stage).
// fetch room to get actual list of peers const fetchedRoom = await fishjamClient.getRoom(room.id); const currentSpeakers = fetchedRoom.peers; // audience joins in manual mode const { peer: audience } = await fishjamClient.createPeer(room.id, { subscribeMode: "manual", }); // subscribe them to all current speakers await Promise.all( currentSpeakers.map((speaker) => fishjamClient.subscribePeer(room.id, audience.id, speaker.id), ), );

As new speakers join, simply call subscribe_peer again to add them to the audience’s feed.


Notes & limitations

  • Only connected peers can subscribe to others.
  • Peers created with subscribeMode: 'auto' always subscribe to everyone automatically.
  • Unsubscribe support is not yet implemented (for now, just remove peer sessions when needed).

See also

🗒️ For server-side recording or media processing, see Agents (documented separately).