# Querying Calls

The Stream Video SDK allows you to query calls and watch them.
This allows you to build apps that display feeds of calls with real-time updates (without joining them).

You can query calls based on built-in fields as well as any custom field you add to the calls.
Multiple filters can be combined using AND, OR logical operators,
each filter can use its comparison (equality, inequality, greater than, greater or equal, etc.).

You can use the `StreamVideoClient` to query for:

- Upcoming calls
- Calls that are currently live
- Popular live streams / audio rooms with a link to the recording

## Client API

You can query calls by using the client directly by using the following API:

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

## Filters

Filter expressions support multiple match criteria, and it's also possible to combine filters.
You can filter on the following fields:

| Field                | Description                                                   |
| -------------------- | ------------------------------------------------------------- |
| `id`                 | The id for this call                                          |
| `cid`                | The cid for this call. IE: `default:123`                      |
| `team`               | The team id for the call.                                     |
| `type`               | The call type. Typically `default`, `livestream` etc...       |
| `created_by_user_id` | The user id who created the call                              |
| `created_at`         | When the call was created                                     |
| `updated_at`         | When the call was updated                                     |
| `ended_at`           | When the call ended                                           |
| `starts_at`          | When the call starts at                                       |
| `backstage`          | If the call is in backstage mode or not                       |
| `members`            | Check if the call has these members listed                    |
| `ongoing`            | Check if the call is ongoing or not                           |
| `custom`             | You can query custom data using the `"custom.myfield"` syntax |

For more information, visit the [filter operators guide](/chat/docs/react/query_syntax_operators/). Or check the examples:

### Calls that are about to start

In this snippet, you can see how you can query for calls that have `livestream` type and are about to start 30 minutes from now:

```typescript
import { StreamVideoClient } from "@stream-io/video-client";

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

```typescript
import { StreamVideoClient } from "@stream-io/video-client";

let client: StreamVideoClient;

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

### Calls that are ongoing / currently have participants

```typescript
import { StreamVideoClient } from "@stream-io/video-client";

let client: StreamVideoClient;

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

### Calls the user has created or is a member of

```typescript
import { StreamVideoClient } from "@stream-io/video-client";

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

The `SortParamRequest` model contains two properties: `field` and `direction`.

The `direction` can be `1` for ascending and `-1` for descending, while the field can be one of the following values:

| Field        | Description                                             |
| ------------ | ------------------------------------------------------- |
| `starts_at`  | When the call starts at                                 |
| `created_at` | When the call was created                               |
| `updated_at` | When the call was updated                               |
| `ended_at`   | When the call ended                                     |
| `type`       | The call type. Typically `default`, `livestream` etc... |
| `id`         | The id for this call                                    |
| `cid`        | The cid for this call. IE: `default:123`                |

```typescript
import { StreamVideoClient } from "@stream-io/video-client";

let client: StreamVideoClient;

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

It's possible to provide multiple sort parameters:

```typescript
import { StreamVideoClient } from "@stream-io/video-client";

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

If you specify `watch: true` as an option, the SDK will create a subscription to the call data on the server and you'll be able to receive updates in real-time.

The server will send updates to the client when the call data changes
(for example, members are updated, a call session has started, etc...).
This is useful for showing a live preview of who is in the call or building a call dashboard.

## Pagination

You can specify the page size using the `limit` option. The API response will include links to the previous/next pages. The following code example shows how pagination works:

```typescript
import { StreamVideoClient } from "@stream-io/video-client";

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 }));
```


---

This page was last updated at 2026-04-10T16:31:15.280Z.

For the most recent version of this documentation, visit [https://getstream.io/video/docs/javascript/guides/querying-calls/](https://getstream.io/video/docs/javascript/guides/querying-calls/).