@todo fix me!
v1.0.1
  • Get Started
  • Templates
  • GitHub
  • Overview
  • B24Hook
  • Methods
  • callMethod
  • callFastListMethod
  • fetchListMethod
  • callBatch
  • callBatchByChunk
  • getTargetOrigin
  • getTargetOriginWithPath
  • getLogger
  • setLogger
  • destroy
  • getHttpClient
  • offClientSideWarning
  • Getters
  • auth
  • isInit
  • b24ui
  • b24icons
v1.0.1
  • Docs
  • Frame
  • Hook
  • OAuth
  • Templates

B24Hook::callBatch()

Use B24Hook.callBatch() to execute batch requests to the Bitrix24 REST API. This allows you to execute up to 50 different commands in a single HTTP request, significantly increasing performance for bulk data operations. Works only in server environment.
B24Hook
TypeB24
The B24Hook object is intended exclusively for use on the server.
  • A webhook contains a secret access key, which MUST NOT be used in client-side code (browser, mobile app).
  • For the client side, use B24Frame.

Quick Overview

Use callBatch() to execute up to 50 API commands in a single request. This is especially useful when you need to retrieve or update large amounts of data while minimizing network requests and adhering to API limits.

// Basic usage
import { B24Hook, EnumCrmEntityTypeId } from '@bitrix24/b24jssdk'

const $b24 = B24Hook.fromWebhookUrl('https://your_domain.bitrix24.com/rest/1/webhook_code/')

const response = await $b24.callBatch({
  ServerTime: { method: 'server.time' },
  UserProfile: { method: 'user.current' }
})

Method Signature

callBatch(
  calls: Array<any> | Record<string, any>,
  isHaltOnError?: boolean,
  returnAjaxResult?: boolean
): Promise<Result>

Parameters

ParameterTypeRequiredDescription
callsArray<any> | Record<string, any>YesA batch of calls. Can be represented in three formats:
1. Array of arrays: [[method, params], [method, params]]
2. Array of objects: [{method, params}, {method, params}]
3. Object with named commands: {key: {method, params}, key2: [method, params]}
isHaltOnErrorbooleanNoHalt on error. The default is true, then execution of the batch is halted if an error occurs in any of the commands. If false - commands are executed even if some fail.
returnAjaxResultbooleanNoReturn value format. If true, the method returns a Result object containing either a Record<string | number, AjaxResult> or an AjaxResult[] (depending on the calls format). The default is false - object containing the complete array of retrieved data.

Return Value

Promise<Result> — a promise that resolves to a Result object. This object provides:

  • .getData() — returns response data. The structure depends on the call parameters.
  • .isSuccess: boolean — a flag indicating the successful completion of the request.
  • .getErrorMessages(): string[] — an array of error messages.

Key Concepts

Batch Request Formats

  1. Object with named commands:
    {
      deals: { method: 'crm.item.list', params: { entityTypeId: EnumCrmEntityTypeId.deal, select: ['id'] } },
      contacts: ['crm.item.list', { entityTypeId: EnumCrmEntityTypeId.contact, select: ['id'] }]
    }
    

    When returnAjaxResult: true, Record<string, AjaxResult> is returned.
  2. Array of arrays:
    [
      ['crm.item.list', { entityTypeId: EnumCrmEntityTypeId.deal, select: ['id']'] }],
      ['crm.item.list', { entityTypeId: EnumCrmEntityTypeId.contact, select: ['id'] }]
    ]
    

    When returnAjaxResult: true, AjaxResult[] is returned.
  3. Array of objects:
    [
      { method: 'crm.item.list', params: { entityTypeId: EnumCrmEntityTypeId.deal, select: ['id']'] } },
      { method: 'crm.item.list', params: { entityTypeId: EnumCrmEntityTypeId.contact, select: ['id']'] } }
    ]
    

    When returnAjaxResult: true, AjaxResult[] is returned.

Links between teams

In batch queries, you can use the results of one command as parameters for another using a special syntax:

await $b24.callBatch({
  FirstDeal: {
    method: 'crm.item.list',
    params: { entityTypeId: EnumCrmEntityTypeId.deal, order: { id: 'desc' }, select: ['id'] }
  },
  DealTasks: {
    method: 'tasks.task.list',
    params: {
      filter: {
        UF_CRM_TASK: 'D_$result[FirstDeal][items][0][id]' // Link to the result of the first command
      }
    }
  }
})

Important Limitations

  • Maximum 50 commands in a single batch request.
  • Total execution time must not exceed Bitrix24 limits (usually 30-60 seconds).
  • API Limits: A batch request is counted as a single API request, but each command within it counts toward the overall operation limits.
  • Execution Order: Commands in a batch are executed sequentially in the order they are specified.

Error Handling

Always check the result using isSuccess and handle errors.

const response: Result<Record<string, AjaxResult>> = await $b24.callBatch({
  ServerTime: { method: 'server.time' }
}, true) // isHaltOnError = true

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

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

Examples

Batch request in object format

BatchObject.ts
import type { Result } from '@bitrix24/b24jssdk'
import { B24Hook, EnumCrmEntityTypeId, LoggerFactory } from '@bitrix24/b24jssdk'

type BatchResponse = {
  CompanyList?: { items: Record<string, any> }
  ContactList?: { items: Record<string, any> }
}

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

try {
  const response = await $b24.callBatch<BatchResponse>(
    {
      CompanyList: {
        method: 'crm.item.list',
        params: {
          entityTypeId: EnumCrmEntityTypeId.company,
          order: { id: 'desc' },
          select: ['id', 'title', 'createdTime']
        }
      },
      ContactList: {
        method: 'crm.item.list',
        params: {
          entityTypeId: EnumCrmEntityTypeId.contact,
          order: { id: 'desc' },
          select: ['id', 'name', 'lastName', 'createdTime']
        }
      }
    },
    { isHaltOnError: true }
  ) as Result<BatchResponse>

  if (!response.isSuccess) {
    throw new Error(`API Error: ${response.getErrorMessages().join('; ')}`)
  }

  const data = response.getData()!
  const dataCompanyList = (data.CompanyList?.items || []).map((item: any) => ({
    id: Number(item.id),
    title: item.title,
    createdTime: new Date(item.createdTime)
  }))

  const dataContactList = (data.ContactList?.items || []).map((item: any) => ({
    id: Number(item.id),
    name: item.name,
    lastName: item.lastName,
    createdTime: new Date(item.createdTime)
  }))

  $logger.info('response', {
    dataCompanyList,
    dataContactList
  })
} catch (error) {
  $logger.error('some error', { error })
}

Using returnAjaxResult for fine-grained control

BatchWithAjaxResult.ts
import type { AjaxResult, Result } from '@bitrix24/b24jssdk'
import { B24Hook, EnumCrmEntityTypeId, LoggerFactory } from '@bitrix24/b24jssdk'

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

try {
  // `return AjaxResult = true` returns an AjaxResult for each command
  const response = await $b24.callBatch(
    {
      ServerTime: { method: 'server.time' },
      UserProfile: { method: 'user.current' },
      DealCount: { method: 'crm.item.list', params: { entityTypeId: EnumCrmEntityTypeId.deal, select: ['id'] } }
    },
    { isHaltOnError: false, returnAjaxResult: true }
  ) as Result<Record<string, AjaxResult>>

  if (!response.isSuccess) {
    throw new Error(`API Error: ${response.getErrorMessages().join('; ')}`)
  }

  const data = response.getData()!

  // We check each command separately
  if (data.ServerTime?.isSuccess) {
    $logger.info('Server time:', data.ServerTime.getData().result)
  }

  if (data.UserProfile?.isSuccess) {
    $logger.info('Current user', {
      name: (data.UserProfile.getData().result as unknown as { NAME: string }).NAME
    })
  }

  if (data.DealCount?.isSuccess) {
    $logger.info(`Total deals`, {
      total: data.DealCount?.getTotal()
    })
  }
} catch (error) {
  $logger.error('some error', { error })
}

Combined package with links between commands

BatchWithReferences.ts
import type { Result } from '@bitrix24/b24jssdk'
import { B24Hook, EnumCrmEntityTypeId, LoggerFactory } from '@bitrix24/b24jssdk'

type BatchResponse = {
  Deal?: { item: Record<string, any> }
  DealContact?: { item: Record<string, any> }
  ContactTasks?: { tasks: Record<string, any> }
}

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

const dealId = 1

try {
  const response = await $b24.callBatch(
    {
      // 1. We receive a transaction by ID
      Deal: {
        method: 'crm.item.get',
        params: {
          entityTypeId: EnumCrmEntityTypeId.deal,
          id: dealId
        }
      },

      // 2. We get the contact from the deal (using the result of the first command)
      DealContact: {
        method: 'crm.item.get',
        params: {
          entityTypeId: EnumCrmEntityTypeId.contact,
          id: '$result[Deal][item][contactId]'
        }
      },

      // 3. We receive the last 50 tasks for this contact.
      ContactTasks: {
        method: 'tasks.task.list',
        params: {
          filter: {
            UF_CRM_TASK: 'C_$result[DealContact][item][id]'
          },
          select: ['ID', 'TITLE', 'DEADLINE'],
          order: { ID: 'DESC' }
        }
      }
    },
    { isHaltOnError: true }
  ) as Result<BatchResponse>

  if (!response.isSuccess) {
    throw new Error(`API Error: ${response.getErrorMessages().join('; ')}`)
  }

  const data = response.getData()!
  $logger.info('response', {
    Deal: data.Deal?.item,
    Contact: data.DealContact?.item,
    Tasks: data.ContactTasks?.tasks || []
  })
} catch (error) {
  $logger.error('some error', { error })
}

Alternatives and Recommendations

  • To get the entire list in memory: Use callFastListMethod, which returns the entire array of data.
  • For step-by-step streaming processing of very large lists: Use fetchListMethod. Returns an async generator that yields data page by page, allowing processing to start before the entire list is loaded and saving memory.
  • When you need the total item count: Use the regular callMethod with manual pagination, as callFastListMethod does not count the total.
  • To run more commands (more than 50): Use callBatchByChunk, which automatically splits commands into chunks of 50.
  • On the client (browser): Use the built-in B24Frame object instead of B24Hook.

References

  • AjaxResult — Documentation for the result object.
  • Result — Documentation for the result object.
  • Official Bitrix24 REST API Documentation — Reference for all available methods.
  • Working with Large Volumes of Data — Recommendations for optimizing code to retrieve large data.

fetchListMethod

Use `B24Hook.fetchListMethod()` for step-by-step stream processing of very large data lists. It returns an asynchronous generator that fetches data page by page, allowing processing to begin before the entire list has finished loading and conserving memory. It doesn

callBatchByChunk

Use `B24Hook.callBatchByChunk()` to execute batch requests to the Bitrix24 REST API with any number of commands. The method automatically splits a large list of commands into chunks of 50 commands each (the maximum size of a single batch in Bitrix24) and executes them sequentially. Works only in a server environment.

On this page

  • Quick Overview
  • Method Signature
    • Parameters
    • Return Value
  • Key Concepts
    • Batch Request Formats
    • Links between teams
    • Important Limitations
    • Error Handling
  • Examples
    • Batch request in object format
    • Using returnAjaxResult for fine-grained control
    • Combined package with links between commands
  • Alternatives and Recommendations
  • References
Releases
Published under MIT License.

Copyright © 2024-present Bitrix24