# 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

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

## Filters

Available filter 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 |

See [filter operators guide](https://getstream.io/docs/platform/query-syntax-operators/) for details.

### Calls that are about to start

```ts
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

```ts
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

```ts
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

```ts
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):

| 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`                |

```ts
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:

```ts
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:

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

---

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