v3.0.0

UMD

Guide for using UMD version Bitrix24 JS SDK in you applications.

Add to your project

Include the library

You can include the library directly via CDN. Add the following <script> tag to your HTML file:

<script src="https://unpkg.com/@bitrix24/b24jssdk@3/dist/umd/index.min.js"></script>
Pin the major version, never @latest. A <script> tag has no lockfile, so @latest moves your app to a new major the moment it is published — with its breaking changes and no compiler to point at them. When 3.0.0 came out, embeds that loaded @latest broke on the removed B24Js.LoggerBrowser (#586). @3 still receives every 3.x fix. To stay on the 2.x line while you migrate, load @2 instead, and see Migration to v3.

If necessary, download the UMD version of the library from unpkg.com and add it to your project.

Then include it in your HTML file:

<script src="/path/to/umd/index.min.js"></script>
The UMD bundle inlines its dependencies (axios, luxon, qs-esm) so it can run from a single <script> with no module resolution. That means npm audit in your project does not see those bundled copies — a future advisory in, say, axios is only picked up once a new SDK release ships an updated bundle. For dependency auditing and deduplication, prefer the ESM / CommonJS entries (import / require), which keep these dependencies external. Use UMD only for direct browser <script> / CDN usage.

Import

After including, the library will be available through the global variable B24Js.

B24Js.LoggerFactory.createForBrowser('B24/jsSdk::umd', true);

Init

To work with Bitrix24 from the application built into the Bitrix24 interface use the B24Frame object.

It is initialized on the client side using initializeB24Frame().

const logger = B24Js.LoggerFactory.createForBrowser('B24/jsSdk::umd', true);

try {
  // Initialize B24Frame instance
  let b24 = await B24Js.initializeB24Frame();
  
} catch (error) {
  logger.error('Some problems', { error })
}

Examples

B24Frame client-side

Here's a simple example demonstrating how to get a list of records — companies under restApi:v2, tasks under restApi:v3, since crm.* is v2-only.

The code is expected to run in the Bitrix24 user interface.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Bitrix24 JS SDK Demo</title>
</head>
<body>
<h1>Company Loader Example</h1>
<p>Check developer console for results</p>

<script src="https://unpkg.com/@bitrix24/b24jssdk@3/dist/umd/index.min.js"></script>
<script>
  // Create logger
  const logger = B24Js.LoggerFactory.createForBrowser('B24/jsSdk::umd', true);

  /**
   * Load company list
   */
  async function loadCompanies(b24) {
    try {
      logger.debug('Loading companies...');

      const response = await b24.actions.v2.call.make({
        method: 'crm.item.list',
        params: {
          entityTypeId: B24Js.EnumCrmEntityTypeId.company,
          order: { id: 'desc' },
          select: ['id', 'title', 'createdTime']
        }
      });

      const data = response.getData().result;

      const companies = (data?.items || []).map((item) => {
        return {
          id: Number.parseInt(item.id),
          title: item.title,
          createdTime: B24Js.Text.toDateTime(item.createdTime) // @memo this is luxon/DateTime
        };
      });

      logger.debug('Companies loaded successfully', { companies });
      return companies;
    } catch (error) {
      logger.error('Request failed', { error });
      throw error;
    }
  }

  /**
   * Main application function
   */
  async function main() {
    try {
      // Initialize B24Frame instance
      let b24 = await B24Js.initializeB24Frame();

      // Load companies
      const companies = await loadCompanies(b24);

      // Further data processing...
      logger.info('Loaded ' + companies.length + ' companies');
    } catch (error) {
      logger.error('Some problems', { error })
    }
  }

  /// Start application after DOM load
  document.addEventListener('DOMContentLoaded', function() {
    main();
  });
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Bitrix24 JS SDK Demo</title>
</head>
<body>
<h1>Task Loader Example</h1>
<p>Check developer console for results</p>

<script src="https://unpkg.com/@bitrix24/b24jssdk@3/dist/umd/index.min.js"></script>
<script>
  // Create logger
  const logger = B24Js.LoggerFactory.createForBrowser('B24/jsSdk::umd', true);

  /**
   * Load task list
   */
  async function loadTasks(b24) {
    try {
      logger.debug('Loading tasks...');

      const response = await b24.actions.v3.call.make({
        method: 'tasks.task.list',
        params: {
          select: ['id', 'title', 'created']
        }
      });

      const data = response.getData().result;

      const tasks = (data?.items || []).map((item) => {
        return {
          id: Number.parseInt(item.id),
          title: item.title,
          created: B24Js.Text.toDateTime(item.created) // @memo this is luxon/DateTime
        };
      });

      logger.debug('Tasks loaded successfully', { tasks });
      return tasks;
    } catch (error) {
      logger.error('Request failed', { error });
      throw error;
    }
  }

  /**
   * Main application function
   */
  async function main() {
    try {
      // Initialize B24Frame instance
      let b24 = await B24Js.initializeB24Frame();

      // Load tasks
      const tasks = await loadTasks(b24);

      // Further data processing...
      logger.info('Loaded ' + tasks.length + ' tasks');
    } catch (error) {
      logger.error('Some problems', { error })
    }
  }

  /// Start application after DOM load
  document.addEventListener('DOMContentLoaded', function() {
    main();
  });
</script>
</body>
</html>

Current user and placement client-side

A minimal frame page that shows who opened the application and where it is embedded. The placement data arrives with the frame's init data, so it needs no request; the user comes from the user.current REST method.

The code is expected to run in the Bitrix24 user interface — in the application slider or a registered placement. user.current needs the user_brief scope (user or user_basic also work); without it the call fails with insufficient_scope. If the user ID and the admin flag are enough, the profile method needs only the basic scope.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>B24 UMD: user and placement</title>
</head>
<body>
<pre id="out">Loading…</pre>

<script src="https://unpkg.com/@bitrix24/b24jssdk@3/dist/umd/index.min.js"></script>
<script>
  const logger = B24Js.LoggerFactory.createForBrowser('umd-demo', true);
  const out = document.getElementById('out');

  async function main() {
    // 1. Initialize the frame
    const b24 = await B24Js.initializeB24Frame();
    b24.setLogger(B24Js.LoggerFactory.createForBrowser('Core'));

    // 2. Placement: delivered with the init data, no request needed
    const placement = {
      code: b24.placement.placement,        // 'DEFAULT', 'CRM_DEAL_DETAIL_TAB', ...
      isDefault: b24.placement.isDefault,
      isSliderMode: b24.placement.isSliderMode,
      options: b24.placement.options        // PLACEMENT_OPTIONS, e.g. { ID: '123' } on a CRM card
    };

    // 3. Current user: the user.current REST method
    const response = await b24.actions.v2.call.make({ method: 'user.current', params: {} });
    if (!response.isSuccess) {
      throw new Error(response.getErrorMessages().join('; '));
    }
    const u = response.getData().result;

    const info = {
      portal: b24.getTargetOrigin(),
      lang: b24.getLang(),
      isAdmin: b24.auth.isAdmin,
      user: { id: Number(u.ID), name: u.NAME, lastName: u.LAST_NAME, email: u.EMAIL },
      placement
    };

    logger.info('Frame info', info);
    out.textContent = JSON.stringify(info, null, 2);
  }

  document.addEventListener('DOMContentLoaded', () => {
    main().catch((error) => {
      logger.error('Init failed', { error });
      out.textContent = 'Error: ' + (error?.message || error);
    });
  });
</script>
</body>
</html>

b24.placement.options is always an object. Its key case is the portal's choice, so read a value by checking it rather than assuming a key — see Placement. Tokens are available through b24.auth.getAuthData(); the example deliberately does not print them.