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:
- One call or many? A single REST method or several at once.
- Bounded or unbounded? Do you know up front there are ≤ 50 results, or could there be 50 000?
- All-at-once or stream? Need every record in memory for aggregation, or process them as they arrive?
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 for one-to-one rewrites.Decision matrix
Then pick the API version: prefer v3 for any method available in v3 (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
Common anti-patterns
b24.callMethod()/b24.callBatch()/b24.callListMethod()/b24.fetchListMethod()/b24.callBatchByChunk(). Deprecated shortcuts onAbstractB24. They still work but emit a warning on every call and will be removed in v2.0.0. Migrate to the matchingb24.actions.v{2,3}.<primitive>.make({…})— see the v0 → v1 migration guide for the one-to-one mapping.for (const id of ids) await b24.actions.v2.call.make(...). N IDs = N round-trips. Useactions.v2.batch.makeifids.length ≤ 50,actions.v2.batchByChunk.makeotherwise.actions.v2.callList.make → actions.v2.callList.make → actions.v2.callList.makefor related entities. This is the cause of most slow dashboards. Fetch the parent list once (actions.v2.callList.makeoractions.v2.fetchList.make), then load related records via oneactions.v2.batch.makeper chunk of 50 IDs.- Custom
orderonactions.v{2,3}.callList.make/actions.v{2,3}.fetchList.make. Cursor pagination needsorder: { idKey: 'ASC' }. Any user-suppliedorderis stripped with a runtime warning (see Limitations). Usefilterto narrow the slice instead. actions.v{2,3}.batch.makewith named commands across > 50 items. Either split manually into multiplebatch.makecalls, or switch toactions.v{2,3}.batchByChunk.makeand accept ordered results.- Mixing v2 and v3 methods in one
actions.v3.batch.makecall.BatchV3pre-validates the call list and throwsSdkErrorwith codeJSSDK_CORE_METHOD_NOT_SUPPORT_IN_API_V3if any method isn't v3-supported. Split the batch by API version, or useactions.v2.batch.make.
See also
- Recipe: Export deals to CSV —
FetchListfor streaming export. - Recipe: Bulk update deals —
BatchByChunkfor mass mutation. - Error codes and handling —
SdkError,AjaxError, REST-side codes. - Restrictions System — choosing a
restrictionParamspreset for the chosen method.