Call Attendance

The QueryCallParticipantSessions endpoint retrieves a paginated list of participant sessions for a given call session. Each entry describes an individual join/leave event for a user within that session. This data is not real-time — stats may be delayed or incomplete during an active call. The complete and final data becomes available after the call ends and the call.stats_report_ready event is received.

Response overview

  • call_type: Type of the call.
  • call_id: ID of the call.
  • call_session_id: ID of the call session being queried.
  • total_participant_sessions: Total number of participant sessions in the call session.
  • total_participant_duration: Sum of all participant durations in seconds.
  • participants_sessions: Array of participant session details. Available for 90 days after the call session ends — after that, this array will be empty while all other response fields remain available:
    • user_id: ID of the user.
    • user_session_id: ID of the user's session.
    • joined_at: Timestamp when the participant joined.
    • left_at: Timestamp when the participant left.
    • duration_in_seconds: Duration of the participant's session in seconds.
    • publisher_type: Type of publisher (webrtc, rtmp, srt, etc.).
    • roles: Roles assigned to the participant.
  • next / prev: Cursors for pagination.
const call = client.video.call("default", "call-id");
const response = await call.queryCallParticipantSessions({
  session: "<session-id>",
  limit: 25,
});

Filtering

You can narrow down results using filter_conditions. Filters follow the same syntax as other query endpoints. Note that filters only affect the participants_sessions list — aggregated fields such as total_participant_sessions and total_participant_duration always reflect the full call session.

const response = await call.queryCallParticipantSessions({
  session: "<session-id>",
  filter_conditions: { user_id: { $eq: "alice" } },
});

To compute aggregated values (such as total duration or session count) for a filtered subset of participants, paginate through all pages and accumulate the results manually:

const filter_conditions = { user_id: { $eq: "alice" } };
let cursor;
let totalDuration = 0;
let totalSessions = 0;

do {
  const response = await call.queryCallParticipantSessions({
    session: "<session-id>",
    limit: 100,
    next: cursor,
    filter_conditions,
  });
  for (const s of response.data.participants_sessions) {
    totalDuration += s.duration_in_seconds;
    totalSessions += 1;
  }
  cursor = response.data.next;
} while (cursor);

Pagination

Use next and prev cursors from the response to paginate through results.

let cursor;
do {
  const response = await call.queryCallParticipantSessions({
    session: "<session-id>",
    limit: 25,
    next: cursor,
  });
  cursor = response.data.next;
} while (cursor);