Skip to main content
These events fire when media tracks start or stop, when screen sharing changes, and when audio level and face detection information is available. Support varies per event — see the badge on each section.

track-started

Fires when a participant’s media track begins. Use this to attach the track to a media element or update your UI when a new audio, video, or screen share track becomes available.
action
string
Always "track-started".
callClientId
string
The ID of the call client instance that emitted this event.
participant
DailyParticipant
The participant whose track started. See participants() for the full shape.
track
MediaStreamTrack
The MediaStreamTrack that started.
type
string
The track type. One of 'audio', 'video', 'screenAudio', 'screenVideo', or a custom track name.
// Example event object
{
  "action": "track-started",
  "callClientId": "17225364729060.9442072768918943",
  "participant": {
    "session_id": "f2190c86-169a-464f-c0a4-ee1d5c00af58",
    "user_id": "f2190c86-169a-464f-c0a4-ee1d5c00af58",
    "user_name": "",
    "local": true,
    "owner": false,
    "record": false,
    "networkQualityState": "good",
    "tracks": {
      "audio": { "state": "playable", "subscribed": true },
      "video": { "state": "playable", "subscribed": true },
      "screenVideo": { "state": "off", "subscribed": false },
      "screenAudio": { "state": "off", "subscribed": false }
    },
    "joined_at": "2024-06-01T12:00:00.000Z",
    "will_eject_at": "2024-06-01T13:00:00.000Z"
  },
  "track": {
    "contentHint": "",
    "enabled": true,
    "id": "60d47b9f-6b07-4039-930a-8b752c6dbd26",
    "kind": "video",
    "label": "FaceTime HD Camera (Built-in) (05ac:8514)",
    "muted": false,
    "onended": null,
    "onmute": null,
    "onunmute": null,
    "readyState": "live",
    "managedByDaily": true
  },
  "type": "video"
}
call.on('track-started', ({ participant, track, type }) => {
  if (type === 'video' && !participant.local) {
    const videoEl = document.createElement('video');
    videoEl.srcObject = new MediaStream([track]);
    videoEl.autoplay = true;
    document.getElementById('remote-videos').appendChild(videoEl);
  }
});

track-stopped

Fires when a participant’s media track stops. Use this to remove a media element or update your UI when a track is no longer active.
action
string
Always "track-stopped".
callClientId
string
The ID of the call client instance that emitted this event.
participant
DailyParticipant
The participant whose track stopped. See participants() for the full shape.
track
MediaStreamTrack
The MediaStreamTrack that stopped.
type
string
The track type. One of 'audio', 'video', 'screenAudio', 'screenVideo', or a custom track name.
// Example event object
{
  "action": "track-stopped",
  "callClientId": "17225364729060.9442072768918943",
  "participant": {
    "session_id": "f2190c86-169a-464f-c0a4-ee1d5c00af58",
    "user_id": "f2190c86-169a-464f-c0a4-ee1d5c00af58",
    "user_name": "",
    "local": true,
    "owner": false,
    "record": false,
    "networkQualityState": "good",
    "tracks": {
      "audio": { "state": "playable", "subscribed": true },
      "video": { "state": "off", "subscribed": false },
      "screenVideo": { "state": "off", "subscribed": false },
      "screenAudio": { "state": "off", "subscribed": false }
    },
    "joined_at": "2024-06-01T12:00:00.000Z",
    "will_eject_at": "2024-06-01T13:00:00.000Z"
  },
  "track": {
    "contentHint": "",
    "enabled": true,
    "id": "60d47b9f-6b07-4039-930a-8b752c6dbd26",
    "kind": "video",
    "label": "FaceTime HD Camera (Built-in) (05ac:8514)",
    "muted": false,
    "onended": null,
    "onmute": null,
    "onunmute": null,
    "readyState": "ended",
    "managedByDaily": true
  },
  "type": "video"
}
call.on('track-stopped', ({ participant, track, type }) => {
  if (type === 'video' && !participant.local) {
    const videoEl = document.getElementById(`video-${participant.session_id}`);
    if (videoEl) videoEl.remove();
  }
});

local-screen-share-started

Fires when the local participant’s screen share has started. Use this to update your UI to reflect that sharing is active.
action
string
Always "local-screen-share-started".
callClientId
string
The ID of the call client instance that emitted this event.
// Example event object
{
  "action": "local-screen-share-started",
  "callClientId": "17225364729060.9442072768918943"
}
call.on('local-screen-share-started', () => {
  document.getElementById('share-btn').textContent = 'Stop sharing';
  document.getElementById('share-indicator').classList.remove('hidden');
});

local-screen-share-stopped

Fires when the local participant’s screen share has stopped. Use this to reset any screen-share UI state.
action
string
Always "local-screen-share-stopped".
callClientId
string
The ID of the call client instance that emitted this event.
// Example event object
{
  "action": "local-screen-share-stopped",
  "callClientId": "17225364729060.9442072768918943"
}
call.on('local-screen-share-stopped', () => {
  document.getElementById('share-btn').textContent = 'Share screen';
  document.getElementById('share-indicator').classList.add('hidden');
});

local-screen-share-canceled

Fires when the user dismisses the browser’s screen picker before ever starting a screen share.
Detection of this user action only works in Chrome. On Safari and Firefox, this action is reported as the user blocking the permission and a nonfatal screen-share-error event is sent instead.
action
string
Always "local-screen-share-canceled".
callClientId
string
The ID of the call client instance that emitted this event.
// Example event object
{
  "action": "local-screen-share-canceled",
  "callClientId": "17225364729060.9442072768918943"
}
call.on('local-screen-share-canceled', () => {
  // User closed the picker — reset the button back to its idle state.
  document.getElementById('share-btn').disabled = false;
  document.getElementById('share-btn').textContent = 'Share screen';
});

local-audio-level

Fires at the frequency specified when starting the local audio level observer, providing the local participant’s current audio level. Use this to drive a volume indicator in your UI.
action
string
Always "local-audio-level".
callClientId
string
The ID of the call client instance that emitted this event.
audioLevel
number
The local participant’s current audio level, from 0.0 (silent) to 1.0 (maximum).
// Example event object
{
  "action": "local-audio-level",
  "callClientId": "17225364729060.9442072768918943",
  "audioLevel": 0.149356
}
call.on('local-audio-level', ({ audioLevel }) => {
  const bar = document.getElementById('local-volume-bar');
  bar.style.width = `${Math.round(audioLevel * 100)}%`;
});

remote-participants-audio-level

Fires at the frequency specified when starting the remote participants audio level observer, providing audio levels for all remote participants. Use this to drive per-participant volume indicators or highlight the active speaker.
action
string
Always "remote-participants-audio-level".
callClientId
string
The ID of the call client instance that emitted this event.
participantsAudioLevel
object
A map of participant session_id to audio level (0.01.0). Only remote participants are included.
// Example event object
{
  "action": "remote-participants-audio-level",
  "callClientId": "17225364729060.9442072768918943",
  "participantsAudioLevel": {
    "24ebb6ed-315f-40c3-acb7-a917c4ea6202": 0.1,
    "cc3d2760-442e-4cfa-afc1-4fd387253f72": 0.0223872113856834
  }
}
call.on('remote-participants-audio-level', ({ participantsAudioLevel }) => {
  let activeSpeakerId = null;
  let maxLevel = 0;

  for (const [sessionId, level] of Object.entries(participantsAudioLevel)) {
    const bar = document.getElementById(`volume-${sessionId}`);
    if (bar) bar.style.width = `${Math.round(level * 100)}%`;

    if (level > maxLevel) {
      maxLevel = level;
      activeSpeakerId = sessionId;
    }
  }

  if (activeSpeakerId) {
    highlightActiveSpeaker(activeSpeakerId);
  }
});

face-counts-updated

Fires when the face count in the local camera view has changed. Use this to identify how many people are visible in frame at a given time. This event is only emitted while the face-detection video processor is active. See updateInputSettings() for details on enabling it.
action
string
Always "face-counts-updated".
callClientId
string
The ID of the call client instance that emitted this event.
faceCounts
number
The number of faces currently detected in the local camera view.
// Example event object
{
  "action": "face-counts-updated",
  "callClientId": "17225364729060.9442072768918943",
  "faceCounts": 1
}
call.on('face-counts-updated', ({ faceCounts }) => {
  const label = document.getElementById('face-count-label');
  label.textContent = `${faceCounts} ${faceCounts === 1 ? 'person' : 'people'} in frame`;
});

See also