@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.callMethod()

The primary method for executing Bitrix24 REST API calls via webhook. Allows calling any REST API method with specified parameters. Works only in a server environment. 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 callMethod for direct REST API calls. The method returns a Promise with an AjaxResult object containing the response data, status, and methods for error handling and pagination.

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

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

const response = await $b24.callMethod('method.api', {parameters})

Method Signature

callMethod<T = unknown>(
  method: string,
  params?: object
): Promise<AjaxResult<T>>

Parameters

ParameterTypeRequiredDescription
methodstringYesName of the REST API method to call (e.g. crm.item.get).
paramsobjectNoObject with parameters to pass to the API method.

Return Value

Promise<AjaxResult<T>> — a promise that resolves to an AjaxResult object.

This object provides:

  • .getData(): Payload<T> — returns the full API response.
  • .isSuccess: boolean — flag indicating successful request execution.
  • .getErrorMessages(): string[] — array of error messages.
  • .isMore(): boolean — indicates if more data is available during pagination.

Key Concepts

Pagination

API methods that return lists use pagination.

  • Fixed page size: 50 records.
  • Offset management: The params.start parameter sets the offset.
    • params.start: 0 — first page (records 1-50).
    • params.start: 50 — second page (records 51-100).
    • Formula: params.start = (Page_Number - 1) * 50.
  • Retrieving all data without pagination: Set params.start: -1 for efficient export of large data volumes. This disables the total count calculation, significantly speeding up the process.
    • We will still receive 50 records per request.
    • The idea is to change the filter condition on the ID field ('>id': lastId) and continue calling the request until an empty response is received.

Error Handling

Always check the result using isSuccess and handle errors.

const response = await $b24.callMethod('some.method')

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

Getting a CRM Item

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

type CrmItem = {
  id: number
  title: string
  [key: string]: any
}

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

async function getCrmItem(entityTypeId: number, itemId: number): Promise<CrmItem> {
  const response: AjaxResult<{ item: CrmItem }> = await $b24.callMethod('crm.item.get', {
    entityTypeId: entityTypeId,
    id: itemId
  })

  if (!response.isSuccess) {
    throw new Error(`Failed to fetch item: ${response.getErrorMessages().join('; ')}`)
  }

  return response.getData().result.item
}

// Use for the company
try {
  const company = await getCrmItem(EnumCrmEntityTypeId.company, 5284)
  $logger.info(`Company: ${company?.title}`, { company })
} catch (error) {
  $logger.error('some error', { error })
}

Getting a Single User

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

type User = {
  ID: number
  NAME: string
}

const devMode = typeof import.meta !== 'undefined' && (globalThis._importMeta_.env?.DEV || false)
const $logger = LoggerFactory.createForBrowser('Example:getUser', devMode)
const $b24 = B24Hook.fromWebhookUrl('https://your_domain.bitrix24.com/rest/1/webhook_code/')
async function getUser(id: number): Promise<User | null> {
  const response: AjaxResult<User[]> = await $b24.callMethod('user.get', { ID: id })

  if (!response.isSuccess) {
    throw new Error(`Failed to get user: ${response.getErrorMessages().join('; ')}`)
  }

  const users = response.getData().result
  return users.length > 0 ? users[0] : null
}

// Usage
try {
  const user = await getUser(1)
  $logger.info(`User: ${user?.NAME}`, { user })
} catch (error) {
  $logger.error('some error', { error })
}

Getting a Single Task

@todo off preview

import { B24Hook, LoggerFactory, AjaxError } from '@bitrix24/b24jssdk'

type Task = {
  id: number
  title: string
}

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

const loggerForDebugB24 = LoggerFactory.createForBrowser('b24', false)
$b24.setLogger(loggerForDebugB24)

async function getTask(id: number, requestId: string): Promise<Task | null> {
  // We can use $b24.callV3() or $b24.callMethod()
  const response = await $b24.callMethod<{ item: Task }>(
    'tasks.task.get',
    {
      id,
      select: ['id', 'title']
    },
    requestId
  )

  if (!response.isSuccess) {
    throw new Error(`Failed to get task: ${response.getErrorMessages().join('; ')}`)
  }

  return response.getData().result.item
}

// Usage
const requestId = 'test-task-v3'
try {
  const task = await getTask(2, requestId)
  $logger.info(`Task: ${task?.title}`, {
    requestId,
    task
  })
} catch (error) {
  if (error instanceof AjaxError) {
    $logger.critical(error.message, {
      requestId,
      code: error.code
    })
  } else {
    $logger.alert('some error', {
      requestId,
      error
    })
  }
}
import { B24Hook, LoggerFactory } from '@bitrix24/b24jssdk'

type Task = {
  ID: number
  TITLE: string
}

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

const loggerForDebugB24 = LoggerFactory.createForBrowser('b24', false)
$b24.setLogger(loggerForDebugB24)

async function getTask(id: number, requestId: string): Promise<Task | null> {
  const response = await $b24.callV2<{ item: Task }>(
    'tasks.task.get',
    {
      taskId: id,
      select: ['ID', 'TITLE']
    },
    requestId
  )

  if (!response.isSuccess) {
    throw new Error(`Failed to get task: ${response.getErrorMessages().join('; ')}`)
  }

  return response.getData().result.item
}

// Usage
const requestId = 'test-task-v2'
try {
  const task = await getTask(2, requestId)
  $logger.info(`Task: ${task?.TITLE}`, {
    requestId,
    task
  })
} catch (error) {
  $logger.alert('some error', {
    requestId,
    error
  })
}

Getting All Data with Pagination

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

type Deal = {
  id: number
  title: string
}

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

async function getAllDeals(): Promise<Deal[]> {
  let allDeals: Deal[] = []
  let start = 0
  let hasMore = true

  while (hasMore) {
    const response: AjaxResult<{ items: Deal[] }> = await $b24.callMethod(
      'crm.item.list',
      {
        entityTypeId: EnumCrmEntityTypeId.deal,
        filter: {
          // use some filter by title
          '=%title': 'Automatic%'
        },
        order: { id: 'asc' },
        select: ['id', 'title'],
        start
      }
    )

    if (!response.isSuccess) {
      throw new Error(`Failed to fetch deals: ${response.getErrorMessages().join('; ')}`)
    }

    const pageDeals = response.getData().result.items
    allDeals = allDeals.concat(pageDeals)

    // Check if there is more data
    hasMore = response.isMore()
    start += Number((response.getData() as ListPayload<Deal[]>).next) // Increase the offset for the next page
  }

  return allDeals
}

// Usage
try {
  const list = await getAllDeals()
  $logger.info(`Deals list (${list.length})`, { list })
} catch (error) {
  $logger.error('some error', { error })
}

Efficient Export of All Data

No Pagination, start=-1

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

type Company = {
  id: number
  title: string
}

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

async function getAllCompaniesFast(): Promise<Company[]> {
  let allCompanies: Company[] = []
  let lastId = 0
  let batch: Company[]

  do {
    const response: AjaxResult<{ items: Company[] }> = await $b24.callMethod(
      'crm.item.list',
      {
        entityTypeId: EnumCrmEntityTypeId.company,
        filter: {
          '>id': lastId, // Important filter: select data by ID
          // use some filter by title
          '=%title': 'Prime%'
        },
        order: { id: 'asc' },
        select: ['id', 'title'],
        start: -1 // Important parameter: disable pagination and counting
      }
    )

    if (!response.isSuccess) {
      throw new Error(`Failed to fetch Companies: ${response.getErrorMessages().join('; ')}`)
    }

    batch = response.getData().result.items
    if (batch.length > 0) {
      allCompanies = allCompanies.concat(batch)
      lastId = Number(batch[batch.length - 1]!.id) // Update the last ID for the filter
    }
  } while (batch.length > 0) // We query until we get an empty batch

  return allCompanies
}

// Usage
try {
  const list = await getAllCompaniesFast()
  $logger.info(`Companies list (${list.length})`, { list })
} catch (error) {
  $logger.error('some error', { error })
}
The same result can be obtained using the callFastListMethod method.

Alternatives and Recommendations

  • For working with lists: Instead of manually managing pagination in callMethod, use:
    • callFastListMethod — automatically retrieves all pages and returns a single result.
    • fetchListMethod — returns an async generator for step-by-step processing of large lists.
  • For batch operations: Use callBatch to execute up to 50 commands in a single request.
  • On the client (browser): Use the built-in B24Frame object instead of B24Hook.

References

  • AjaxResult — 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.

B24Hook

Class for secure interaction with the Bitrix24 REST API from server-side code. Contains methods for creating authorized requests via webhooks. Works only in server environment.

callFastListMethod

Use `B24Hook.callFastListMethod()` to quickly fetch all list items from the Bitrix24 REST API. The method automatically performs all necessary requests to retrieve the complete dataset using an optimized approach that does not count the total number of items, significantly speeding up the process when working with large data volumes. Works only in server environment.

On this page

  • Quick Overview
  • Method Signature
    • Parameters
    • Return Value
  • Key Concepts
    • Pagination
    • Error Handling
  • Examples
    • Getting a CRM Item
    • Getting a Single User
    • Getting a Single Task
    • Getting All Data with Pagination
    • Efficient Export of All Data
  • Alternatives and Recommendations
  • References
Releases
Published under MIT License.

Copyright © 2024-present Bitrix24