v1.3.0

CallListV3.make

Method for quickly retrieving all data from list methods of Bitrix24 REST API version 3.
It's important to note that REST API version 3 allows you to retrieve up to 1000 elements in a single request using the pagination parameter: { limit: 1000, page: 1 }.

Overview

When you need to retrieve all records from list methods of REST API version 3 with maximum efficiency and are ready to store the complete dataset in memory, use CallListV3.make().

This method automatically handles pagination and returns all data in a single array.

For importing, exporting, processing all elements and generating reports, we recommend using FetchList - it returns an asynchronous generator for step-by-step processing of large lists.
// Basic usage
const response = await $b24.actions.v3.callList.make({
  method: 'main.eventlog.list',
  params: {
    filter: [
      ['userId', '=', 1]
    ],
    select: ['id', 'userId']
  },
  idKey: 'id',
  customKeyForResult: 'items',
  requestId: 'unique-request-id',
  limit: 600
})

When to Use CallListV3.make()

  1. Small to medium data volumes: When the total number of records does not exceed several thousand.
  2. Simple processing: When you need simple access to all data at once.

Method Signature

make<T = unknown>(
  options: ActionCallListV3
): Promise<Result<T[]>>

Parameters

The options object contains the following properties:

ParameterTypeRequiredDescription
methodstringYesREST API method name that returns a data list (e.g., crm.contact.list, tasks.task.list).
paramsOmit<TypeCallParams, 'pagination' | 'order'>NoRequest parameters, excluding the pagination and order parameters. The pagination parameter is reserved because the method retrieves all data in a single call. The order parameter is reserved because cursor-based pagination requires sorting strictly by cursorIdKey (which defaults to idKey) ascending — see Limitations. Use filter and select to control the selection.
idKeystringNoName of the id field as it appears in each response item; its value drives the cursor. Default: 'id'. Set it to match the id field the method returns.
cursorIdKeystringNoField name used in the request for order and the [field, '>', n] page filter. Defaults to idKey. Set it only when the sortable / filterable field name differs from the response field name (e.g. an uppercase request field but a lowercase response id): pass idKey: 'id', cursorIdKey: 'ID'.
customKeyForResultstringYesCustom key indicating that the REST API response will be selected by this field. For example: items for a list of CRM elements.
requestIdstringNoUnique request identifier for tracking. Used for request deduplication and debugging.
limitnumberNoHow many records to retrieve at a time. Default is 50. Maximum is 1000.

Return Value

Promise<Result<T[]>> — a promise that resolves to a Result<T[]> object containing an array of all retrieved elements.

This object provides:

  • .getData(): T[] — returns an array of all retrieved elements.
  • .isSuccess: boolean — flag indicating successful execution of all requests.
  • .getErrorMessages(): string[] — array of error messages.

Key Concepts

Performance Optimization

The method implements the Bitrix24 recommended algorithm for efficient work with large data volumes:

  1. Filtering by increasing id: Each subsequent query uses a [cursorIdKey, '>', id] filter with the id of the last retrieved element (read via idKey).
  2. Automatic data end detection: Requests stop when an empty array is received, or when a page is shorter than the largest page seen so far. This keys the stop on the page size the server actually returns rather than the requested options.limit, so a method that silently caps the page below limit (e.g. tasks.task.list, fixed at 50) still pages through every record instead of stopping after the first capped page.

REST API v3 Response Structure

The customKeyForResult parameter is retained for backward compatibility. In the future, after analyzing real usage, a decision will be made regarding its necessity.

In REST API version 3, various methods return data in the same structures:

  • Grouped array: { result: { items: [...] } }

The customKeyForResult parameter allows you to specify the key where the data is located in the response.

Some v3 list methods (e.g. note.*) also return a nextCursor field in the response envelope alongside items{ result: { nextCursor, items: [...] } }. You do not need to read or pass it: CallListV3.make() paginates with its own idKey cursor (the injected [idField, '>', n] filter) and walks every page regardless of nextCursor. The field is informational; the SDK ignores it.

Limitations

  • Page size: Bitrix24 REST API version 3 limitation — maximum 1000 records per request.
  • Sorting is fixed: The method always sorts by cursorIdKey (which defaults to idKey) ascending, because cursor pagination relies on [cursorIdKey, '>', nextId] filters to walk the dataset. A user-supplied order value would break that invariant, so the type signature excludes order and any value passed at runtime is stripped with a warning log entry. To narrow the result set, use filter instead.
  • Only for list methods: Intended only for methods that return data arrays.

Error Handling

Always check the result using isSuccess and handle errors:

// @check-ignore: top-level return in error-handling illustration

const response = await $b24.actions.v3.callList.make({
  method: 'some.method',
  params: { /* some_params */ },
  idKey: 'id',
  customKeyForResult: 'items',
  requestId: 'unique-request-id',
  limit: 600
})

if (!response.isSuccess) {
  // Handling error
  console.error(new Error(`Error: ${response.getErrorMessages().join('; ')}`))
  return
}

// Working with a successful result
const data = response.getData()

Examples

Getting all Event Log Items with filtering

AllMainEventLogItems.ts
import { B24Hook, LoggerFactory, Text, SdkError, AjaxError } from '@bitrix24/b24jssdk'

type MainEventLogItem = {
  id: number
  userId: number
}

const devMode = !!(typeof import.meta !== 'undefined' && (import.meta.dev || import.meta.env?.DEV))
const $logger = LoggerFactory.createForBrowser('Example:AllMainEventLogItems', devMode)
const $b24 = B24Hook.fromWebhookUrl('https://your_domain.bitrix24.com/rest/1/webhook_code/')

async function getMainEventLogItemList(requestId: string): Promise<MainEventLogItem[]> {
  const sixMonthAgo = new Date()
  sixMonthAgo.setMonth((new Date()).getMonth() - 6)
  sixMonthAgo.setHours(0, 0, 0)

  const response = await $b24.actions.v3.callList.make<MainEventLogItem>({
    method: 'main.eventlog.list',
    params: {
      filter: [
        ['timestampX', '>=', Text.toB24Format(sixMonthAgo)] // created at least 6 months ago
      ],
      select: ['id', 'userId']
    },
    idKey: 'id',
    customKeyForResult: 'items',
    requestId,
    limit: 60
  })

  if (!response.isSuccess) {
    throw new SdkError({
      code: 'MY_APP_GET_PROBLEM',
      description: `Problem ${response.getErrorMessages().join('; ')}`,
      status: 404
    })
  }

  return response.getData() ?? []
}

// Usage
const requestId = 'some-main-event-log-item-list'
try {
  const list = await getMainEventLogItemList(requestId)
  $logger.info(`List [${list?.length}]`, { requestId, list })
} catch (error) {
  if (error instanceof AjaxError) {
    $logger.critical(error.message, { requestId, code: error.code })
  } else {
    $logger.alert('Problem', { requestId, error })
  }
}

When the request and response id fields differ

Some methods sort / filter by one field name but return another (for example an uppercase ID in the request vs a lowercase id in the payload). Set idKey to the response field and cursorIdKey to the request field:

const response = await $b24.actions.v3.callList.make({
  method: 'some.list',
  params: { select: ['ID', 'TITLE'] },
  idKey: 'id', // read the id from each returned item
  cursorIdKey: 'ID', // order + ["ID", ">", n] page filter in the request
  customKeyForResult: 'items'
})

If idKey can't be read from a full page, the SDK logs a warning and stops paginating instead of silently truncating.

Alternatives and Recommendations

  • For working with lists: Instead of manually managing pagination use:
    • FetchList — returns an async generator for step-by-step processing of large lists.
  • For batch operations: Use Batch to execute up to 50 commands in a single request.
  • On the client-side (browser): Use the built-in B24Frame object.