Querying Calls

Query and watch calls to build feeds with real-time updates without joining. Filter by built-in or custom fields using AND/OR operators with various comparisons (equality, inequality, greater than, etc.).

Best Practices

  • Use watch: true to receive real-time call updates via WebSocket.
  • Combine filters with $or and $and operators for complex queries.
  • Use pagination for large result sets to improve performance.
  • Query custom fields with "custom.fieldName" syntax.

Query for upcoming calls, live calls, or popular streams/audio rooms.

Client API

const { calls } = await client.queryCalls({
  filter_conditions: { ...filters },
  sort: [...sortOptions],
  limit: 25,
  watch: true,
});

Filters

Available filter fields:

FieldDescription
idThe id for this call
cidThe cid for this call. IE: default:123
teamThe team id for the call.
typeThe call type. Typically default, livestream etc...
created_by_user_idThe user id who created the call
created_atWhen the call was created
updated_atWhen the call was updated
ended_atWhen the call ended
starts_atWhen the call starts at
backstageIf the call is in backstage mode or not
membersCheck if the call has these members listed
ongoingCheck if the call is ongoing or not
customYou can query custom data using the "custom.myfield" syntax

See filter operators guide for details.

Calls that are about to start

import { StreamVideoClient } from "@stream-io/video-react-sdk";

let client: StreamVideoClient;

const inNext30mins = new Date(Date.now() + 1000 * 60 * 60 * 30);

const { calls } = await client.queryCalls({
  filter_conditions: {
    type: { $eq: "livestream" },
    starts_at: { $gt: inNext30mins.toISOString() },
  },
  sort: [{ field: "starts_at", direction: -1 }],
  limit: 10,
  watch: true,
});

Call filters on a custom property

import { StreamVideoClient } from "@stream-io/video-react-sdk";

let client: StreamVideoClient;

const { calls } = await client.queryCalls({
  filter_conditions: { "custom.color": "red" },
  limit: 10,
  watch: true,
});

Calls that are ongoing / currently have participants

import { StreamVideoClient } from "@stream-io/video-react-sdk";

let client: StreamVideoClient;

const { calls } = await client.queryCalls({
  filter_conditions: { ongoing: true },
});

Calls the user has created or is a member of

import { StreamVideoClient } from "@stream-io/video-react-sdk";

let client: StreamVideoClient;

const { calls } = await client.queryCalls({
  filter_conditions: {
    $or: [
      { created_by_user_id: "<user id>" },
      { members: { $in: ["<user id>"] } },
    ],
  },
  limit: 10,
  watch: true,
});

Sorting

Use field and direction (1 ascending, -1 descending):

FieldDescription
starts_atWhen the call starts at
created_atWhen the call was created
updated_atWhen the call was updated
ended_atWhen the call ended
typeThe call type. Typically default, livestream etc...
idThe id for this call
cidThe cid for this call. IE: default:123
import { StreamVideoClient } from "@stream-io/video-react-sdk";

let client: StreamVideoClient;

const { calls } = await client.queryCalls({
  sort: [{ field: "starts_at", direction: -1 }],
  limit: 10,
  watch: true,
});

Multiple sort parameters:

import { StreamVideoClient } from "@stream-io/video-react-sdk";

let client: StreamVideoClient;

const { calls } = await client.queryCalls({
  sort: [
    { field: "starts_at", direction: -1 },
    { field: "created_at", direction: 1 },
  ],
  limit: 10,
  watch: true,
});

Watching calls

Set watch: true to receive real-time updates when call data changes (members updated, session started, etc.). Useful for live previews and dashboards.

Pagination

Use limit to set page size. The response includes prev/next cursors for navigation:

import { StreamVideoClient } from "@stream-io/video-react-sdk";

let client: StreamVideoClient;

const inNext30mins = new Date(Date.now() + 1000 * 60 * 60 * 30);
const callQuery = {
  filter_conditions: {
    type: { $eq: "livestream" },
    starts_at: { $gt: inNext30mins.toISOString() },
  },
  sort: [{ field: "starts_at", direction: -1 }],
  limit: 10,
  watch: true,
};

let { calls, prev, next } = await client.queryCalls(callQuery);

// Go to the next page
({ calls, prev, next } = await client.queryCalls({ ...callQuery, next }));

// Go to the previous page
({ calls, prev, next } = await client.queryCalls({ ...callQuery, prev }));