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.
var call = client.video().call("default", "call-id");
var response = call.queryCallParticipantSessions(
  "<session-id>",
  QueryCallParticipantSessionsRequest.builder().limit(25).build()
);

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.

var response = call.queryCallParticipantSessions(
  "<session-id>",
  QueryCallParticipantSessionsRequest.builder()
    .filterConditions(Map.of("user_id", Map.of("$eq", "alice")))
    .build()
);

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:

String cursor = null;
long totalDuration = 0;
int totalSessions = 0;

do {
  var response = call.queryCallParticipantSessions(
    "<session-id>",
    QueryCallParticipantSessionsRequest.builder()
      .limit(100)
      .next(cursor)
      .filterConditions(Map.of("user_id", Map.of("$eq", "alice")))
      .build()
  );
  for (var s : response.getData().getParticipantsSessions()) {
    totalDuration += s.getDurationInSeconds();
    totalSessions++;
  }
  cursor = response.getData().getNext();
} while (cursor != null);

Pagination

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

String cursor = null;
do {
  var response = call.queryCallParticipantSessions(
    "<session-id>",
    QueryCallParticipantSessionsRequest.builder().limit(25).next(cursor).build()
  );
  cursor = response.getData().getNext();
} while (cursor != null);