---
title: "Choosing the right method"
description: "Decision guide for picking between Call, CallList, FetchList, Batch and BatchByChunk in REST API v2 and v3."
canonical_url: "https://bitrix24.github.io/b24jssdk/docs/working-with-the-rest-api/choosing-the-right-method"
last_updated: "2026-06-02"
---
# Choosing the right method

> Decision guide for picking between Call, CallList, FetchList, Batch and BatchByChunk in REST API v2 and v3.

## Overview

The SDK exposes five primitives for talking to the Bitrix24 REST API, all reached through `b24.actions.v{2,3}.<primitive>.make(options)`. They look similar but have very different cost profiles. Picking the wrong one is the single most common source of slow apps and "why is my dashboard hammering the queue?" tickets — so this page exists to make the decision in 30 seconds.

Three axes drive the choice:

1. **One call or many?** A single REST method or several at once.
2. **Bounded or unbounded?** Do you know up front there are ≤ 50 results, or could there be 50 000?
3. **All-at-once or stream?** Need every record in memory for aggregation, or process them as they arrive?

> [!CAUTION]
> The instance-level shortcuts on `AbstractB24` (`b24.callMethod()`, `b24.callBatch()`, `b24.callListMethod()`, `b24.fetchListMethod()`, `b24.callBatchByChunk()`) are `@deprecated` and slated for removal in v2.0.0. They emit a runtime warning on every call and ignore the API-version split. Always call the action explicitly: `b24.actions.v2.call.make({…})` / `b24.actions.v3.batch.make({…})` etc. See the [v0 → v1 migration guide](https://bitrix24.github.io/b24jssdk/raw/docs/getting-started/migration/v1.md) for one-to-one rewrites.

## Decision matrix

| Your situation | Use |
| --- | --- |
| One method, one record (`crm.deal.get` , `tasks.task.get` ) | `Call` |
| One list method, ≤ a few thousand records, you need the full array in memory | `CallList` |
| One list method, tens of thousands of records, processed in chunks (CSV export, ETL) | `FetchList` |
| Multiple **different** methods you want to fire in one round-trip (dashboard tile load) | `Batch` |
| Many calls of the same shape (bulk create / update / delete > 50 items) | `BatchByChunk` |

Then pick the API version: prefer **v3** for any method [available in v3](https://apidocs.bitrix24.com/api-reference/rest-v3/index.html) (better filtering, larger pages, server-side optimization), and **v2** for everything else. The SDK's v2 `Call.make()` even logs a warning when you call a v3-eligible method on v2 — that's your prompt to migrate.

## Per-method tradeoffs

### `Call.make()`

**Use when** you need exactly one record or one server-side operation (`update`, `add`, `delete`).

**Avoid when** you find yourself wrapping it in a `for` loop with `await` — that's the signal to switch to `Batch` or `BatchByChunk`. A loop of N `Call.make()` calls is N round-trips; `Batch` collapses up to 50 into one. `BatchByChunk` collapses any number into `ceil(N / 50)` round-trips.

### `CallList.make()`

**Use when** the result set is small enough to hold in memory and you'll do something cross-cutting on it (sort, group, aggregate, dedupe, pass to a chart library).

**Avoid when** you only need a small slice — pass `select` and `filter` to narrow the result instead of fetching everything. The method always fetches every page that matches your filter; "give me top 10" with no filter is wasteful.

### `FetchList.make()`

**Use when** the result is unbounded (or could be), and you can process records as soon as they arrive: stream them to a CSV, push them into a queue, write them to a database, send them over a WebSocket.

**Avoid when** you need cross-record aggregation that requires the whole set in memory — `CallList` is simpler. The generator yields chunks of `50` (v2) or `options.limit` up to `1000` (v3); your downstream code must handle each chunk before the next request fires, so heavy synchronous work between chunks slows the overall scan.

### `Batch.make()`

**Use when** a single user action depends on data from several different methods. A typical example is a dashboard tile that needs the user's profile, their open deals count, and their pinned tasks — three different methods, one round-trip.

**Avoid when** the same method is repeated 50+ times. That's exactly what `BatchByChunk` is for, and `Batch` will reject anything over 50 commands. Also avoid when you need named output keys *and* > 50 calls — `BatchByChunk` deliberately only accepts array-of-tuples / array-of-objects (named commands break across chunk boundaries).

### `BatchByChunk.make()`

**Use when** you have an arbitrary number of commands of the same shape — bulk migrations, mass `create` / `update` / `delete`, exporting per-id details for thousands of related records.

**Avoid when** you only have a handful of calls — `Batch` is simpler and gives you named results. Also avoid when you need transactional behavior — `BatchByChunk` is **not** atomic. If chunk 7 of 30 fails, chunks 1-6 are already applied; chunks 8-30 may or may not run depending on `isHaltOnError`.

## Limits at a glance

| Method | Max calls | Max page | Returns | Throws on first error? |
| --- | --- | --- | --- | --- |
| `Call.make()` | 1 | n/a | `AjaxResult` | No (check `isSuccess` ) |
| `CallList.make()` | unbounded (paged) | 50 (v2) / 1000 (v3) | `Result` | No |
| `FetchList.make()` | unbounded (streamed) | 50 (v2) / 1000 (v3) | `AsyncGenerator` | Yes — `SdkError` |
| `Batch.make()` | 50 | n/a | `CallBatchResult` | Configurable via `isHaltOnError` |
| `BatchByChunk.make()` | unbounded (chunked × 50) | n/a | `Result` | Configurable via `isHaltOnError` |

## Common anti-patterns

- **b24.callMethod() / b24.callBatch() / b24.callListMethod() / b24.fetchListMethod() / b24.callBatchByChunk().** Deprecated shortcuts on `AbstractB24`. They still work but emit a warning on every call and will be removed in v2.0.0. Migrate to the matching `b24.actions.v{2,3}.<primitive>.make({…})` — see the [v0 → v1 migration guide](https://bitrix24.github.io/b24jssdk/raw/docs/getting-started/migration/v1.md) for the one-to-one mapping.
- **for (const id of ids) await b24.actions.v2.call.make(...).** N IDs = N round-trips. Use `actions.v2.batch.make` if `ids.length ≤ 50`, `actions.v2.batchByChunk.make` otherwise.
- **actions.v2.callList.make → actions.v2.callList.make → actions.v2.callList.make for related entities.** This is the cause of most slow dashboards. Fetch the parent list once (`actions.v2.callList.make` or `actions.v2.fetchList.make`), then load related records via one `actions.v2.batch.make` per chunk of 50 IDs.
- **Custom order on actions.v{2,3}.callList.make / actions.v{2,3}.fetchList.make.** Cursor pagination needs `order: { idKey: 'ASC' }`. Any user-supplied `order` is stripped with a runtime warning (see [Limitations](https://bitrix24.github.io/b24jssdk/raw/docs/working-with-the-rest-api/fetch-list-rest-api-ver2.md#limitations)). Use `filter` to narrow the slice instead.
- **actions.v{2,3}.batch.make with named commands across > 50 items.** Either split manually into multiple `batch.make` calls, or switch to `actions.v{2,3}.batchByChunk.make` and accept ordered results.
- **Mixing v2 and v3 methods in one actions.v3.batch.make call.** `BatchV3` pre-validates the call list and throws `SdkError` with code `JSSDK_CORE_METHOD_NOT_SUPPORT_IN_API_V3` if any method isn't v3-supported. Split the batch by API version, or use `actions.v2.batch.make`.

## See also

- [Recipe: Export deals to CSV](https://bitrix24.github.io/b24jssdk/raw/docs/examples/dashboard-deals-csv.md) — `FetchList` for streaming export.
- [Recipe: Bulk update deals](https://bitrix24.github.io/b24jssdk/raw/docs/examples/bulk-update-deals.md) — `BatchByChunk` for mass mutation.
- [Error codes and handling](https://bitrix24.github.io/b24jssdk/raw/docs/working-with-the-rest-api/errors.md) — `SdkError`, `AjaxError`, REST-side codes.
- [Restrictions System](https://bitrix24.github.io/b24jssdk/raw/docs/working-with-the-rest-api/limiters.md) — choosing a `restrictionParams` preset for the chosen method.

## Sitemap

See the full [sitemap](/b24jssdk/sitemap.md) for all pages.
