@bitrix24/b24jssdk
Version:
Bitrix24 REST API JavaScript SDK
7,449 lines • 273 kB
text/typescript
import { Writable } from 'node:stream';
import { DateTimeOptions, DateTime } from 'luxon';
import { AxiosInstance, AxiosError } from 'axios';
/**
* Log levels in ascending order of severity.
*
* Levels allow filtering messages: when a specific level is set,
* messages of that level and all higher levels will be logged.
*/
declare enum LogLevel {
/**
* Detailed debug information for developers.
* Default level in development environment.
*/
DEBUG = 0,
/**
* Informational messages about normal application operation.
* Used for tracking business logic.
*/
INFO = 1,
/**
* Important but non-critical events.
* Examples: successful request processing, configuration changes.
*/
NOTICE = 2,
/**
* Warnings about potential problems.
* Application continues to run but attention is required.
*/
WARNING = 3,
/**
* Runtime errors requiring intervention.
* Some functionality is unavailable but the application is running.
*/
ERROR = 4,
/**
* Critical errors disrupting component operation.
* Require immediate intervention during working hours.
*/
CRITICAL = 5,
/**
* Serious problems requiring immediate resolution.
* Examples: database unavailable, disk space exhausted.
*/
ALERT = 6,
/**
* System is unusable, requires urgent intervention.
* Highest severity level.
*/
EMERGENCY = 7
}
type LogLevelName = keyof typeof LogLevel;
interface LogRecord {
channel: string;
level: LogLevel;
levelName: LogLevelName;
message: string;
context: Record<string, any>;
extra: Record<string, any>;
timestamp: Date;
}
interface Formatter {
format(record: LogRecord): any;
}
interface HandlerOptions {
bubble?: boolean;
[key: string]: any;
}
interface Handler {
/**
* Handles a log record.
*
* @param {LogRecord} record - Log record to handle.
* @returns {boolean}
*/
handle(record: LogRecord): Promise<boolean>;
isHandling(level: LogLevel): boolean;
shouldBubble(): boolean;
setFormatter(formatter: Formatter): void;
getFormatter(): Formatter | null;
}
type Processor = (record: LogRecord) => LogRecord;
interface LoggerInterface {
/**
* Logs with an arbitrary level.
*/
log(level: LogLevel, message: string, context?: Record<string, any>): Promise<void>;
/**
* Detailed debug information.
*/
debug(message: string, context?: Record<string, any>): Promise<void>;
/**
* Interesting events.
*
* Example: User logs in, SQL logs.
*/
info(message: string, context?: Record<string, any>): Promise<void>;
/**
* Normal but significant events.
*/
notice(message: string, context?: Record<string, any>): Promise<void>;
/**
* Exceptional occurrences that are not errors.
*
* Example: Use of deprecated APIs, poor use of an API, undesirable things
* that are not necessarily wrong.
*/
warning(message: string, context?: Record<string, any>): Promise<void>;
/**
* Runtime errors that do not require immediate action but should typically
* be logged and monitored.
*/
error(message: string, context?: Record<string, any>): Promise<void>;
/**
* Critical conditions
*
* Example: Application component unavailable, unexpected exception
*/
critical(message: string, context?: Record<string, any>): Promise<void>;
/**
* Action must be taken immediately.
*
* Example: Entire website down, database unavailable, etc. This should
* trigger the SMS alerts and wake you up.
*/
alert(message: string, context?: Record<string, any>): Promise<void>;
/**
* System is unusable.
*/
emergency(message: string, context?: Record<string, any>): Promise<void>;
}
/**
* Support date format:
* - `YYYY` - Full year (e.g., 2024)
* - `YY` - Two-digit year (e.g., 24)
* - `MMMM` - Full month name (e.g., "January")
* - `MMM` - Abbreviated month name (e.g., "Jan")
* - `MM` - Month with leading zero (01-12)
* - `M` - Month without leading zero (1-12)
* - `DD` - Day of month with leading zero (01-31)
* - `D` - Day of month without leading zero (1-31)
* - `HH` - Hour (24-hour) with leading zero (00-23)
* - `H` - Hour (24-hour) without leading zero (0-23)
* - `hh` - Hour (12-hour) with leading zero (00-11)
* - `h` - Hour (12-hour) without leading zero (0-11)
* - `mm` - Minutes with leading zero (00-59)
* - `m` - Minutes without leading zero (0-59)
* - `ss` - Seconds with leading zero (00-59)
* - `s` - Seconds without leading zero (0-59)
* - `SSS` - Milliseconds (000-999)
* - `a` - AM/PM lowercase (am/pm)
* - `A` - AM/PM uppercase (AM/PM)
* - `ZZZ` - Timezone (e.g., UTC)
* - `ZZ` - Timezone offset (e.g., +03:00)
*/
declare abstract class AbstractFormatter implements Formatter {
protected dateFormat: string;
constructor(dateFormat?: string);
abstract format(record: LogRecord): string;
protected _formatTimestamp(date: Date): string;
protected _formatDate(date: Date): string;
}
/**
* JsonFormatter
*
* @inheritDoc
*/
declare class JsonFormatter extends AbstractFormatter implements Formatter {
constructor(dateFormat?: string);
format(record: LogRecord): string;
}
/**
* LineFormatter
*
* @inheritDoc
*/
declare class LineFormatter extends AbstractFormatter implements Formatter {
protected formatString: string;
constructor(formatString?: string, dateFormat?: string);
format(record: LogRecord): string;
}
/**
* TelegramFormatter
*
* Formats a log entry for sending to Telegram.
* Supports HTML markup with escaped special characters.
*
* @link https://core.telegram.org/bots/api#html-style
*/
declare class TelegramFormatter extends AbstractFormatter implements Formatter {
private useHtml;
private maxMessageLength;
constructor(useHtml?: boolean, dateFormat?: string, maxMessageLength?: number);
format(record: LogRecord): string;
protected _formatBaseMessage(record: LogRecord): string;
protected _formatAdditionalInfo(record: LogRecord): string;
protected _escapeHtml(text: string): string;
protected _escapeMarkdownV2(text: string): string;
/**
* Set the use of HTML markup
*/
setUseHtml(useHtml: boolean): this;
/**
* // Set the maximum message length
*/
setMaxMessageLength(maxLength: number): this;
}
declare const pidProcessor: Processor;
declare const memoryUsageProcessor: Processor;
/**
* Abstract Handler
*/
declare abstract class AbstractHandler implements Handler {
protected level: LogLevel;
protected formatter: Formatter | null;
protected bubble: boolean;
constructor(level?: LogLevel, bubble?: boolean);
isHandling(level: LogLevel): boolean;
shouldBubble(): boolean;
setFormatter(formatter: Formatter): void;
getFormatter(): Formatter | null;
/**
* @inheritDoc
*/
abstract handle(record: LogRecord): Promise<boolean>;
}
interface ConsoleHandlerOptions extends HandlerOptions {
useStyles?: boolean;
}
/**
* Console Handler
*/
declare class ConsoleHandler extends AbstractHandler implements Handler {
protected _styles: Map<LogLevel, string[]>;
protected readonly _useStyles: boolean;
constructor(level?: LogLevel, options?: ConsoleHandlerOptions);
protected _initStyles(): void;
/**
* @inheritDoc
*/
handle(record: LogRecord): Promise<boolean>;
protected _getConsoleMethod(level: LogLevel): 'log' | 'info' | 'warn' | 'error' | 'trace';
}
/**
* Console Handler V2
*/
declare class ConsoleV2Handler extends ConsoleHandler implements Handler {
constructor(level?: LogLevel, options?: ConsoleHandlerOptions);
/**
* @inheritDoc
*/
handle(record: LogRecord): Promise<boolean>;
}
interface MemoryHandlerOptions extends HandlerOptions {
limit?: number;
}
/**
* Memory Handler
*/
declare class MemoryHandler extends AbstractHandler implements Handler {
private records;
private readonly limit;
constructor(level?: LogLevel, options?: MemoryHandlerOptions);
/**
* @inheritDoc
*/
handle(record: LogRecord): Promise<boolean>;
getRecords(): LogRecord[];
clear(): void;
}
interface StreamHandlerOptions extends HandlerOptions {
stream: Writable;
}
/**
* Stream Handler
*
* Node.js stream handler for writing logs to streams.
*/
declare class StreamHandler extends AbstractHandler implements Handler {
/**
* Stream for writing logs.
* @private
*/
private stream;
/**
* Creates a StreamHandler instance.
*
* @param {LogLevel} level - Minimum log level.
* @param options
* - `stream: Writable` - Stream to write to (e.g., `process.stdout`, `process.stderr`, `fs.WriteStream`)
* - `bubble?: boolean` - Determines whether the handler should bubble the record to the next handler.
*/
constructor(level: LogLevel | undefined, options: StreamHandlerOptions);
/**
* @inheritDoc
*/
handle(record: LogRecord): Promise<boolean>;
/**
* Closes the stream (if supported).
*
* @returns {Promise<void>}
*/
close(): Promise<void>;
}
interface ConsolaAdapterOptions extends HandlerOptions {
consolaInstance: any;
}
/**
* Adapter for Consola
*
* @memo Consola has its own formatter
* @link https://github.com/unjs/consola
*/
declare class ConsolaAdapter extends AbstractHandler implements Handler {
private consolaInstance;
constructor(level: LogLevel | undefined, options: ConsolaAdapterOptions);
setFormatter(_formatter: Formatter): void;
getFormatter(): Formatter | null;
handle(record: LogRecord): Promise<boolean>;
}
interface WinstonAdapterOptions extends HandlerOptions {
winstonLogger: any;
}
/**
* Adapter for Winston
*
* @memo Winston has its own formatter
* @link https://github.com/winstonjs/winston
*/
declare class WinstonAdapter extends AbstractHandler implements Handler {
private winstonLogger;
constructor(level: LogLevel | undefined, options: WinstonAdapterOptions);
setFormatter(_formatter: Formatter): void;
getFormatter(): Formatter | null;
handle(record: LogRecord): Promise<boolean>;
}
/**
* Define the environment
*/
declare enum Environment {
UNKNOWN = "unknown",
BROWSE = "browser",
NODE = "node"
}
declare function getEnvironment(): Environment;
interface TelegramHandlerOptions extends HandlerOptions {
botToken: string;
chatId: string | number;
parseMode?: 'HTML' | 'Markdown' | 'MarkdownV2';
disableNotification?: boolean;
disableWebPagePreview?: boolean;
useStyles?: boolean;
warnInBrowser?: boolean;
}
/**
* Telegram Handler
*
* Sends logs to Telegram chat.
* The browser displays a warning in the console.
* In Node.js, sends a message via the Telegram Bot API.
*/
declare class TelegramHandler extends AbstractHandler implements Handler {
protected botToken: string;
protected chatId: string | number;
protected parseMode: 'HTML' | 'Markdown' | 'MarkdownV2';
protected disableNotification: boolean;
protected disableWebPagePreview: boolean;
protected readonly environment: Environment;
protected warnInBrowser: boolean;
constructor(level: LogLevel | undefined, options: TelegramHandlerOptions);
/**
* @inheritDoc
*/
handle(record: LogRecord): Promise<boolean>;
/**
* Processing in the browser
*/
protected _handleInBrowser(_message: string, record: LogRecord): Promise<boolean>;
/**
* Processing in Node.js
*/
protected _handleInNode(message: string, _record: LogRecord): Promise<boolean>;
/**
* Fallback processing for unknown environments
*/
protected _handleFallback(message: string): Promise<boolean>;
updateSettings(options: Partial<TelegramHandlerOptions>): this;
/**
* Get current environment
*/
getEnvironment(): Environment;
/**
* Check if the Telegram API is available
*/
testConnection(): Promise<boolean>;
}
declare abstract class AbstractLogger implements LoggerInterface {
/**
* @inheritDoc
*/
abstract log(_level: LogLevel, _message: string, _context?: Record<string, any>): Promise<void>;
/**
* @inheritDoc
*/
debug(message: string, context?: Record<string, any>): Promise<void>;
/**
* @inheritDoc
*/
info(message: string, context?: Record<string, any>): Promise<void>;
/**
* @inheritDoc
*/
notice(message: string, context?: Record<string, any>): Promise<void>;
/**
* @inheritDoc
*/
warning(message: string, context?: Record<string, any>): Promise<void>;
/**
* @inheritDoc
*/
error(message: string, context: Record<string, any>): Promise<void>;
/**
* @inheritDoc
*/
critical(message: string, context?: Record<string, any>): Promise<void>;
/**
* @inheritDoc
*/
alert(message: string, context?: Record<string, any>): Promise<void>;
/**
* @inheritDoc
*/
emergency(message: string, context?: Record<string, any>): Promise<void>;
}
/**
* This Logger can be used to avoid conditional log calls.
*
* Logging should always be optional, and if no logger is provided to your
* library creating a NullLogger instance to have something to throw logs at
* is a good way to avoid littering your code with `if (this.logger) { }`
* blocks.
*/
declare class NullLogger extends AbstractLogger implements LoggerInterface {
static create(): NullLogger;
/**
* @inheritDoc
*/
log(_level: LogLevel, _message: string, _context?: Record<string, any>): Promise<void>;
}
/**
* A logger created according to the principles of `Monolog`
*
* @link https://github.com/Seldaek/monolog
*/
declare class Logger extends AbstractLogger implements LoggerInterface {
private readonly channel;
private handlers;
private processors;
constructor(channel: string);
static create(channel: string): Logger;
pushHandler(handler: Handler): this;
popHandler(): Handler | null;
setHandlers(handlers: Handler[]): this;
pushProcessor(processor: Processor): this;
/**
* **Never throws and never rejects.** Logging is a side channel: a failure in
* it must degrade observability, not the operation being observed. Every
* callsite in the SDK invokes this without `await` (`this.getLogger().info(…)`
* as a statement), so a rejected promise would surface as an *unhandled
* rejection* — which terminates the Node process by default. A handler doing
* network or file I/O (Telegram, a stream, a third-party adapter) rejects for
* ordinary operational reasons, so that path is reachable in normal operation,
* not just in principle (#346).
*
* A processor or handler that fails is skipped and reported via
* {@link reportLoggingFailure}; the remaining handlers still receive the
* record.
*
* This covers failures *inside* the logger. It does not cover an exception
* raised while a caller builds its log arguments — those are evaluated eagerly
* at the callsite, before `log()` is reached (see `truncateForLog`, #338).
*
* ### Deliberately outside this guarantee
*
* Three gaps sit outside `log()` and were each weighed and left open on
* purpose (#346). They are recorded here so they are not re-opened as
* oversights:
*
* 1. **A third-party `LoggerInterface` is not isolated.** This guarantee
* belongs to this class, not to the interface. Every SDK callsite is
* written `…info(…).catch(() => {})`, which absorbs a *rejected promise*;
* an implementation that throws *synchronously*, before returning one,
* escapes into the caller. `setLogger(...)` warns about the shape it can
* check without calling anything (see `warnOnNonPromiseLogger`); returning
* promises is the implementor's side of the contract. Wrapping every
* installed logger defensively was considered and rejected: it would make
* the SDK responsible for code it does not own, on every one of ~94
* callsites, to cover a case TypeScript already rejects at compile time.
*
* 2. **A handler that fails forever is never detached.** Each failure is
* reported, every time — see {@link reportLoggingFailure}. Auto-detaching
* after N failures was considered and rejected: it silently changes a
* configuration the application made, and "N failures" is a policy the SDK
* has no basis to pick on the application's behalf.
*
* 3. **The synchronous half — argument construction — stays the caller's.**
* Making it total would mean wrapping the argument list at every callsite,
* which trades a narrow, findable failure (#338 was one expression in one
* helper) for noise at every call. Individual helpers on the hot path are
* made total instead, as `truncateForLog` was.
*
* @inheritDoc
*/
log(level: LogLevel, message: string, context?: Record<string, any>): Promise<void>;
/**
* Report a processor/handler that threw.
*
* Reported on every failure, deliberately: suppressing repeats would hide how
* often a sink is failing, and a sink that has been broken for an hour looks
* identical to one that failed once. The volume is the signal — if it is
* noisy, the sink is failing that often. Filtering belongs to whoever reads
* the output, not to the SDK.
*
* `console` is used rather than the logger — routing a logging failure back
* through the logger that just failed is how this turns into recursion.
*
* The handler is **not** detached, however many times it fails. Doing so would
* silently discard part of a configuration the application built, and the
* threshold that would trigger it is a policy call the SDK cannot make for the
* application. A sink that is broken stays wired and stays loud; whoever reads
* the output decides what to do about it (#346).
*/
private reportLoggingFailure;
}
declare class LoggerFactory {
static createNullLogger(): LoggerInterface;
static createForBrowser(channel: string, isDevMode?: boolean): LoggerInterface;
static createForBrowserDevelopment(channel: string, level?: LogLevel): LoggerInterface;
static createForBrowserProduction(channel: string, level?: LogLevel): LoggerInterface;
static forcedLog(logger: LoggerInterface, action: 'debug' | 'info' | 'notice' | 'warning' | 'error' | 'critical' | 'alert' | 'emergency', message: string, context: Record<string, any>): Promise<void>;
}
/**
* @deprecated This enum is deprecated and will be removed in version `3.0.0`
*/
declare enum LoggerType {
desktop = "desktop",
log = "log",
info = "info",
warn = "warn",
error = "error",
trace = "trace"
}
/**
* LoggerBrowser
*
* @deprecated This class is deprecated and will be removed in version `3.0.0`
* - use {@link Logger `Logger`}
*
* @removed 3.0.0
*/
declare class LoggerBrowser implements LoggerInterface {
#private;
/**
* Create a LoggerBrowser instance
*
* @deprecated This method is deprecated and will be removed in version `3.0.0`
*
* @removed 3.0.0
*/
static build(title: string, isDevelopment?: boolean): LoggerBrowser;
private constructor();
/**
* Set config
*
* @deprecated This method is deprecated and will be removed in version `3.0.0`
*
* @removed 3.0.0
*/
setConfig(_types: Record<string | LoggerType, boolean>): void;
/**
* Set enable
*
* @deprecated This method is deprecated and will be removed in version `3.0.0`
*
* @removed 3.0.0
*/
enable(_type: LoggerType): boolean;
/**
* Set disable
*
* @deprecated This method is deprecated and will be removed in version `3.0.0`
*
* @removed 3.0.0
*/
disable(_type: LoggerType): boolean;
/**
* Test is enable
*
* @deprecated This method is deprecated and will be removed in version `3.0.0`
*
* @removed 3.0.0
*/
isEnabled(_type: LoggerType): boolean;
desktop(...params: any[]): Promise<void>;
log(...params: any[]): Promise<void>;
info(...params: any[]): Promise<void>;
warn(...params: any[]): Promise<void>;
error(...params: any[]): Promise<void>;
trace(...params: any[]): Promise<void>;
debug(...params: any[]): Promise<void>;
notice(...params: any[]): Promise<void>;
warning(...params: any[]): Promise<void>;
critical(...params: any[]): Promise<void>;
alert(...params: any[]): Promise<void>;
emergency(...params: any[]): Promise<void>;
}
/**
* String which is actually a number, like `'20.23'`
*/
type NumberString = string;
/**
* Like `'2018-06-07T03:00:00+03:00'`
*/
type ISODate = string;
type BoolString = 'Y' | 'N';
type GenderString = 'M' | 'F' | '';
type PlacementViewMode = 'view' | 'edit';
type TextType = 'text' | 'html';
type Fields = {
readonly [key: string]: {
readonly type: string;
readonly isRequired: boolean;
readonly isReadOnly: boolean;
readonly isImmutable: boolean;
readonly isMultiple: boolean;
readonly isDynamic: boolean;
readonly title: string;
readonly upperName?: string;
};
};
type MultiField = {
readonly ID: NumberString;
readonly VALUE_TYPE: string;
readonly VALUE: string;
readonly TYPE_ID: string;
};
type MultiFieldArray = ReadonlyArray<Pick<MultiField, 'VALUE' | 'VALUE_TYPE'>>;
/**
* Describes the inline settings in UF
*/
type UserFieldType = {
USER_TYPE_ID: string;
HANDLER: string;
TITLE: string;
DESCRIPTION: string;
OPTIONS?: {
height: number;
};
};
/**
* Data types
* @link https://apidocs.bitrix24.ru/api-reference/data-types.html
* @link https://dev.1c-bitrix.ru/rest_help/crm/dynamic/methodscrmitem/crm_item_fields.php
*/
declare enum DataType {
undefined = "undefined",
any = "any",
integer = "integer",
boolean = "boolean",
double = "double",
date = "date",
datetime = "datetime",
string = "string",
text = "text",
file = "file",
array = "array",
object = "object",
user = "user",
location = "location",
crmCategory = "crm_category",
crmStatus = "crm_status",
crmCurrency = "crm_currency"
}
interface BlobLike {
readonly size: number;
readonly type: string;
slice(start?: number, end?: number, contentType?: string): Blob;
}
interface FileLike extends BlobLike {
name: string;
lastModified?: number;
lastModifiedDate?: object;
}
/**
* A collection of runtime type guards used across the SDK.
*
* Every method (other than `getTag` and `clone`) is a TypeScript type guard
* (`value is X`), so it can be used directly in `if` chains and have the
* compiler narrow the value's type. It groups together checks for:
* - primitives (strings, numbers, booleans, `null` / `undefined`),
* - objects (plain objects, functions, `Map` / `Set` / `WeakMap` / `WeakSet`, `RegExp`, prototypes),
* - arrays and array-like values (including typed arrays and `ArrayBuffer`),
* - DOM nodes (elements, text nodes),
* - file-like values (`Blob`, `File`, `FormData`),
* - JSON-RPC message shapes.
*
* The class is exported as the `Type` singleton — you never instantiate it yourself.
*
* @example
* ```ts
* import { Type } from '@bitrix24/b24jssdk'
*
* function process(value: unknown) {
* if (Type.isStringFilled(value)) {
* // value: string
* return value.trim()
* }
* }
* ```
*
* @see bitrix/js/main/core/src/lib/type.js
*/
declare class TypeManager {
/**
* Returns the internal `[[Class]]` tag of a value.
* @param value - The value to inspect.
* @returns The result of `Object.prototype.toString.call(value)`, e.g. `'[object Array]'`.
*/
getTag(value: any): string;
/**
* Checks that value is string
* @param value
* @return {boolean}
*
* @memo get from pull.client.Utils
*/
isString(value: any): value is string;
/**
* Returns true if a value is not an empty string
* @param value
* @returns {boolean} Returns true if a value is not an empty string
*/
isStringFilled(value: any): value is string;
/**
* Checks that value is function
* @param value
* @return {boolean}
*
* @memo get from pull.client.Utils
*/
isFunction(value: any): value is Function;
/**
* Checks that value is an object
* @param value
* @return {boolean}
*/
isObject(value: any): value is object | Function;
/**
* Checks that value is object like
* @param value
* @return {boolean}
*/
isObjectLike<T>(value: any): value is T;
/**
* Checks that value is plain object
* @param value
* @return {boolean}
*/
isPlainObject(value: any): value is Record<string | number, any>;
/**
* Checks that value looks like a JSON-RPC request object.
* @param value - The value to check.
* @returns True when `value` has a non-empty `jsonrpc` string and a non-empty `method` string.
*/
isJsonRpcRequest(value: any): boolean;
/**
* Checks that value looks like a JSON-RPC response object.
* @param value - The value to check.
* @returns True when `value` has a non-empty `jsonrpc` string, an `id`, and either a `result` or an `error` property.
*/
isJsonRpcResponse(value: any): boolean;
/**
* Checks that value is boolean
* @param value
* @return {boolean}
*/
isBoolean(value: any): value is boolean;
/**
* Checks that value is number
* @param value
* @return {boolean}
*/
isNumber(value: any): value is number;
/**
* Checks that value is integer
* @param value
* @return {boolean}
*/
isInteger(value: any): value is number;
/**
* Checks that value is float
* @param value
* @return {boolean}
*/
isFloat(value: any): value is number;
/**
* Checks that value is nil
* @param value
* @return {boolean}
*/
isNil(value: any): value is null | undefined;
/**
* Checks that value is an array
* @param value
* @return {boolean}
*/
isArray(value: any): value is any[];
/**
* Returns true if a value is an array, and it has at least one element
* @param value
* @returns {boolean} Returns true if a value is an array, and it has at least one element
*/
isArrayFilled(value: any): value is any[];
/**
* Checks that value is array like
* @param value
* @return {boolean}
*/
isArrayLike(value: any): value is ArrayLike<any>;
/**
* Checks that value is Date
* @param value
* @return {boolean}
*/
isDate(value: any): value is Date;
/**
* Checks that is a DOM node
* @param value
* @return {boolean}
*/
isDomNode(value: any): value is Node;
/**
* Checks that value is element node
* @param value
* @return {boolean}
*/
isElementNode(value: any): value is HTMLElement;
/**
* Checks that value is a text node
* @param value
* @return {boolean}
*/
isTextNode(value: any): value is Text;
/**
* Checks that value is Map
* @param value
* @return {boolean}
*/
isMap(value: any): value is Map<unknown, unknown>;
/**
* Checks that value is Set
* @param value
* @return {boolean}
*/
isSet(value: any): value is Set<unknown>;
/**
* Checks that value is WeakMap
* @param value
* @return {boolean}
*/
isWeakMap(value: any): value is WeakMap<object, unknown>;
/**
* Checks that value is WeakSet
* @param value
* @return {boolean}
*/
isWeakSet(value: any): value is WeakSet<object>;
/**
* Checks that value is prototype
* @param value
* @return {boolean}
*/
isPrototype(value: any): value is object;
/**
* Checks that value is regexp
* @param value
* @return {boolean}
*/
isRegExp(value: any): value is RegExp;
/**
* Checks that value is null
* @param value
* @return {boolean}
*/
isNull(value: any): value is null;
/**
* Checks that value is undefined
* @param value
* @return {boolean}
*/
isUndefined(value: any): value is undefined;
/**
* Checks that value is ArrayBuffer
* @param value
* @return {boolean}
*/
isArrayBuffer(value: any): value is ArrayBuffer;
/**
* Checks that value is typed array
* @param value
* @return {boolean}
*/
isTypedArray(value: any): value is Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array;
/**
* Checks that value is Blob
* @param value
* @return {boolean}
*/
isBlob(value: any): value is BlobLike;
/**
* Checks that value is File
* @param value
* @return {boolean}
*/
isFile(value: any): value is FileLike;
/**
* Checks that value is FormData
* @param value
* @return {boolean}
*/
isFormData(value: any): value is FormData;
/**
* Deep-clones a value, with support for DOM nodes.
*
* Primitives and `null` / `undefined` are returned unchanged. `Date` instances
* are cloned via `new Date(obj)`, DOM nodes via `Node.cloneNode`, and plain
* objects/arrays are copied property by property (recursively, when `bCopyObj` is true).
*
* @param obj - The value to clone.
* @param bCopyObj - When true (default), nested objects/arrays are cloned recursively; when false, they are copied by reference.
* @returns A clone of `obj` (or `obj` itself for primitives).
*/
clone(obj: any, bCopyObj?: boolean): any;
}
declare const Type: TypeManager;
/**
* Returns a new object containing only the specified keys from `data`.
*/
declare function pick<Data extends object, Keys extends keyof Data>(data: Data, keys: Keys[]): Pick<Data, Keys>;
/**
* Returns a shallow copy of `data` with the specified keys removed.
*/
declare function omit<Data extends object, Keys extends keyof Data>(data: Data, keys: Keys[]): Omit<Data, Keys>;
/**
* Type guard that returns `true` when `item` is an array of arrays rather than a flat array.
*/
declare function isArrayOfArray<A>(item: A[] | A[][]): item is A[][];
/**
* Returns the enum member whose value equals `value`, or `undefined` if no match is found.
*
* @example
* const result = getEnumValue(EnumBizprocDocumentType, 'CCrmDocumentSmartOrder')
*/
declare function getEnumValue<T extends Record<string, string | number>>(enumObj: T, value: string | number): T[keyof T] | undefined;
/**
* A collection of text and date utilities used across the SDK.
*
* It groups together helpers for:
* - generating identifiers (random strings, UUID v4 and UUID v7),
* - encoding and decoding HTML entities,
* - converting arbitrary values to numbers, integers, and booleans,
* - changing the case and format of strings (camelCase, PascalCase, kebab-case),
* - formatting numbers and dates,
* - building `application/x-www-form-urlencoded` query strings.
*
* The class is exported as the `Text` singleton — you never instantiate it yourself.
*
* @example
* ```ts
* import { Text } from '@bitrix24/b24jssdk'
*
* Text.getUuidRfc4122() // '019323ac-8ace-725b-a3dc-6a7c333da066'
* Text.getDateForLog() // '2026-05-04 09:53:51'
* Text.numberFormat(1234.567, 2) // '1,234.57'
* ```
*
* @see bitrix/js/main/core/src/lib/text.js
*/
declare class TextManager {
/**
* Generates a random `[a-z0-9]` string of the requested length.
*
* Each character is drawn from `Math.random()`, so the result is **not**
* cryptographically secure — use it for cache-busting keys and disposable
* ids, not for tokens or secrets.
*
* @param length - Number of characters to generate. Defaults to `8`.
* @returns A random lowercase alphanumeric string.
*
* @example
* ```ts
* Text.getRandom() // 'a7f3k1z9'
* Text.getRandom(4) // 'p2x8'
* ```
*/
getRandom(length?: number): string;
/**
* Generates a locally-computed UUID v4 (random) string.
*
* The value is built from `Math.random()` and is **not**
* cryptographically secure. For a time-ordered, RFC 4122 identifier prefer
* {@link getUuidRfc4122}.
*
* @returns A UUID v4 formatted string (`xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`).
*
* @example
* ```ts
* Text.getUniqId() // 'd2b8a1f0-3c4e-4a9b-8f7c-1e2d3a4b5c6d'
* ```
*/
getUniqId(): string;
/**
* Generates a time-ordered UUID v7 (RFC 4122).
*
* This is the identifier the SDK uses as the default request id, because its
* leading timestamp keeps generated ids sortable by creation time.
*
* @returns A UUID v7 formatted string.
*
* @example
* ```ts
* Text.getUuidRfc4122() // '019323ac-8ace-725b-a3dc-6a7c333da066'
* ```
*/
getUuidRfc4122(): string;
/**
* Encodes the unsafe HTML characters `&`, `<`, `>`, `'`, and `"` into their
* entity codes.
*
* To match the legacy Bitrix Framework behaviour the trailing `;` is
* deliberately omitted (`&` instead of `&`). Non-string values are
* returned untouched.
*
* This is **not** a general-purpose HTML sanitizer: it only escapes those
* five characters and is not context-aware (it does not neutralise
* attribute-breakout, `javascript:` URLs, or markup outside the escaped set).
* Do not rely on it as the sole XSS defence for untrusted input rendered as
* HTML.
*
* @param value - The string to encode.
* @returns The encoded string, or the original value when it is not a string.
*
* @example
* ```ts
* Text.encode('<b>Tom & Jerry</b>') // '<b>Tom & Jerry</b>'
* ```
*/
encode(value: string): string;
/**
* Decodes HTML entities produced by {@link encode} back into their
* characters.
*
* Both the named entities (`&`, `<`, …) and their numeric equivalents
* (`&`, `<`, …) are recognised. Like {@link encode}, the tokens carry
* no trailing `;`, so a `;` that follows an entity in the input is left in
* place (`&` decodes to `&;`). Non-string values are returned untouched.
*
* @param value - The string to decode.
* @returns The decoded string, or the original value when it is not a string.
*
* @example
* ```ts
* Text.decode('<b>Tom & Jerry</b>') // '<b>Tom & Jerry</b>'
* ```
*/
decode(value: string): string;
/**
* Parses a value into a floating-point number.
*
* Uses `Number.parseFloat`, so a leading numeric portion is accepted
* (`'12px'` → `12`). Any value that cannot be parsed becomes `0`.
*
* @param value - The value to convert.
* @returns The parsed number, or `0` when parsing fails.
*
* @example
* ```ts
* Text.toNumber('12.5') // 12.5
* Text.toNumber('abc') // 0
* ```
*/
toNumber(value: any): number;
/**
* Parses a value into an integer (base 10).
*
* Any value that cannot be parsed becomes `0`.
*
* @param value - The value to convert.
* @returns The parsed integer, or `0` when parsing fails.
*
* @example
* ```ts
* Text.toInteger('42.9') // 42
* Text.toInteger('abc') // 0
* ```
*/
toInteger(value: any): number;
/**
* Interprets a value as a boolean.
*
* `true` is returned for `true`, `1`, `'true'`, `'y'`, and `'1'`
* (string comparison is case-insensitive). Extra truthy tokens can be added
* through `trueValues`; everything else yields `false`.
*
* @param value - The value to interpret.
* @param trueValues - Additional values that should be treated as `true`.
* @returns `true` when the value matches a truthy token, otherwise `false`.
*
* @example
* ```ts
* Text.toBoolean('Y') // true
* Text.toBoolean('on', ['on']) // true
* Text.toBoolean('no') // false
* ```
*/
toBoolean(value: any, trueValues?: string[]): boolean;
/**
* Converts a string to `camelCase`.
*
* Hyphens, underscores, and whitespace are treated as word separators. A
* fully uppercase string is lowercased (`'ABC'` → `'abc'`); an empty or
* non-filled string is returned untouched.
*
* @param str - The string to convert.
* @returns The `camelCase` string.
*
* @example
* ```ts
* Text.toCamelCase('get_user_id') // 'getUserId'
* Text.toCamelCase('Some Value') // 'someValue'
* ```
*/
toCamelCase(str: string): string;
/**
* Converts a string to `PascalCase`.
*
* Equivalent to `capitalize(toCamelCase(str))`. An empty or non-filled string
* is returned untouched.
*
* @param str - The string to convert.
* @returns The `PascalCase` string.
*
* @example
* ```ts
* Text.toPascalCase('get_user_id') // 'GetUserId'
* ```
*/
toPascalCase(str: string): string;
/**
* Converts a string to `kebab-case`.
*
* Splits on uppercase-letter boundaries as well as existing separators, so
* both `camelCase` and mixed-case acronyms are handled. An uppercase run that
* is immediately followed by a digit is split into single letters
* (`parseHTML5` → `parse-h-t-m-l-5`), because there is no word boundary
* between the acronym and the digit. An empty or non-filled string is
* returned untouched.
*
* @param str - The string to convert.
* @returns The `kebab-case` string.
*
* @example
* ```ts
* Text.toKebabCase('getUserId') // 'get-user-id'
* Text.toKebabCase('XMLHttpRequest') // 'xml-http-request'
* ```
*/
toKebabCase(str: string): string;
/**
* Uppercases the first character of a string, leaving the rest untouched.
*
* An empty or non-filled string is returned untouched.
*
* @param str - The string to capitalize.
* @returns The capitalized string.
*
* @example
* ```ts
* Text.capitalize('hello') // 'Hello'
* ```
*/
capitalize(str: string): string;
/**
* Formats a number with grouped thousands and a fixed number of decimals.
*
* Mirrors the algorithm Bitrix24 uses on the server: non-finite inputs are
* treated as `0`, the fractional part is rounded to `decimals` places, and
* the thousands separator is inserted every three digits left of the decimal
* point.
*
* @param number - The number to format.
* @param decimals - Number of digits after the decimal point. Defaults to `0`.
* @param decPoint - The decimal-point character. Defaults to `'.'`.
* @param thousandsSep - The thousands separator. Defaults to `','`.
* @returns The formatted number as a string.
*
* @example
* ```ts
* Text.numberFormat(1234.567, 2) // '1,234.57'
* Text.numberFormat(1234.567, 2, ',', ' ') // '1 234,57'
* ```
*/
numberFormat(number: number, decimals?: number, decPoint?: string, thousandsSep?: string): string;
/**
* Converts a string into a Luxon `DateTime`.
*
* When `template` is provided the string is parsed with
* `DateTime.fromFormat`; otherwise it is parsed as ISO 8601 via
* `DateTime.fromISO`.
*
* @param dateString - The date string to parse.
* @param template - Optional Luxon format token describing `dateString`.
* @param opts - Optional Luxon parsing options (zone, locale, …).
* @returns The parsed `DateTime` (use `.isValid` to check the result).
*
* @see https://moment.github.io/luxon/#/parsing?id=parsing-technical-formats
*
* @example
* ```ts
* Text.toDateTime('2026-05-04T09:53:51+03:00')
* Text.toDateTime('04.05.2026', 'dd.MM.yyyy')
* ```
*/
toDateTime(dateString: string, template?: string, opts?: DateTimeOptions): DateTime;
/**
* Formats a date into the string Bitrix24 expects in REST payloads
* (`yyyy-MM-dd'T'HH:mm:ssZZ`, i.e. PHP's `Y-m-d\TH:i:sP`).
*
* A string input is passed through unchanged (assumed already formatted); a
* JS `Date` is converted through Luxon first.
*
* @param date - The value to format: an already-formatted string, a JS `Date`,
* or a Luxon `DateTime`.
* @returns The Bitrix24-formatted date string.
*
* @example
* ```ts
* Text.toB24Format(new Date()) // '2026-05-04T09:53:51+03:00'
* ```
*/
toB24Format(date: string | DateTime | Date): string;
/**
* Returns the current local timestamp formatted for log lines
* (`yyyy-MM-dd HH:mm:ss`).
*
* @returns The formatted current timestamp.
*
* @example
* ```ts
* Text.getDateForLog() // '2026-05-04 09:53:51'
* ```
*/
getDateForLog(): string;
/**
* Serialises a plain object into an `application/x-www-form-urlencoded`
* query string.
*
* Keys and values are percent-encoded. Array values are expanded into
* indexed pairs (`key[0]=a&key[1]=b`). The leading `?` is **not** included.
*
* @param params - The object to serialise. A `null` / `undefined` value
* yields an empty string.
* @returns The encoded query string (without a leading `?`).
*
* @example
* ```ts
* Text.buildQueryString({ id: 7, tag: ['a', 'b'] })
* // 'id=7&tag%5B0%5D=a&tag%5B1%5D=b'
* ```
*/
buildQueryString(params: any): string;
}
declare const Text$1: TextManager;
/**
* Cheap user-agent / platform / capability detector for browser environments.
*
* Exported as the `Browser` singleton. All checks are derived from a module-level
* `UA` string (a lower-cased `navigator.userAgent`, captured once at import time)
* or from browser globals (`window`, `document`, `navigator`, `localStorage`).
* Because of this, the methods are only meaningful when running in a browser —
* in non-browser environments (e.g. Node/SSR) `UA` falls back to `'?'` and any
* method that touches `window`/`document`/`localStorage` directly may throw.
*
* @see bitrix/js/main/core/src/lib/browser.js
*/
declare class BrowserManager {
/**
* Checks whether the current browser is Opera.
*
* @returns `true` if the user agent string contains `opera`.
*/
isOpera(): boolean;
/**
* Checks whether the current browser is Internet Explorer (any version).
*
* @returns `true` if `document` exposes the legacy `attachEvent` API and the browser is not Opera.
*/
isIE(): boolean;
/**
* Checks whether the current browser is Internet Explorer 6.
*
* @returns `true` if the user agent string contains `msie 6`.
*/
isIE6(): boolean;
/**
* Checks whether the current browser is Internet Explorer 7.
*
* @returns `true` if the user agent string contains `msie 7`.
*/
isIE7(): boolean;
/**
* Checks whether the current browser is Internet Explorer 8.
*
* @returns `true` if the user agent string contains `msie 8`.
*/
isIE8(): boolean;
/**
* Checks whether the current browser is Internet Explorer 9 or the document is rendered in IE9+ document mode.
*
* @returns `true` if `document.documentMode` is defined and `>= 9`.
*/
isIE9(): boolean;
/**
* Checks whether the current browser is Internet Explorer 10 or the document is rendered in IE10+ document mode.
*
* @returns `true` if `document.documentMode` is defined and `>= 10`.
*/
isIE10(): boolean;
/**
* Checks whether the current browser is Safari.
*
* @returns `true` if the user agent string contains `safari` and does not contain `chrome`.
*/
isSafari(): boolean;
/**
* Checks whether the current browser is Firefox.
*
* @returns `true` if the user agent string contains `firefox`.
*/
isFirefox(): boolean;
/**
* Checks whether the current browser is Chrome.
*
* @returns `true` if the user agent string contains `chrome`.
*/
isChrome(): boolean;
/**
* Detects the Internet Explorer version using a chain of user-agent and
* `document`/`navigator` heuristics (including legacy Trident/MSIE detection).
*
* @returns The detected IE version number, or `-1` if the browser is Opera, Safari, Firefox, or Chrome (i.e. not IE).
*/
detectIEVersion(): number;
/**
* Checks whether the current browser is Internet Explorer 11.
*
* @returns `true` if {@link detectIEVersion} resolves to `11` or higher.
*/
isIE11(): boolean;
/**
* Checks whether the current OS is macOS.
*
* @returns `true` if the user agent string contains `macintosh`.
*/
isMac(): boolean;
/**
* Checks whether the current OS is Windows.
*
* @returns `true` if the user agent string contains `windows`.
*/
isWin(): boolean;
/**
* Checks whether the current OS is Linux (desktop, not Android).
*
* @returns `true` if the user agent string contains `linux` and the platform is not Android.
*/
isLinux(): boolean;
/**
* Checks whether the current OS is Android.
*
* @returns `true` if the user agent string contains `android`.
*/
isAndroid(): boolean;
/**
* Checks whether the current device is an iPad.
*
* @returns `true` if the user agent string contains `ipad;`, or the platform is macOS with touch support (modern iPadOS reporting as Mac).
*/
isIPad(): boolean;
/**
* Checks whether the current device is an iPhone.
*
* @returns `true` if the user agent string contains `iphone;`.
*/
isIPhone(): boolean;
/**
* Checks whether the current device runs iOS.
*
* @returns `true` if {@link isIPad} or {@link isIPhone} is `true`.
*/
isIOS(): boolean;
/**
* Checks whether the current device is a mobile device.
*
* @returns `true` if the device is an iPhone, iPad, or Android device, or the user agent string contains `mobile` or `touch`.
*/
isMobile(): boolean;
/**
* Checks whether the current display is a high-density (Retina) screen.
*
* @returns `true` if `window.devicePixelRatio` is defined and `>= 2`.
*/
isRetina(): boolean;
/**
* Checks whether the current device supports touch input.
*
* @returns `true` if `window` exposes `ontouchstart` or `navigator.maxTouchPoints` is greater than `0`.
*/
isTouchDevice(): boolean;
/**
* Checks whether a document is rendered in standards mode (as opposed to quirks mode).
*
* @param target - The document to inspect. Defaults to the global `document` when omitted/falsy.
* @returns `true` if `compatMode` is `'CSS1Compat'`, or a truthy fallback based on `documentElement.clientHeight` when `compatMode` is unavailable.
*/
isDoctype(target: any): boolean;
/**
* Checks whether `localStorage` is available and writable in the current environment.
*
* @returns `true` if a test key can be written to and removed from `localStorage` without throwing.
*/
isLocalStorageSupported(): boolean;
/**
* Detects the Android OS version from the user agent string.
*
* @returns The parsed Android version number, or `0` if it cannot be detected (e.g. not Android).
*/
detectAndroidVersion(): number;
}
declare const Browser: BrowserManager;
/**
* Interface defining the structure and methods of a Result object.
*/
interface IResult<T = any> {
/**
* Indicates whether the operation resulted in success (no errors).
*/
readonly isSuccess: boolean;
/**
* Collection of errors
*/
readonly errors: Map<string, Error>;
/**
* Sets the data associated with the result.
*
* @param data The data to be stored in the result.
* @returns The current Result object for chaining methods.
*/
setData: (data: T | null | undefined) => IResult<T>;
/**
* Retrieves the data associated with the result.
*
* @returns The data stored in the result, if any.
*/
getData: () => T | null | undefined;
/**
* Adds an error message or Error object to the result.
* @param error The error message or Error object to be added.
* @param key Error key. You can leave it blank. Then it will be generated automatically.
* @returns {IResult<T>} The current Result object for chaining methods.
*/
addError: (error: Error | string, key?: string) => IResult<T>;
/**
* Adds multiple errors to the result in a single call.
*
* @param errors An array of errors or strings that will be converted to errors.
* @returns {IResult<T>} The current Result object for chaining methods.
*/
addErrors: (errors: (Error | string)[]) => IResult<T>;
/**
* Retrieves an iterator for the errors collected in the result.
*
* @returns {IterableIterator<Error>} An iterator over the stored Error objects.
* @see {@link IResult.getErrorsByKey} — keeps the request keys.
*/
getErrors: () => IterableIterator<Error>;
/**
* Retrieves an array of error messages from the collected errors.
*
* @returns {string[]} An array of strings representing the error messages.
*/
getErrorMessages: () => string[];
/**
* Retrieves all errors keyed by their identifier (e.g. the batch request key),
* preserving which request produced each error. Unlike {@link getErrors}, the
* keys are not discarded — useful for batch calls with `isHaltOnError: false`.
*
* @returns {Record<string, Error>} A map of error key to Error object.
*/
getErrorsByKey: () => Record<string, Error>;
/**
* Retrieves all error messages keyed by their identifier (e.g. the batch
* request key). Unlike {@link getErrorMessages}, the keys are preserved.
*
* @returns {Record<string, string>} A map of error key to error message.
*/
getErrorMessagesByKey: () => Record<string, string>;
/**
* Checks for an error in a collection by key
* @param key - Error key
*/
hasError(key: string): boolean;
/**
* Converts the Result object to a string.
*
* @returns {string} Returns a string representation of the result operation
*/
toString: () => string;
}
/**
* A class representing an operation result with success/failure status, data, and errors.
* Similar to \Bitrix\Main\Result from Bitrix Framework.
* @link https://dev.1c-bitrix.ru/api_d7/bitrix/main/result/index.php
*/
declare class Result<T = any> implements IResult<T> {
protected _errors: Map<string, Error>;
protected _data: T | null | undefined;
constructor(data?: T);
get isSuccess(): boolean;
get errors(): Map<string, Error>;
setData(data: T | null | undefined): this;
getData(): T | null | undefined;
addError(error: Error | string, key?: string): this;
addErrors(errors: (Error | string)[]): this;
getErrors(): IterableIterator<Error>;
hasError(key: string): boolean;
/**
* Retrieves an array of error messages from the collected errors.
*
* @returns An array of strings representing the error messages. Each string
* contains the message of a corresponding error object.
*/
getErrorMessages(): string[];
/**
* Retrieves all errors as a plain object (a snapshot copy) keyed by their
* identifier, preserving which request produced each error. Unlike
* {@link Result.getErrors}, the keys are not discarded — useful for batch
* calls with `isHaltOnError: false`.
*
* For batch calls the key tells you *which* command failed:
* - an **object / named-command batch** keys each error by the command label;
* - an **array-mode batch** keys each per-command error by its **numeric
* position** (`'0'`, `'1'`, … as a string), matching the command order you
* passed in. (#255 — previously these fell back to a random UUID.)
*
* An envelope-level soft error (not tied to one command) lands under the
* internal `'base-error'` key, and {@link Result.addErrors} (no explicit key)
* still uses generated UUIDs — for those, prefer {@link Result.getErrors} /
* {@link Result.getErrorMessages}. (#230)
*
* @returns {Record<string, Error>} A map of error key to Error object.
*/
getErrorsByKey(): Record<string, Error>;
/**
* Retrieves all error messages as a plain object (a snapshot copy) keyed by
* their identifier. Unlike {@link Result.getErrorMessages}, the keys are
* preserved. See {@link Result.getErrorsByKey} for when keys are meaningful.
*
* @returns {Record<string, string>} A map of error key to error message.
*/
getErrorMessagesByKey(): Record<string, string>;
/**
* Converts the Result object to a string.
*
* @returns {string} Returns a string representation of the result operation
*/
toString(): string;
private safeStringify;
private replacer;
static ok<U>(data?: U): Result<U>;
static fail<U>(error: Error | string, key?: string): Result<U>;
}
/**
* Types for authentication and OAuth token data passed to Bitrix24 REST API event handlers.
* `HandlerAuthParams` contains the full auth context provided with every incoming event request.
*/
interface HandlerAuthParams {
access_token: string;
expires: string;
expires_in: string;
scope: string;
domain: string;
server_endpoint: string;
status: string;
client_endpoint: string;
member_id: string;
user_id: string;
refresh_token: string;
application_token: string;
}
type PayloadOAuthToken = Pick<HandlerAuthParams, 'access_token' | 'refresh_token' | 'expires' | 'expires_in' | 'client_endpoint' | 'server_endpoint' | 'member_id' | 'status' | 'user_id'>;
declare enum LoadDataType {
App = "app",
Profile = "profile",
Currency = "currency",
AppOptions = "appOptions",
UserOptions = "userOptions"
}
type TypeUser = {
readonly isAdmin: boolean;
readonly id: null | number;
readonly lastName: null | string;
readonly name: null | string;
readonly gender: GenderString;
readonly photo: null | string;
readonly TimeZone: null | string;
readonly TimeZoneOffset: null | number;
};
declare const EnumAppStatus: {
readonly Free: "F";
readonly Demo: "D";
readonly Trial: "T";
readonly Paid: "P";
readonly Local: "L";
readonly Subscription: "S";
};
declare const StatusDescriptions: Record<(typeof EnumAppStatus)[keyof typeof EnumAppStatus], string>;
type TypeEnumAppStatus = keyof typeof EnumAppStatus;
/**
* @link https://dev.1c-bitrix.ru/rest_help/general/app_info.php
*/
type TypeApp = {
/**
* Local application identifier on the portal
*/
readonly id: number;
/**
* application code
*/
readonly code: string;
/**
* installed version of the application
*/
readonly version: number;
/**
* application status
*/
readonly status: TypeEnumAppStatus;
/**
* application installed flag
*/
readonly isInstalled: boolean;
};
/**
* @link https://dev.1c-bitrix.ru/rest_help/general/app_info.php
*/
type TypePayment = {
/**
* flag indicating whether the paid period or trial period has expired
*/
readonly isExpired: boolean;
/**
* number of days remaining until the end of the paid period or trial period
*/
readonly days: number;
};
/**
* @link https://dev.1c-bitrix.ru/rest_help/general/app_info.php
*/
type TypeLicense = {
/**
* language code designation
*/
readonly languageId: null | string;
/**
* tariff designation with indication of the region as a prefix
*/
readonly license: null | string;
/**
* internal tariff designation without indication of region
*/
readonly licenseType: null | string;
/**
* past meaning of license
*/
readonly licensePrevious: null | string;
/**
* Tariff designation without specifying the region.
*/
readonly licenseFamily: null | string;
/**
* flag indicating whether it is a box (true) or a cloud (false)
*/
readonly isSelfHosted: boolean;
};
declare const TypeSpecificUrl: {
readonly MainSettings: "MainSettings";
readonly UfList: "UfList";
readonly UfPage: "UfPage";
};
type TypeB24Form = {
readonly app_code: string;
readonly app_status: string;
readonly payment_expired: BoolString;
readonly days: number;
/**
* B24 tariff plan identifier (if cloud)
*/
readonly b24_plan: string;
readonly c_name: string;
readonly c_last_name: string;
readonly hostname: string;
};
type CurrencyFormat = {
decimals: number;
decPoint: string;
formatString: string;
fullName: string;
isHideZero: boolean;
thousandsSep?: string;
thousandsVariant?: 'N' | 'D' | 'C' | 'S' | 'B' | 'OWN' | string;
};
type Currency = {
amount: number;
amountCnt: number;
isBase: boolean;
currencyCode: string;
dateUpdate: DateTime;
decimals: number;
decPoint: string;
formatString: string;
fullName: string;
lid: string;
sort: number;
thousandsSep?: string;
lang: Record<string, CurrencyFormat>;
};
declare enum TypeOption {
NotSet = "notSet",
JsonArray = "jsonArray",
JsonObject = "jsonObject",
FloatVal = "float",
IntegerVal = "integer",
BoolYN = "boolYN",
StringVal = "string"
}
/**
* Types and interfaces for configuring rate-limiting and adaptive throttling of REST API requests.
* These settings control the operating time window, per-window limits, and adaptive pause behaviour.
*/
/**
* Settings for operating limiting
*/
interface OperatingLimitConfig {
/**
* Operating limit time period in milliseconds
* Default: 10 minutes (600_000 ms)
*/
windowMs: number;
/**
* Maximum total execution time (operating) in milliseconds
* Default: 480 seconds (480_000 ms)
* When calculating the operating limit, we will use 5 seconds less
* @see Http.getTimeToFree
*/
limitMs: number;
/**
* Threshold for notifications about heavy queries (%)
*/
heavyPercent: number;
}
/**
* Adaptive pause settings
*/
interface AdaptiveConfig {
/**
* Threshold for heavy queries (%)
* Default: 80% - this means that `operating >= 384`
* Specifies what % of `operatingLimit.limitMs` in `operating` should pause.
*/
thresholdPercent: number;
/**
* Pause multiplier
* Default: 0.01 - 0.002 will result in a 1.2-second pause with increasing load
* If: operating_reset_at > Date.now()
* Then: Pause = (operating_reset_at - Date.now()) * coefficient
* Otherwise: Pause = 7_000
* There's no point in specifying a value close to 1, as this will create unnecessary delays.
* In other words: if coefficient === 1, the pause will last until the blocking is unblocked, and our code hasn't yet reached the limits.
* It's important to understand that the goal of adaptive blocking is to smoothly reduce the 'operating' of heavy queries.
*/
coefficient: number;
/**
* Maximum pause (ms)
* Default: 7_000 ms
* Limits the maximum estimated pause time
*/
maxDelay: number;
/**
* Whether adaptive pause is enabled
* Default: true
*/
enabled: boolean;
}
/**
* Rate limiting settings (Leaky Bucket)
*/
interface RateLimitConfig {
/**
* X - limit before blocking (bucket capacity)
* For standard plans: 50
* For Enterprise: 250
*/
burstLimit: number;
/**
* Y - leak rate (requests per second)
* For standard plans: 2
* For Enterprise: 5
*/
drainRate: number;
/**
* Whether adaptive control is enabled
* Default: true
*/
adaptiveEnabled: boolean;
}
/**
* Parameters for managing all types of restrictions
*/
interface RestrictionParams {
rateLimit?: RateLimitConfig;
operatingLimit?: OperatingLimitConfig;
adaptiveConfig?: AdaptiveConfig;
/**
* Maximum number of retries
* Default: 3
*/
maxRetries?: number;
/**
* Base delay between retries (ms)
* Default: 1_000
*/
retryDelay?: number;
/**
* Whether to retry on transport-level errors (`NETWORK_ERROR`, `REQUEST_TIMEOUT`).
*
* Default: `true` — preserves the historical retry behaviour.
*
* Set to `false` for **non-idempotent** calls (e.g. `crm.documentgenerator.document.add`,
* any `*.add` that creates an entity, file uploads). When the request times out
* client-side, the server may still have processed it successfully — retrying then
* creates duplicates. With `retryOnNetworkError: false` the SDK immediately throws
* `NETWORK_ERROR` / `REQUEST_TIMEOUT` instead of retrying.
*
* For long-running heavy operations also raise the axios timeout:
* ```ts
* const clientAxios = $b24.getHttpClient(ApiVersion.v2).ajaxClient
* clientAxios.defaults.timeout = 120_000
* ```
*/
retryOnNetworkError?: boolean;
/**
* Additional error codes that must be thrown as exceptions immediately,
* without any retry. Merged with the SDK's built-in hard list — you can
* only **add** codes, not remove built-ins (auth / fatal codes are always hard).
*
* Use this for business-specific or custom REST methods whose error codes
* the SDK doesn't know about (otherwise the SDK treats unknown codes as
* transient and retries them with backoff).
*
* @example
* ```ts
* await $b24.setRestrictionManagerParams({
* ...ParamsFactory.getDefault(),
* hardErrorCodes: ['DOCUMENT_GENERATOR_ALREADY_IN_QUEUE', 'MY_APP_BAD_PAYLOAD']
* })
* ```
*/
hardErrorCodes?: string[];
/**
* Additional error codes that should be returned inside `AjaxResult` as a
* soft error instead of thrown. Merged with the SDK's built-in soft list.
*
* Use this when your application expects to inspect a specific REST error
* code as part of normal control flow (e.g. validation errors from a
* custom v3 endpoint).
*/
softErrorCodes?: string[];
}
/**
* Limiter operation statistics
*/
interface RestrictionManagerStats {
/** Retries */
retries: number;
/** Consecutive errors */
consecutiveErrors: number;
/** Limit hits */
limitHits: number;
/** Current number of tokens */
tokens: number;
/** Adaptive delays */
adaptiveDelays: number;
/** Total time of adaptive delays */
totalAdaptiveDelay: number;
/** Heavy requests */
heavyRequestCount: number;
/** Method statistics in seconds */
operatingStats: {
[method: string]: number;
};
}
interface ILimiter {
getTitle(): string;
setConfig(config: any): Promise<void>;
setLogger(logger: LoggerInterface): void;
getLogger(): LoggerInterface;
canProceed(requestId: string, method: string, params?: any): Promise<boolean>;
waitIfNeeded(requestId: string, method: string, params?: any): Promise<number>;
updateStats(requestId: string, method: string, data: any): Promise<void>;
reset(): Promise<void>;
getStats(): Record<string, any>;
}
/**
* Abstract Class for working with actions
*/
type ActionOptions = {
[key: string]: any;
};
declare abstract class AbstractAction {
protected _b24: TypeB24;
protected _logger: LoggerInterface;
constructor(b24: TypeB24, logger: LoggerInterface);
/**
* Warns when an option that belongs inside a nested bag was passed at the top
* level, where it is read by nobody.
*
* The action option types no longer carry an index signature, so a TypeScript
* caller writing an object literal gets a compile error instead. This covers
* everyone else: JavaScript callers, a literal widened through a variable, and
* anything crossing a `JSON.parse` boundary. Without it the call simply
* behaves as though the flag were never set — and a dropped
* `returnAjaxResult` turns a batch where every command succeeded into one that
* reads as wholly failed, because `isSuccess` on a raw payload is `undefined`
* (#426).
*
* @param options the argument as received
* @param nestedKeys names that belong in the nested bag
* @param nestedName the bag they belong in, for the message
*/
protected _warnMisplacedOptions(options: object | undefined, nestedKeys: readonly string[], nestedName: string): void;
abstract make(options?: ActionOptions): AsyncGenerator | Promise<unknown>;
}
type ActionCallV2 = {
method: string;
params?: TypeCallParamsV2;
requestId?: string;
};
/**
* Calls the Bitrix24 REST API method `restApi:v2`
*
* Executes a single REST API request against the v2 HTTP client and returns the raw response.
* Unlike `CallListV2`, `FetchListV2`, `BatchV2`, or `BatchByChunkV2`, this class makes exactly
* one HTTP call and returns the result without any pagination or batching logic.
*/
declare class CallV2 extends AbstractAction {
/**
* Calls the Bitrix24 REST API method.
*
* @template T - The expected data type in the response (default is `unknown`).
*
* @param {ActionCallV2} options - parameters for executing the request.
* - `method: string` - REST API method name (eg: `crm.item.get`)
* - `params?: TypeCallParamsV2` - Parameters for calling the method.
* - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging.
*
* @returns {Promise<AjaxResult<T>>} A promise that resolves to the result of an REST API call.
*
* @example
* import { EnumCrmEntityTypeId } from '@bitrix24/b24jssdk'
*
* interface CrmItem { id: number, name: string, lastName: string }
* const response = await b24.actions.v2.call.make<{ item: CrmItem }>({
* method: 'crm.item.get',
* params: {
* entityTypeId: EnumCrmEntityTypeId.contact,
* id: 123
* },
* requestId: 'item-123'
* })
* if (!response.isSuccess) {
* throw new Error(`Problem: ${response.getErrorMessages().join('; ')}`)
* }
* console.log(response.getData().result.item.name)
*/
make<T = unknown>(options: ActionCallV2): Promise<AjaxResult<T>>;
}
type ActionCallListV2 = {
method: string;
params?: Omit<TypeCallParamsV2, 'start' | 'order'>;
idKey?: string;
cursorIdKey?: string;
customKeyForResult?: string;
requestId?: string;
};
/**
* Fast data retrieval without counting the total number of records. `restApi:v2`
*
* Iterates through all pages of a v2 list method using cursor-based pagination (ordering and
* filtering by the item id) and collects every item into a single array returned as a `Result`.
* Unlike `FetchListV2`, which yields pages one by one via an async generator, this class waits
* for all pages to finish and returns the complete dataset in one call.
*/
declare class CallListV2 extends AbstractAction {
/**
* Fast data retrieval without counting the total number of records.
*
* @template T - The type of the elements of the returned array (default is `unknown`).
*
* @param {ActionCallListV2} options - parameters for executing the request.
* - `method: string` - The name of the REST API method that returns a list of data (for example: `crm.item.list`, `tasks.task.list`)
* - `params?: Omit<TypeCallParamsV2, 'start' | 'order'>` - Request parameters, excluding the `start` and `order` parameters,
* since the method is designed to obtain all data in one call.
* Note: Use `filter`, `order`, and `select` to control the selection.
* - `idKey?: string` - The name of the id field as it appears in each RESPONSE item; its value
* drives the cursor. Default is 'ID' (uppercase). For methods that return a lowercase /
* camelCase id (for example `tasks.task.list` returns `id`), set `idKey: 'id'`.
* - `cursorIdKey?: string` - The field name used in the REQUEST for `order` and the `>` page
* filter. Defaults to `idKey`. Set it only when the sortable / filterable field name differs
* from the response field name — e.g. `tasks.task.list` sorts and filters by `ID` (uppercase)
* but returns `id` (lowercase): pass `idKey: 'id', cursorIdKey: 'ID'`.
* - `customKeyForResult?: string` - A custom key indicating that the response REST API will be
* grouped by this field.
* Example: `items` to group a list of CRM items.
* - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging.
*
* @returns {Promise<Result<T[]>>} A promise that resolves to the result of an REST API call.
*
* @example
* import { EnumCrmEntityTypeId, Text } from '@bitrix24/b24jssdk'
*
* interface CrmItem { id: number, title: string }
* const sixMonthAgo = new Date()
* sixMonthAgo.setMonth((new Date()).getMonth() - 6)
* sixMonthAgo.setHours(0, 0, 0)
* const response = await b24.actions.v2.callList.make<CrmItem>({
* method: 'crm.item.list',
* params: {
* entityTypeId: EnumCrmEntityTypeId.company,
* filter: {
* '=%title': 'A%',
* '>=createdTime': Text.toB24Format(sixMonthAgo) // created at least 6 months ago
* },
* select: ['id', 'title']
* },
* idKey: 'id',
* customKeyForResult: 'items',
* requestId: 'list-123'
* })
* if (!response.isSuccess) {
* throw new Error(`Problem: ${response.getErrorMessages().join('; ')}`)
* }
* const list = response.getData()
* console.log(`Result: ${list?.length}`) // Number of items received
*/
make<T = unknown>(options: ActionCallListV2): Promise<Result<T[]>>;
}
type ActionFetchListV2 = {
method: string;
params?: Omit<TypeCallParamsV2, 'start' | 'order'>;
idKey?: string;
cursorIdKey?: string;
customKeyForResult?: string;
requestId?: string;
};
/**
* Calls a REST API list method and returns an async generator for efficient large data retrieval. `restApi:v2`
*
* Iterates through all pages of a v2 list method using cursor-based pagination and yields each
* page as an array, allowing callers to process records incrementally without holding the entire
* dataset in memory. Unlike `CallListV2`, which accumulates all pages before returning, this
* class exposes an `AsyncGenerator` so processing can begin as soon as the first page arrives.
*/
declare class FetchListV2 extends AbstractAction {
/**
* Calls a REST API list method and returns an async generator for efficient large data retrieval.
* Implements the fast algorithm for iterating over large datasets without loading all data into memory at once.
*
* @template T - The type of items in the returned arrays (default is `unknown`).
*
* @param {ActionFetchListV2} options - parameters for executing the request.
* - `method: string` - The name of the REST API method that returns a list of data (for example: `crm.item.list`, `tasks.task.list`)
* - `params?: Omit<TypeCallParamsV2, 'start' | 'order'>` - Request parameters, excluding the `start` and `order` parameters,
* since the method is designed to obtain all data in one call.
* Note: Use `filter`, `order`, and `select` to control the selection.
* - `idKey?: string` - The name of the id field as it appears in each RESPONSE item; its value
* drives the cursor. Default is 'ID' (uppercase). For methods that return a lowercase /
* camelCase id (for example `tasks.task.list` returns `id`), set `idKey: 'id'`.
* - `cursorIdKey?: string` - The field name used in the REQUEST for `order` and the `>` page
* filter. Defaults to `idKey`. Set it only when the sortable / filterable field name differs
* from the response field name — e.g. `tasks.task.list` sorts and filters by `ID` (uppercase)
* but returns `id` (lowercase): pass `idKey: 'id', cursorIdKey: 'ID'`.
* - `customKeyForResult?: string` - A custom key indicating that the response REST API will be
* grouped by this field.
* Example: `items` to group a list of CRM items.
* - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging.
*
* @returns {AsyncGenerator<T[]>} An async generator that yields chunks of data as arrays of type `T`.
* Each iteration returns the next page/batch of results until all data is fetched.
*
* @example
* import { EnumCrmEntityTypeId, Text } from '@bitrix24/b24jssdk'
*
* interface CrmItem { id: number, title: string }
* const sixMonthAgo = new Date()
* sixMonthAgo.setMonth((new Date()).getMonth() - 6)
* sixMonthAgo.setHours(0, 0, 0)
* const generator = b24.actions.v2.fetchList.make<CrmItem>({
* method: 'crm.item.list',
* params: {
* entityTypeId: EnumCrmEntityTypeId.company,
* filter: {
* '=%title': 'A%',
* '>=createdTime': Text.toB24Format(sixMonthAgo) // created at least 6 months ago
* },
* select: ['id', 'title']
* },
* idKey: 'id',
* customKeyForResult: 'items',
* requestId: 'list-123'
* })
*
* for await (const chunk of generator) {
* // Process chunk (e.g., save to database, analyze, etc.)
* console.log(`Processing ${chunk.length} items`)
* }
*
* @see {@link https://apidocs.bitrix24.com/settings/performance/huge-data.html Bitrix24: Fast algorithm for large data}
*/
make<T = unknown>(options: ActionFetchListV2): AsyncGenerator<T[]>;
}
declare abstract class AbstractBatch extends AbstractAction {
protected _addBatchErrorsIfAny(response: Result<ICallBatchResult<any>>, result: Result): void;
protected _processBatchResponse<T>(response: Result<ICallBatchResult<T>>, calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal | BatchNamedCommandsUniversal, options: IB24BatchOptions): CallBatchResult<T>;
protected _createBatchResultWithAjax<T>(response: Result<ICallBatchResult<T>>, isArrayCall: boolean): CallBatchResult<T>;
protected _createBatchArrayResult<T>(response: Result<ICallBatchResult<T>>): Result<AjaxResult<T>[]>;
protected _createBatchObjectResult<T>(response: Result<ICallBatchResult<T>>): Result<Record<string | number, AjaxResult<T>>>;
protected _createBatchResultSimple<T>(response: Result<ICallBatchResult<T>>, isArrayCall: boolean): CallBatchResult<T>;
protected _extractBatchSimpleData<T>(response: Result<ICallBatchResult<T>>, isArrayCall: boolean): T;
chunkArray<T = unknown>(array: Array<T>, chunkSize?: number): T[][];
}
type ActionBatchV2 = {
calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal | BatchNamedCommandsUniversal;
options?: IB24BatchOptions;
};
/**
* Executes a batch request to the Bitrix24 REST API with a maximum number of commands of no more than 50. `restApi:v2`
* Allows you to execute multiple requests in a single API call, significantly improving performance.
*
* Sends up to 50 commands in a single v2 batch HTTP call and returns their results together.
* Supports array, object, and named-command formats. Unlike `BatchByChunkV2`, it does not
* split large command sets automatically — callers must ensure the command count stays within
* the 50-command limit.
*/
declare class BatchV2 extends AbstractBatch {
/**
* Executes a batch request to the Bitrix24 REST API with a maximum number of commands of no more than 50.
* Allows you to execute multiple requests in a single API call, significantly improving performance.
*
* @template T - The data type returned by batch query commands (default is `unknown`)
*
* @param {ActionBatchV2} options - parameters for executing the request.
* - `calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal | BatchNamedCommandsUniversal` - Commands to execute in a batch.
* Supports several formats:
* 1. Array of tuples: `[['method1', params1], ['method2', params2], ...]`
* 2. Array of objects: `[{ method: 'method1', params: params1 }, { method: 'method2', params: params2 }, ...]`
* 3. An object with named commands: `{ cmd1: { method: 'method1', params: params1 }, cmd2: ['method2', params2], ...}`
* - `options?: IB24BatchOptions` - Additional options for executing a batch request.
* - `isHaltOnError?: boolean` - Whether to stop execution on the first error (default: true)
* - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging (default: undefined)
* - `returnAjaxResult?: boolean` - Whether to return an AjaxResult object instead of data (default: false)
*
* @returns {Promise<CallBatchResult<T>>} A promise that is resolved by the result of executing a batch request:
* - On success: a `Result` object with the command execution results
* - The structure of the results depends on the format of the `calls` input data:
* - For an array of commands, an array of results in the same order
* - For named commands, an object with keys corresponding to the command names
*
* @example
* import { EnumCrmEntityTypeId } from '@bitrix24/b24jssdk'
*
* interface Contact { id: number, name: string }
* const response = await b24.actions.v2.batch.make<{ item: Contact }>({
* calls: [
* ['crm.item.get', { entityTypeId: EnumCrmEntityTypeId.contact, id: 1 }],
* ['crm.item.get', { entityTypeId: EnumCrmEntityTypeId.contact, id: 2 }],
* ['crm.item.get', { entityTypeId: EnumCrmEntityTypeId.contact, id: 3 }]
* ],
* options: {
* isHaltOnError: true,
* returnAjaxResult: true,
* requestId: 'batch-123'
* }
* })
* if (!response.isSuccess) {
* throw new Error(`Problem: ${response.getErrorMessages().join('; ')}`)
* }
*
* const resultData = (response as Result<AjaxResult<{ item: Contact }>[]>).getData()
* resultData.forEach((resultRow, index) => {
* if (resultRow.isSuccess) {
* console.log(`Item ${index + 1}:`, resultRow.getData()!.result.item)
* }
* })
*
* @example
* import { EnumCrmEntityTypeId } from '@bitrix24/b24jssdk'
*
* const response = await b24.actions.v2.batch.make({
* calls: [
* { method: 'crm.item.get', params: { entityTypeId: EnumCrmEntityTypeId.contact, id: 1 } },
* { method: 'crm.item.get', params: { entityTypeId: EnumCrmEntityTypeId.contact, id: 2 } }
* ],
* options: {
* isHaltOnError: true,
* returnAjaxResult: true,
* requestId: 'batch-123'
* }
* })
* if (!response.isSuccess) {
* throw new Error(`Problem: ${response.getErrorMessages().join('; ')}`)
* }
*
* @example
* import { EnumCrmEntityTypeId } from '@bitrix24/b24jssdk'
*
* interface Contact { id: number, name: string }
* interface Deal { id: number, title: string }
* const response = await b24.actions.v2.batch.make<{ item: Contact } | { item: Deal }>({
* calls: {
* Contact: { method: 'crm.item.get', params: { entityTypeId: EnumCrmEntityTypeId.contact, id: 1 } },
* Deal: ['crm.item.get', { entityTypeId: EnumCrmEntityTypeId.deal, id: 2 }]
* },
* options: {
* isHaltOnError: true,
* returnAjaxResult: true,
* requestId: 'batch-123'
* }
* })
* if (!response.isSuccess) {
* throw new Error(`Problem: ${response.getErrorMessages().join('; ')}`)
* }
*
* const results = response.getData() as Record<string, AjaxResult<{ item: Contact } | { item: Deal }>>
* console.log('Contact:', results.Contact.getData()?.result.item as Contact)
* console.log('Deal:', results.Deal.getData()?.result.item as Deal)
*
* @warning The maximum number of commands in one batch request is 50.
* @note A batch request executes faster than sequential single calls,
* but if one command fails, the entire batch may fail
* (depending on API settings and options).
*/
make<T = unknown>(options: ActionBatchV2): Promise<CallBatchResult<T>>;
}
type ActionBatchByChunkV2 = {
calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal;
options?: Omit<IB24BatchOptions, 'returnAjaxResult'>;
};
/**
* Executes a batch request with automatic chunking for any number of commands. `restApi:v2`
*
* Splits an arbitrarily large command list into sequential chunks of up to 50 and sends each
* chunk as a separate v2 batch call, merging successful results into a flat array. Unlike
* `BatchV2`, there is no 50-command ceiling for the caller, but named commands are not supported
* because they cannot be reliably merged across chunk boundaries.
*/
declare class BatchByChunkV2 extends AbstractBatch {
/**
* Executes a batch request with automatic chunking for any number of commands.
* Unlike `BatchV2`, which is limited to 50 commands, this method automatically splits
* a large set of commands into multiple batches and executes them sequentially.
*
* @template T - The data type returned by commands (default: `unknown`)
*
* @param {ActionBatchByChunkV2} options - parameters for executing the request.
* - `calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal` - Commands to execute in a batch.
* Supports several formats:
* 1. Array of tuples: `[['method1', params1], ['method2', params2], ...]`
* 2. Array of objects: `[{ method: 'method1', params: params1 }, { method: 'method2', params: params2 }, ...]`
* - Note: Named commands are not supported as they are difficult to process when chunking.
* - `options?: Omit<IB24BatchOptions, 'returnAjaxResult'>` - Additional options for executing a batch request.
* - `isHaltOnError?: boolean` - Whether to stop execution on the first error (default: true)
* - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging (default: undefined)
*
* @returns {Promise<Result<T[]>>} A promise that is resolved by the result of executing all commands.
*
* @example
* import { EnumCrmEntityTypeId, Text } from '@bitrix24/b24jssdk'
*
* interface Contact { id: number, name: string }
* const commands = Array.from({ length: 150 }, (_, i) =>
* ['crm.item.get', { entityTypeId: EnumCrmEntityTypeId.contact, id: i + 1 }]
* )
*
* const response = await b24.actions.v2.batchByChunk.make<{ item: Contact }>({
* calls: commands,
* options: {
* isHaltOnError: false,
* requestId: 'batch-by-chunk-123'
* }
* })
*
* if (!response.isSuccess) {
* throw new Error(`Problem: ${response.getErrorMessages().join('; ')}`)
* }
*
* const resultData = response.getData()
* const items: Contact[] = []
* resultData.forEach((chunkRow) => {
* items.push(chunkRow.item)
* })
* console.log(`Successfully retrieved ${items.length} items`)
*
* @tip For very large command sets, consider using server-side task queues instead of bulk batch requests.
*/
make<T = unknown>(options: ActionBatchByChunkV2): Promise<Result<T[]>>;
}
/**
* Some actions for TypeB24 by Api:v2
*/
declare class ActionsManagerV2 {
protected _b24: TypeB24;
protected _logger: LoggerInterface;
protected _mapActions: Map<symbol, AbstractAction>;
constructor(b24: TypeB24);
setLogger(logger: LoggerInterface): void;
getLogger(): LoggerInterface;
get call(): CallV2;
get callList(): CallListV2;
get fetchList(): FetchListV2;
get batch(): BatchV2;
get batchByChunk(): BatchByChunkV2;
}
type ActionCallV3 = {
method: string;
params?: TypeCallParamsV3;
requestId?: string;
};
/**
* Calls the Bitrix24 REST API method `restApi:v3`
*
* Executes a single REST API request against the v3 HTTP client and returns the raw response.
* Unlike its v2 counterpart `CallV2`, it routes through the v3 endpoint without a client-side
* method allowlist — the server validates the method and returns `METHODNOTFOUNDEXCEPTION` for
* unknown ones. Like `CallV2`, it makes exactly one HTTP call with no pagination or batching.
*/
declare class CallV3 extends AbstractAction {
/**
* Calls the Bitrix24 REST API method.
*
* @template T - The expected data type in the response (default is `unknown`).
*
* @param {ActionCallV3} options - parameters for executing the request.
* - `method: string` - REST API method name (eg: `crm.item.get`)
* - `params?: TypeCallParamsV3` - Parameters for calling the method.
* - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging.
*
* @returns {Promise<AjaxResult<T>>} A promise that resolves to the result of an REST API call.
*
* @example
* interface TaskItem { id: number, title: string }
* const response = await b24.actions.v3.call.make<{ item: TaskItem }>({
* method: 'tasks.task.get',
* params: { id: 123, select: ['id', 'title'] },
* requestId: 'task-123'
* })
* if (!response.isSuccess) {
* throw new Error(`Problem: ${response.getErrorMessages().join('; ')}`)
* }
* console.log(response.getData().result.item.title)
*/
make<T = unknown>(options: ActionCallV3): Promise<AjaxResult<T>>;
}
type ActionCallListV3 = {
method: string;
/**
* `filter` is narrowed to the v3 array form here, unlike {@link TypeCallParamsV3},
* which also accepts the v2 object dialect for backward compatibility.
*
* Keyset pagination is emulated by appending `[cursorIdKey, '>', cursor]` to
* this filter on every page, so an array is not a preference — it is the only
* shape the mechanism can extend. The object form used to be accepted here and
* then threw `filter is not iterable` at runtime, one page into the walk.
*/
params?: Omit<TypeCallParamsV3, 'pagination' | 'order' | 'filter'> & {
filter?: TypeFilterV3;
};
idKey?: string;
cursorIdKey?: string;
customKeyForResult: string;
requestId?: string;
limit?: number;
};
/**
* Fast data retrieval without counting the total number of records. `restApi:v3`
*
* Iterates through all pages of a v3 list method using keyset (cursor) pagination and collects
* every item into a single array returned as a `Result`. Unlike the v2 counterpart `CallListV2`,
* it uses v3-style array filter syntax and supports the `limit` option (the server enforces its own per-method maximum, commonly 1000).
* Unlike `FetchListV3`, which streams pages via an async generator, this class returns the
* complete dataset in one awaited call.
*/
declare class CallListV3 extends AbstractAction {
/**
* Fast data retrieval without counting the total number of records.
*
* @template T - The type of the elements of the returned array (default is `unknown`).
*
* @param {ActionCallListV3} options - parameters for executing the request.
* - `method: string` - The name of the REST API method that returns a list of data (for example: `crm.item.list`, `tasks.task.list`)
* - `params?: Omit<TypeCallParamsV3, 'pagination' | 'order'>` - Request parameters, excluding the `pagination` and `order` parameters,
* since the method is designed to obtain all data in one call.
* Note: Use `filter`, `order`, and `select` to control the selection.
* - `idKey?: string` - The name of the id field as it appears in each RESPONSE item; its value
* drives the cursor. Default is 'id'. Set it to match the id field the method returns.
* - `cursorIdKey?: string` - The field 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'`.
* - `customKeyForResult: string` - A custom key indicating that the response REST API will be
* grouped by this field.
* Example: `items` to group a list of CRM items.
* - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging.
* - `limit?: number` - How many records to retrieve at a time. Default is `50`. Maximum is `1000`.
*
* @returns {Promise<Result<T[]>>} A promise that resolves to the result of an REST API call.
*
* @example
* import { Text } from '@bitrix24/b24jssdk'
*
* interface MainEventLogItem { id: number, userId: number }
* 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: 'eventlog-123',
* limit: 60
* })
* if (!response.isSuccess) {
* throw new Error(`Problem: ${response.getErrorMessages().join('; ')}`)
* }
* const list = response.getData()
* console.log(`Result: ${list?.length}`) // Number of items received
*/
make<T = unknown>(options: ActionCallListV3): Promise<Result<T[]>>;
}
type ActionFetchListV3 = {
method: string;
/**
* `filter` is narrowed to the v3 array form here, unlike {@link TypeCallParamsV3},
* which also accepts the v2 object dialect for backward compatibility.
*
* Keyset pagination is emulated by appending `[cursorIdKey, '>', cursor]` to
* this filter on every page, so an array is not a preference — it is the only
* shape the mechanism can extend. The object form used to be accepted here and
* then threw `filter is not iterable` at runtime, one page into the walk.
*/
params?: Omit<TypeCallParamsV3, 'pagination' | 'order' | 'filter'> & {
filter?: TypeFilterV3;
};
idKey?: string;
cursorIdKey?: string;
customKeyForResult: string;
requestId?: string;
limit?: number;
};
/**
* Calls a REST API list method and returns an async generator for efficient large data retrieval. `restApi:v3`
*
* Iterates through all pages of a v3 list method using keyset (cursor) pagination and yields
* each page as an array, allowing callers to process records incrementally without holding the
* entire dataset in memory. Unlike `CallListV3`, which accumulates all pages before returning,
* this class exposes an `AsyncGenerator` so processing can begin as soon as the first page
* arrives. Compared to `FetchListV2`, it uses v3-style array filter syntax and supports the
* `limit` option (up to 1000 per page).
*/
declare class FetchListV3 extends AbstractAction {
/**
* Calls a REST API list method and returns an async generator for efficient large data retrieval.
* Implements the fast algorithm for iterating over large datasets without loading all data into memory at once.
*
* @template T - The type of items in the returned arrays (default is `unknown`).
*
* @param {ActionFetchListV3} options - parameters for executing the request.
* - `method: string` - The name of the REST API method that returns a list of data (for example: `crm.item.list`, `tasks.task.list`)
* - `params?: Omit<TypeCallParamsV3, 'pagination' | 'order'>` - Request parameters, excluding the `pagination` and `order` parameters,
* since the method is designed to obtain all data in one call.
* Note: Use `filter`, `order`, and `select` to control the selection.
* - `idKey?: string` - The name of the id field as it appears in each RESPONSE item; its value
* drives the cursor. Default is 'id'. Set it to match the id field the method returns.
* - `cursorIdKey?: string` - The field 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'`.
* - `customKeyForResult: string` - A custom key indicating that the response REST API will be
* grouped by this field.
* Example: `items` to group a list of CRM items.
* - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging.
* - `limit?: number` - How many records to retrieve at a time. Default is `50`. Maximum is `1000`.
*
* @returns {AsyncGenerator<T[]>} An async generator that yields chunks of data as arrays of type `T`.
* Each iteration returns the next page/batch of results until all data is fetched.
*
* @example
* import { Text } from '@bitrix24/b24jssdk'
*
* interface MainEventLogItem { id: number, userId: number }
* const sixMonthAgo = new Date()
* sixMonthAgo.setMonth((new Date()).getMonth() - 6)
* sixMonthAgo.setHours(0, 0, 0)
* const generator = b24.actions.v3.fetchList.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: 'eventlog-123',
* limit: 60
* })
*
* for await (const chunk of generator) {
* // Process chunk (e.g., save to database, analyze, etc.)
* console.log(`Processing ${chunk.length} items`)
* }
*/
make<T = unknown>(options: ActionFetchListV3): AsyncGenerator<T[]>;
}
type ActionCallTailV3 = {
method: string;
params?: Omit<TypeCallParamsV3, 'pagination' | 'order' | 'cursor'>;
cursorField?: string;
order?: 'ASC' | 'DESC' | 'asc' | 'desc' | string;
customKeyForResult?: string;
requestId?: string;
limit?: number;
initialValue?: number | string;
};
/**
* Fast data retrieval via the native `tail` (keyset cursor) action, without
* counting the total number of records. `restApi:v3`
*
* The eager counterpart of `fetchTail`: it walks the same native
* `cursor: { field, value, order, limit }` pagination and returns every record
* as a single array. See the v3 reference §6.2. The cursor field MUST NOT appear
* in `filter`.
*/
declare class CallTailV3 extends AbstractAction {
/**
* Returns every record of a `tail` method as one array.
*
* @template T - The type of the elements of the returned array (default is `unknown`).
*
* @param {ActionCallTailV3} options - parameters for executing the request.
* - `method: string` - A REST API `tail` method name (for example: `main.eventlog.tail`).
* - `params?: Omit<TypeCallParamsV3, 'pagination' | 'order' | 'cursor'>` - Request parameters
* (`filter`, `select`). `pagination`, `order` and `cursor` are managed by this helper.
* The cursor field must NOT be used in `filter`.
* - `cursorField?: string` - The DTO field that drives the cursor. Default is `id`.
* - `order?: 'ASC' | 'DESC'` - Cursor direction. Default is `ASC`. For `DESC` you MUST pass
* `initialValue` (the server pages by `field < value`, so the default `0` returns nothing).
* - `customKeyForResult?: string` - The key the response groups rows under. Default is `items`.
* - `requestId?: string` - Unique request identifier for tracking.
* - `limit?: number` - How many records to retrieve at a time. Default is `50`. Maximum is `1000`.
* - `initialValue?: number | string` - Cursor start value for the first page. Default is `0`
* (valid for ascending numeric fields); required for `DESC` and for non-numeric fields.
*
* @returns {Promise<Result<T[]>>} A promise that resolves to the result of an REST API call.
*
* @example
* const response = await b24.actions.v3.callTail.make<{ id: string }>({
* method: 'main.eventlog.tail',
* params: { select: ['id', 'auditType'] },
* cursorField: 'id',
* customKeyForResult: 'items'
* })
* if (!response.isSuccess) {
* throw new Error(`Problem: ${response.getErrorMessages().join('; ')}`)
* }
* console.log(`Result: ${response.getData()?.length}`)
*/
make<T = unknown>(options: ActionCallTailV3): Promise<Result<T[]>>;
}
type ActionFetchTailV3 = {
method: string;
params?: Omit<TypeCallParamsV3, 'pagination' | 'order' | 'cursor'>;
cursorField?: string;
order?: 'ASC' | 'DESC' | 'asc' | 'desc' | string;
customKeyForResult?: string;
requestId?: string;
limit?: number;
initialValue?: number | string;
};
/**
* Calls a REST API `tail` method (native keyset cursor) and returns an async
* generator for efficient large data retrieval. `restApi:v3`
*
* Unlike `fetchList`, which emulates keyset pagination on top of the `list`
* action by injecting a `[field, '>', n]` filter, this helper drives the server
* `tail` action with its native `cursor: { field, value, order, limit }`
* parameter (see the v3 reference §6.2). The server itself adds `field > value`
* (asc) / `field < value` (desc) and sorts by `field`, so the cursor field
* MUST NOT appear in `filter` (the server rejects it with
* `INVALIDFILTEREXCEPTION`).
*/
declare class FetchTailV3 extends AbstractAction {
/**
* Streams every record of a `tail` method as chunks, advancing the keyset
* cursor between requests.
*
* @template T - The type of items in the returned arrays (default is `unknown`).
*
* @param {ActionFetchTailV3} options - parameters for executing the request.
* - `method: string` - A REST API `tail` method name (for example: `main.eventlog.tail`).
* - `params?: Omit<TypeCallParamsV3, 'pagination' | 'order' | 'cursor'>` - Request parameters.
* Use `filter` and `select` to control the selection. `pagination`, `order` and `cursor`
* are managed by this helper and must not be passed. The cursor field must NOT be used in `filter`.
* - `cursorField?: string` - The DTO field that drives the cursor. Must be monotonic and
* preferably unique, and present in `select`. Default is `id`.
* - `order?: 'ASC' | 'DESC'` - Cursor direction. Default is `ASC`. For `DESC` you MUST pass
* `initialValue` (the server pages by `field < value`, so the default `0` returns nothing).
* - `customKeyForResult?: string` - The key the response groups rows under. Default is `items`.
* - `requestId?: string` - Unique request identifier for tracking.
* - `limit?: number` - How many records to retrieve at a time. Default is `50`. Maximum is `1000`.
* - `initialValue?: number | string` - Cursor start value for the first page. Default is `0`
* (valid for ascending numeric fields); required for `DESC` and for non-numeric fields.
*
* @returns {AsyncGenerator<T[]>} An async generator that yields chunks of data as arrays of type `T`.
*
* @example
* const generator = b24.actions.v3.fetchTail.make<{ id: string }>({
* method: 'main.eventlog.tail',
* params: { select: ['id', 'auditType'] },
* cursorField: 'id',
* customKeyForResult: 'items'
* })
* for await (const chunk of generator) {
* console.log(`Processing ${chunk.length} items`)
* }
*/
make<T = unknown>(options: ActionFetchTailV3): AsyncGenerator<T[]>;
}
/**
* The six aggregate functions the v3 `aggregate` action accepts (reference §7).
* Anything else is rejected server-side with `UNKNOWNAGGREGATEFUNCTIONEXCEPTION`.
*/
type AggregateFunctionV3 = 'sum' | 'avg' | 'min' | 'max' | 'count' | 'countDistinct';
/**
* Per-function field selection. Two forms (reference §7):
* - list: `['amount', 'qty']` — default alias `<func>_<field>`;
* - map: `{ amount: 'totalAmount' }` — custom alias.
* Note: the response keys buckets by the **field name**, not the alias.
*/
type AggregateSelectV3 = Partial<Record<AggregateFunctionV3, string[] | Record<string, string>>>;
/**
* Aggregate response buckets: `{ sum: { amount: 12345 }, count: { id: 87 } }`.
* Keyed by function, then by field name.
*/
type AggregateResultV3 = Partial<Record<AggregateFunctionV3, Record<string, number>>>;
/** @experimental options for the v3 `aggregate` action — unverified live (see {@link AggregateV3}). */
type ActionAggregateV3 = {
method: string;
select: AggregateSelectV3;
params?: Pick<TypeCallParamsV3, 'filter'>;
requestId?: string;
};
/**
* Runs the v3 `aggregate` action for modules that support it (reference §7).
* `restApi:v3`
*
* @experimental NOT verified against a live portal — no module on the SDK's
* reference test portal currently exposes an `*.aggregate` endpoint. The
* request/response shapes follow the published v3 reference and may change once
* verified live; pin to a version if you depend on the exact shape.
*/
declare class AggregateV3 extends AbstractAction {
/**
* @param {ActionAggregateV3} options
* - `method: string` - an `*.aggregate` method name.
* - `select: AggregateSelectV3` - per-function field selection (`sum`/`avg`/`min`/`max`/`count`/`countDistinct`).
* - `params?: { filter }` - optional v3 filter (array-of-triples; use `FilterV3` to build it).
* - `requestId?: string` - tracking id.
*
* @returns {Promise<Result<AggregateResultV3>>} buckets keyed by function then field name.
*
* @example
* const response = await b24.actions.v3.aggregate.make({
* method: 'some.entity.aggregate',
* select: { sum: { amount: 'totalAmount' }, count: ['id'] },
* params: { filter: FilterV3.build(FilterV3.eq('status', 'NEW')) }
* })
* if (response.isSuccess) {
* const total = response.getData()?.sum?.amount
* }
*/
make(options: ActionAggregateV3): Promise<Result<AggregateResultV3>>;
}
type ActionBatchV3 = {
calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal | BatchNamedCommandsUniversal;
options?: IB24BatchOptions;
};
/**
* Executes a batch request to the Bitrix24 REST API with a maximum number of commands of no more than 50. `restApi:v3`
* Allows you to execute multiple requests in a single API call, significantly improving performance.
*
* Sends up to 50 commands in a single v3 batch HTTP call and returns their results together.
* Supports array, object, and named-command formats. Unlike `BatchByChunkV3`, it does not split
* large command sets automatically — callers must keep the command count within the 50-command
* limit. Compared to `BatchV2`, it routes through the v3 endpoint without a client-side method
* allowlist.
*/
declare class BatchV3 extends AbstractBatch {
/**
* Executes a batch request to the Bitrix24 REST API with a maximum number of commands of no more than 50.
* Allows you to execute multiple requests in a single API call, significantly improving performance.
*
* @template T - The data type returned by batch query commands (default is `unknown`)
*
* @param {ActionBatchV3} options - parameters for executing the request.
* - `calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal | BatchNamedCommandsUniversal` - Commands to execute in a batch.
* Supports several formats:
* 1. Array of tuples: `[['method1', params1], ['method2', params2], ...]`
* 2. Array of objects: `[{ method: 'method1', params: params1 }, { method: 'method2', params: params2 }, ...]`
* 3. An object with named commands: `{ cmd1: { method: 'method1', params: params1 }, cmd2: ['method2', params2], ...}`
* - `options?: IB24BatchOptions` - Additional options for executing a batch request.
* - `isHaltOnError?: boolean` - Whether to stop execution on the first error (default: true)
* - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging (default: undefined)
* - `returnAjaxResult?: boolean` - Whether to return an AjaxResult object instead of data (default: false)
*
* @returns {Promise<CallBatchResult<T>>} A promise that is resolved by the result of executing a batch request:
* - On success: a `Result` object with the command execution results
* - The structure of the results depends on the format of the `calls` input data:
* - For an array of commands, an array of results in the same order
* - For named commands, an object with keys corresponding to the command names
*
* @example
* interface TaskItem { id: number, title: string }
* const response = await b24.actions.v3.batch.make<{ item: TaskItem }>({
* calls: [
* ['tasks.task.get', { id: 1, select: ['id', 'title'] }],
* ['tasks.task.get', { id: 2, select: ['id', 'title'] }],
* ['tasks.task.get', { id: 3, select: ['id', 'title'] }]
* ],
* options: {
* isHaltOnError: true,
* returnAjaxResult: true,
* requestId: 'batch-123'
* }
* })
* if (!response.isSuccess) {
* throw new Error(`Problem: ${response.getErrorMessages().join('; ')}`)
* }
*
* const resultData = (response as Result<AjaxResult<{ item: TaskItem }>[]>).getData()
* resultData.forEach((resultRow, index) => {
* if (resultRow.isSuccess) {
* console.log(`Item ${index + 1}:`, resultRow.getData()!.result.item)
* }
* })
*
* @example
* const response = await b24.actions.v3.batch.make({
* calls: [
* { method: 'tasks.task.get', params: { id: 1, select: ['id', 'title'] } },
* { method: 'tasks.task.get', params: { id: 2, select: ['id', 'title'] } }
* ],
* options: {
* isHaltOnError: true,
* returnAjaxResult: true,
* requestId: 'batch-123'
* }
* })
* if (!response.isSuccess) {
* throw new Error(`Problem: ${response.getErrorMessages().join('; ')}`)
* }
*
* @example
* interface TaskItem { id: number, title: string }
* interface MainEventLogItem { id: number, userId: number }
* const response = await b24.actions.v3.batch.make<{ item: TaskItem } | { items: MainEventLogItem[] }>({
* calls: {
* Task: { method: 'tasks.task.get', params: { id: 1, select: ['id', 'title'] } },
* MainEventLog: ['main.eventlog.list', { select: ['id', 'userId'], pagination: { limit: 5 } }]
* },
* options: {
* isHaltOnError: true,
* returnAjaxResult: true,
* requestId: 'batch-123'
* }
* })
* if (!response.isSuccess) {
* throw new Error(`Problem: ${response.getErrorMessages().join('; ')}`)
* }
*
* const results = response.getData() as Record<string, AjaxResult<{ item: TaskItem } | { items: MainEventLogItem[] }>>
* console.log('Task:', results.Task.getData()?.result.item as TaskItem)
* console.log('MainEventLog:', results.MainEventLog.getData()?.result.items as MainEventLogItem[])
*
* @warning The maximum number of commands in one batch request is 50.
* @note A batch request executes faster than sequential single calls,
* but if one command fails, the entire batch may fail
* (depending on API settings and options).
*/
make<T = unknown>(options: ActionBatchV3): Promise<CallBatchResult<T>>;
}
type ActionBatchByChunkV3 = {
calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal;
options?: Omit<IB24BatchOptions, 'returnAjaxResult'>;
};
/**
* Executes a batch request with automatic chunking for any number of commands. `restApi:v3`
*
* Splits an arbitrarily large command list into sequential chunks of up to 50 and sends each
* chunk as a separate v3 batch call, merging successful results into a flat array. Unlike
* `BatchV3`, there is no 50-command ceiling for the caller, but named commands are not supported
* because they cannot be reliably merged across chunk boundaries.
*/
declare class BatchByChunkV3 extends AbstractBatch {
/**
* Executes a batch request with automatic chunking for any number of commands.
* Unlike `BatchV3`, which is limited to 50 commands, this method automatically splits
* a large set of commands into multiple batches and executes them sequentially.
*
* @template T - The data type returned by commands (default: `unknown`)
*
* @param {ActionBatchByChunkV3} options - parameters for executing the request.
* - `calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal` - Commands to execute in a batch.
* Supports several formats:
* 1. Array of tuples: `[['method1', params1], ['method2', params2], ...]`
* 2. Array of objects: `[{ method: 'method1', params: params1 }, { method: 'method2', params: params2 }, ...]`
* - Note: Named commands are not supported as they are difficult to process when chunking.
* - `options?: Omit<IB24BatchOptions, 'returnAjaxResult'>` - Additional options for executing a batch request.
* - `isHaltOnError?: boolean` - Whether to stop execution on the first error (default: true)
* - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging (default: undefined)
*
* @returns {Promise<Result<T[]>>} A promise that is resolved by the result of executing all commands.
*
* @example
* interface TaskItem { id: number, title: string }
* const commands: BatchCommandsArrayUniversal = Array.from({ length: 150 }, (_, i) =>
* ['tasks.task.get', { id: i + 1, select: ['id', 'title'] }]
* )
*
* const response = await b24.actions.v3.batchByChunk.make<{ item: TaskItem }>({
* calls: commands,
* options: {
* isHaltOnError: false,
* requestId: 'batch-by-chunk-123'
* }
* })
*
* if (!response.isSuccess) {
* throw new Error(`Problem: ${response.getErrorMessages().join('; ')}`)
* }
*
* const resultData = response.getData()
* const items: TaskItem[] = []
* resultData.forEach((chunkRow) => {
* items.push(chunkRow.item)
* })
* console.log(`Successfully retrieved ${items.length} items`)
*
* @tip For very large command sets, consider using server-side task queues instead of bulk batch requests.
*/
make<T = unknown>(options: ActionBatchByChunkV3): Promise<Result<T[]>>;
}
/**
* Some actions for TypeB24 by Api:v3
*/
declare class ActionsManagerV3 {
protected _b24: TypeB24;
protected _logger: LoggerInterface;
protected _mapActions: Map<symbol, AbstractAction>;
constructor(b24: TypeB24);
setLogger(logger: LoggerInterface): void;
getLogger(): LoggerInterface;
get call(): CallV3;
get callList(): CallListV3;
get fetchList(): FetchListV3;
get callTail(): CallTailV3;
get fetchTail(): FetchTailV3;
get aggregate(): AggregateV3;
get batch(): BatchV3;
get batchByChunk(): BatchByChunkV3;
}
/**
* Some actions for TypeB24
*/
declare class ActionsManager {
protected _b24: TypeB24;
protected _logger: LoggerInterface;
protected _mapActions: Map<symbol, any>;
constructor(b24: TypeB24);
setLogger(logger: LoggerInterface): void;
getLogger(): LoggerInterface;
get v2(): ActionsManagerV2;
get v3(): ActionsManagerV3;
}
/**
* Abstract Class for working with tools
*/
type ToolOptions = {
[key: string]: any;
};
declare abstract class AbstractTool {
protected _b24: TypeB24;
protected _logger: LoggerInterface;
constructor(b24: TypeB24, logger: LoggerInterface);
abstract make(options?: ToolOptions): Promise<unknown>;
}
/**
* Ping `restApi:v2`
*
* @todo use apiVer3
*/
declare class Ping extends AbstractTool {
/**
* Measures the response speed of the Bitrix24 REST API.
* Performs a test request and returns the response time in milliseconds.
* Useful for performance monitoring and diagnosing latency issues.
*
* @note The method uses a minimal API request (`server.time`) to check availability.
* Does not overload the server with large amounts of data.
*
* @warning Response time may vary depending on server load, network conditions
* and HTTP client settings (timeouts, retries).
*
* @tip For consistent results, it is recommended to perform multiple measurements
* and use the median value.
*
* @param options Some options for executing
* - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging (default: undefined)
*
* @returns {Promise<number>} Promise that resolves to a response time in milliseconds:
* - Positive number: time from sending the request to receiving the response
* - In case of an error or timeout: `-1`
*
* @see {@link HealthCheck} To check API availability
*/
make(options?: ToolOptions & {
requestId?: string;
}): Promise<number>;
}
/**
* HealthCheck `restApi:v2`
*
* @todo use apiVer3
*/
declare class HealthCheck extends AbstractTool {
/**
* Checks the availability of the Bitrix24 REST API.
* Performs a simple request to the API to verify the service is operational and that the required access rights are present.
*
* @note The method uses a minimal API request (`server.time`) to check availability.
* Does not overload the server with large amounts of data.
*
* @param options Some options for executing
* - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging (default: undefined)
*
* @returns {Promise<false>} Promise that resolves to a Boolean value:
* - `true`: the API is available and responding
* - `false`: the API is unavailable, an error occurred, or the required access rights are missing
*
* @see {@link Ping} To measure API response speed
*/
make(options?: ToolOptions & {
requestId?: string;
}): Promise<boolean>;
}
/**
* Manages built-in diagnostic tools available on a {@link TypeB24} instance.
* Provides lazy-initialized access to {@link Ping} and {@link HealthCheck} tools,
* each identified by a unique symbol key stored in an internal map.
*/
declare class ToolsManager {
protected _b24: TypeB24;
protected _logger: LoggerInterface;
protected _mapTools: Map<symbol, AbstractTool>;
constructor(b24: TypeB24);
setLogger(logger: LoggerInterface): void;
getLogger(): LoggerInterface;
get ping(): Ping;
get healthCheck(): HealthCheck;
}
/**
* Core types for the Bitrix24 REST API client: API version enumeration, batch call options,
* and the main B24 client interface exposing HTTP, auth, tools, and actions managers.
*
* @module
*/
declare enum ApiVersion {
v3 = "v3",
v2 = "v2"
}
/**
* Options for batch calls
*/
interface IB24BatchOptions extends ICallBatchOptions {
/**
* Api Version
* If the option is empty, then automatic detection is performed using the specified methods.
*/
apiVersion?: ApiVersion;
/**
* Whether to return an AjaxResult object instead of data
* @default false
*/
returnAjaxResult?: boolean;
}
type CallBatchResult<T> = Result<Record<string | number, AjaxResult<T>>> | Result<AjaxResult<T>[]> | Result<T>;
type TypeB24 = {
/**
* @see {https://bitrix24.github.io/b24jssdk/docs/hook/ Js SDK documentation}
* @see {https://apidocs.bitrix24.com/sdk/bx24-js-sdk/system-functions/bx24-init.html Bitrix24 REST API documentation}
*/
readonly isInit: boolean;
init(): Promise<void>;
destroy(): void;
getLogger(): LoggerInterface;
setLogger(logger: LoggerInterface): void;
/**
* Returns the AuthActions interface for handling authorization.
*/
get auth(): AuthActions;
/**
* Returns the ActionsManager interface for working with Bitrix24 methods. Dependent on the REST API version.
*/
get actions(): ActionsManager;
/**
* Returns the ToolsManager interface for access to Bitrix24 utilities independent of the REST API version.
*/
get tools(): ToolsManager;
/**
* Sets the restriction parameters
*/
setRestrictionManagerParams(params: RestrictionParams): Promise<void>;
/**
* Get the account address Bitrix24 ( `https://your_domain.bitrix24.com` )
*/
getTargetOrigin(): string;
/**
* Get the account address Bitrix24 with path
* - `restApi:v3` `https://your_domain.bitrix24.com/rest/api/`
* - `restApi:v2` `https://your_domain.bitrix24.com/rest/`
*/
getTargetOriginWithPath(): Map<ApiVersion, string>;
/**
* Calls the Bitrix24 REST API method.
*
* @deprecated This method is deprecated and will be removed in version `3.0.0`
* - for `restApi:v3` use {@link CallV3.make `b24.actions.v3.call.make(options)`}
* - for `restApi:v2` use {@link CallV2.make `b24.actions.v2.call.make(options)`}
*
* @removed 3.0.0
*/
callMethod(method: string, params?: object, start?: number): Promise<AjaxResult>;
/**
* Calls a Bitrix24 REST API list method to retrieve all data.
*
* @deprecated This method is deprecated and will be removed in version `3.0.0`
* - for `restApi:v3` use {@link CallListV3.make `b24.actions.v3.callList.make(options)`}
* - for `restApi:v2` use {@link CallListV2.make `b24.actions.v2.callList.make(options)`}
*
* @removed 3.0.0
*/
callListMethod(method: string, params?: object, progress?: null | ((progress: number) => void), customKeyForResult?: string | null): Promise<Result>;
/**
* Calls a Bitrix24 REST API list method and returns an async generator.
*
* @deprecated This method is deprecated and will be removed in version `3.0.0`
* - for `restApi:v3` use {@link FetchListV3.make `b24.actions.v3.fetchList.make(options)`}
* - for `restApi:v2` use {@link FetchListV2.make `b24.actions.v2.fetchList.make(options)`}
*
* @removed 3.0.0
*/
fetchListMethod(method: string, params?: any, idKey?: string, customKeyForResult?: string | null): AsyncGenerator<any[]>;
/**
* Executes a batch request to the Bitrix24 REST API
*
* @deprecated This method is deprecated and will be removed in version `3.0.0`
* - for `restApi:v3` use {@link BatchV3.make `b24.actions.v3.batch.make(options)`}
* - for `restApi:v2` use {@link BatchV2.make `b24.actions.v2.batch.make(options)`}
*
* @removed 3.0.0
*/
callBatch(calls: Array<any> | object, isHaltOnError?: boolean, returnAjaxResult?: boolean): Promise<Result>;
/**
* Executes a batch request to the Bitrix24 REST API with automatic chunking for any number of commands.
*
* @deprecated This method is deprecated and will be removed in version `3.0.0`
* - for `restApi:v3` use {@link BatchByChunkV3.make `b24.actions.v3.batchByChunk.make(options)`}
* - for `restApi:v2` use {@link BatchByChunkV2.make `b24.actions.v2.batchByChunk.make(options)`}
*
* @removed 3.0.0
*/
callBatchByChunk(calls: Array<any>, isHaltOnError: boolean): Promise<Result>;
/**
* Returns the HTTP client to perform the request.
*/
getHttpClient(version: ApiVersion): TypeHttp;
/**
* Set HTTP client
*/
setHttpClient(version: ApiVersion, client: TypeHttp): void;
};
/**
* @link https://apidocs.bitrix24.com/api-reference/rest-v3/index.html#structure-of-an-unsuccessful-response
*
* @todo ! move to packages/jssdk/src/types/payloads.ts
*/
type TypeDescriptionErrorV3 = {
readonly error: {
code: string;
message: string;
validation?: {
message?: string;
field?: string;
[key: string]: any;
}[];
};
};
type TypeDescriptionError = {
readonly error: 'invalid_token' | 'expired_token' | string;
readonly error_description?: string;
};
/**
* Parameters for hook
*/
type B24HookParams = {
/**
* https://your-bitrix-portal.bitrix24.com
*/
b24Url: string;
userId: number;
secret: string;
};
/**
* Parameters passed in the GET request from the B24 parent window to the application
*/
type B24FrameQueryParams = {
DOMAIN: string | null | undefined;
PROTOCOL: boolean | null | undefined;
LANG: string | null | undefined;
APP_SID: string | null | undefined;
};
/**
* Parameters for application for OAuth
*/
type B24OAuthSecret = {
clientId: string;
clientSecret: string;
};
/**
* Parameters for OAuth
* @memo We get from b24 event this data
*/
interface B24OAuthParams {
/**
* @example '1xxxxx1694'
*/
applicationToken: string;
/**
* @example 1
*/
userId: number;
/**
* @example '3xx2030386cyy1b'
*/
memberId: string;
/**
* @example '1xxxxx1694'
*/
accessToken: string;
/**
* @example '0xxxx4e000011e700000001000000260dc83b47c40e9b5fd501093674c4f5'
*/
refreshToken: string;
/**
* @example 1745997853
*/
expires: number;
/**
* @example 3600
*/
expiresIn: number;
/**
* @example 'crm,catalog,bizproc,placement,user_brief'
*/
scope: string;
/**
* @example 'xxx.bitrix24.com'
*/
domain: string;
/**
* @example 'https://xxx.bitrix24.com/rest/'
*/
clientEndpoint: string;
/**
* @example 'https://oauth.bitrix.info/rest/'
*/
serverEndpoint: string;
/**
* @example 'L'
*/
status: typeof EnumAppStatus[keyof typeof EnumAppStatus];
issuer?: 'request' | 'store' | string;
}
type HandlerRefreshAuth = Pick<HandlerAuthParams, 'access_token' | 'refresh_token' | 'expires' | 'expires_in' | 'client_endpoint' | 'server_endpoint' | 'member_id' | 'scope' | 'status' | 'domain'>;
/**
* Callback called when OAuth authorization is updated
*/
type CallbackRefreshAuth = (params: {
authData: AuthData;
b24OAuthParams: B24OAuthParams;
}) => Promise<void>;
/**
* Use for custom get new refresh token for OAuth
*/
type CustomRefreshAuth = () => Promise<HandlerRefreshAuth>;
/**
* Parameters passed from the parent window when calling refreshAuth
*/
type RefreshAuthData = {
AUTH_ID: string;
REFRESH_ID: string;
AUTH_EXPIRES: NumberString;
};
/**
* Parameters passed from the parent window when calling getInitData
*/
type MessageInitData = RefreshAuthData & {
DOMAIN: string;
PROTOCOL: string;
PATH: string;
LANG: string;
MEMBER_ID: string;
IS_ADMIN: boolean;
APP_OPTIONS: Record<string, any>;
USER_OPTIONS: Record<string, any>;
PLACEMENT: string;
PLACEMENT_OPTIONS: Record<string, any>;
INSTALL: boolean;
FIRST_RUN: boolean;
};
/**
* Parameters for OAuth authorization
*/
type AuthData = {
access_token: string;
refresh_token: string;
expires: number;
expires_in: number;
domain: string;
member_id: string;
[key: string]: any;
};
/**
* Interface for updating authorization
*/
interface AuthActions {
getAuthData: () => false | AuthData;
refreshAuth: () => Promise<AuthData>;
getUniq: (prefix: string) => string;
isAdmin: boolean;
/**
* Get the account address BX24 ( `https://your_domain.bitrix24.com` )
*/
getTargetOrigin(): string;
/**
* Get the account address BX24 with path
* - ver2 `https://your_domain.bitrix24.com/rest/`
* - ver3` https://your_domain.bitrix24.com/rest/api/`
*/
getTargetOriginWithPath(): Map<ApiVersion, string>;
}
type PayloadTime = {
readonly start: number;
readonly finish: number;
readonly duration: number;
readonly processing: number;
readonly date_start: ISODate;
readonly date_finish: ISODate;
/**
* timestamp - when part of the limit for this method will be released.
*/
readonly operating_reset_at: number;
/**
* indicates the execution time of a request to a specific method.
*/
readonly operating: number;
};
type GetPayload<P> = {
readonly result: P;
readonly time: PayloadTime;
};
type ListPayload<P> = {
readonly result: P[];
readonly total: number;
readonly next?: number;
readonly time: PayloadTime;
};
type BatchPayloadResult<C> = {
readonly result: {
readonly [P in keyof C]?: C[P];
} | ReadonlyArray<C[keyof C]>;
readonly result_error: {
readonly [P in keyof C]?: string;
} | readonly string[];
readonly result_total: {
readonly [P in keyof C]?: number;
} | readonly number[];
readonly result_next: {
readonly [P in keyof C]?: number;
} | readonly number[];
readonly result_time: {
readonly [P in keyof C]?: PayloadTime;
} | readonly PayloadTime[];
};
type BatchPayload<C> = {
readonly result: BatchPayloadResult<C>;
readonly time: PayloadTime;
};
type Payload<P> = TypeDescriptionErrorV3 | TypeDescriptionError | GetPayload<P> | ListPayload<P> | BatchPayload<P>;
/**
* Public shape of a successful REST response, as exposed by `AjaxResult.getData()`.
*
* The Bitrix24 REST API always wraps a success response in `{ result, time }` —
* this is true for both `restApi:v2` and `restApi:v3`. Any v2-only envelope
* fields (`next`, `total`) are intentionally NOT part of this type: they have
* no `restApi:v3` counterpart, and the SDK's `actions.v{2,3}.{callList,fetchList}`
* helpers handle pagination internally so consumers never need to read them.
*
* @see GetPayload
*/
type SuccessPayload<P> = {
readonly result: P;
readonly time: PayloadTime;
};
/**
* One entry of the `restApi:v3` `validation` array, as the SDK exposes it.
*
* `field` and `message` are both optional because the portal's own type says so
* — `TypeDescriptionErrorV3` declares them optional and permits extra keys. A
* caller matching on `field` has to handle it being absent; that is the portal's
* shape, not a hedge.
*/
type ValidationDetail = {
readonly field?: string;
readonly message?: string;
readonly [key: string]: unknown;
};
type SdkErrorDetails = {
code: string;
/**
* Human-readable detail. **Never interpolate a caller-supplied value into
* this string** — request params, a filter, a URL, a token.
*
* `AjaxError` runs its `requestInfo` through `redactSensitiveParams` before
* storing it; `SdkError` has no equivalent step, because its description is
* expected to be written by the SDK rather than assembled from input. That
* expectation is the only thing keeping a credential out of it, and error
* messages travel — into logs, into failure reports, into Bitrix24 server-side
* records. A filter alone legitimately carries user data: the email or phone
* number being searched for.
*/
description?: string;
status: number;
originalError?: unknown;
};
/**
* Error in Sdk
*/
declare class SdkError extends Error {
readonly code: string;
protected _status: number;
readonly timestamp: Date;
/**
* Opaque, un-scrubbed payload — may carry transport-layer detail
* (e.g. `AxiosError.config.url` / request headers) with credentials that the
* logger-side redaction does NOT scrub. It is defined **non-enumerable**
* (see the constructor) so property-walking serializers — a spread
* `{ ...err }`, `Object.keys(err)`, `Object.assign({}, err)`, or a
* Sentry-style capture — skip it and can't leak the secret. `toJSON()` /
* `toString()` already omit it too. It stays readable as `err.originalError`
* for local debugging; prefer `code` / `status` / `message` (and
* `AjaxError.requestInfo`, which IS redacted) for anything you log. (#73, #189)
*/
readonly originalError?: unknown;
constructor(params: SdkErrorDetails);
get status(): number;
/**
* Creates SdkError from exception
*/
static fromException(error: unknown, context?: {
code?: string;
status?: number;
}): SdkError;
/**
* Serializes error for logging and debugging
*/
toJSON(): {
name: string;
code: string;
message: string;
status: number;
timestamp: string;
stack: string | undefined;
};
/**
* Formats error information for human-readable output
*/
toString(): string;
protected static formatErrorMessage(params: SdkErrorDetails): string;
protected cleanErrorStack(): void;
}
type AnswerError = {
error: string;
errorDescription: string;
};
type AjaxErrorParams = {
status: number;
answerError: AnswerError;
cause?: Error;
};
type AjaxErrorDetails = SdkErrorDetails & {
requestInfo?: Partial<AjaxQuery>;
validation?: readonly ValidationDetail[];
};
/**
* Error requesting RestApi
*/
declare class AjaxError extends SdkError {
/**
* Redaction contract: `requestInfo.params` has already been run through
* {@link redactSensitiveParams} in the constructor, so credential-bearing
* keys are stored as `***REDACTED***` and are safe to surface via
* `toJSON()` / `toString()`. (#39, #73)
*/
readonly requestInfo?: AjaxErrorDetails['requestInfo'];
/**
* The `restApi:v3` `validation` array, when the portal sent one.
*
* `description` folds the validation messages into one string for display;
* this keeps them apart, **with the `field` each belongs to** — which the
* message alone does not carry, and which is what a form needs in order to
* mark the offending input rather than show a banner (#423).
*
* ```ts
* if (!response.isSuccess) {
* for (const error of response.getErrors()) {
* if (error instanceof AjaxError) {
* for (const detail of error.validation ?? []) {
* markInvalid(detail.field, detail.message)
* }
* }
* }
* }
* ```
*
* Absent under `restApi:v2`, which has no equivalent, and absent when v3
* reported an error without one. `field` is optional inside each entry
* because the portal's own shape says so.
*
* **Included in `toJSON()`**, but only when present — an error carrying no
* validation serializes exactly as it did before. It belongs there because
* `toJSON()` is what reaches a log or an error tracker, and that is where the
* field name matters most: `message` folds the validation *messages* in, but
* not the `field` each came from. A portal often names the field inside its
* own wording, as in `` Обязательное поле `id` не указано `` — but that is the
* portal's phrasing, not a guarantee, and nothing structured survives without
* this.
*
* **Redaction contract:** each entry has been run through
* {@link redactSensitiveParams} in the constructor, on the same terms as
* `requestInfo.params`. That matters because the portal's own shape permits
* extra keys beyond `field` and `message`, and only `message` is folded into
* `description` — so an extra key reaches a serializer without ever passing
* through the text. Before this was added, a row carrying `token: '…'` was
* masked inside `requestInfo.params` and printed verbatim here, from the same
* error object.
*
* What redaction does *not* cover is portal prose: a message that quotes a
* submitted value stays as the portal wrote it, exactly as it already does in
* `message`. Contrast `originalError`, which is genuinely hidden: it holds the
* raw transport error and its credentials.
*/
readonly validation?: readonly ValidationDetail[];
constructor(params: AjaxErrorDetails);
/**
* Creates AjaxError from HTTP response
* @todo add support v3
*/
static fromResponse(response: {
status: number;
data?: {
error?: string;
error_description?: string;
};
config?: AjaxErrorDetails['requestInfo'];
}): AjaxError;
/**
* @inheritDoc
*/
static fromException(error: unknown, context?: {
code?: string;
status?: number;
requestInfo?: AjaxErrorDetails['requestInfo'];
}): AjaxError;
/**
* @inheritDoc
*/
toJSON(): {
stack: string | undefined;
validation?: readonly ValidationDetail[] | undefined;
name: string;
code: string;
message: string;
status: number;
timestamp: string;
requestInfo: Partial<Readonly<{
method: string;
params: TypeCallParams;
requestId: string;
}>> | undefined;
};
/**
* @inheritDoc
*/
toString(): string;
/**
* @inheritDoc
*/
protected static formatErrorMessage(params: AjaxErrorDetails): string;
/**
* @inheritDoc
*/
protected cleanErrorStack(): void;
}
type AjaxQuery = Readonly<{
method: string;
params: TypeCallParams;
requestId: string;
}>;
type AjaxResultOptions<T> = Readonly<{
answer: Payload<T>;
query: AjaxQuery;
status: number;
/**
* An error the caller has already built, used instead of deriving one from
* `answer`.
*
* For the soft-error path in `AbstractHttp`, which has parsed the portal's
* body, built an `AjaxError` from it, and then needs a `Result` to hand back.
* Re-deriving there parses the same body twice — and the second pass folds the
* validation messages onto a description that already contains them, so the
* text came out doubled (#423). Carrying the error is also simply more honest:
* it is the error, not a reconstruction of one.
*/
error?: AjaxError;
}>;
/**
* Typed result wrapper for a single Bitrix24 REST API response.
*
* Extends {@link Result} with the raw HTTP status, the originating query
* (method, params, requestId), and the deserialized payload. On construction
* it inspects the payload for API-level error fields and populates the
* inherited error collection, so callers can branch on {@link isSuccess}
* without inspecting raw HTTP status codes.
*/
declare class AjaxResult<T = unknown> extends Result<Payload<T>> implements IResult<Payload<T>> {
#private;
private readonly _status;
private readonly _query;
protected _data: Payload<T> | null | undefined;
constructor(options: AjaxResultOptions<T>);
get isSuccess(): boolean;
getData(): undefined | SuccessPayload<T>;
/**
* Alias for {@link AjaxResult.isMore}.
*
* `restApi:v2` only — see {@link AjaxResult.isMore} for what this returns on
* a `restApi:v3` response.
*/
hasMore(): boolean;
/**
* Whether the `restApi:v2` envelope carries a `next` offset — i.e. the portal
* has more rows for this query.
*
* **`restApi:v2` only.** `restApi:v3` returns no `next` field, so this returns
* `false` on a v3 response — which is not the same statement as "there are no
* more rows". Do not branch on it for v3; there is nothing to read.
*
* This is a reader for a protocol field, not a deprecated API: it stays for as
* long as `restApi:v2` does, and so does its counterpart
* {@link AjaxResult.getNext} — the two together are the manual `restApi:v2`
* paging loop, and neither is going away. For new code prefer the list
* helpers, which hide the offset bookkeeping and work under both protocol
* versions:
* - `restApi:v2`: `b24.actions.v2.callList.make` or `b24.actions.v2.fetchList.make`
* - `restApi:v3`: `b24.actions.v3.callList.make` or `b24.actions.v3.fetchList.make`
*/
isMore(): boolean;
/**
* The row count the `restApi:v2` envelope reports in its `total` field.
*
* **`restApi:v2` only.** `restApi:v3` returns no `total`, so this returns `0`
* on a v3 response — which is not the same statement as "no rows matched".
* Do not read it for v3; use
* `b24.actions.v3.aggregate.make` with `count` / `countDistinct` instead,
* bearing in mind that action is `@experimental` and unverified against a live
* portal.
*
* This is a reader for a protocol field, not a deprecated API. It is the only
* way to obtain a count under `restApi:v2` — the list helpers iterate without
* exposing `total`, {@link SuccessPayload} deliberately omits it, and the
* `aggregate` action exists for `restApi:v3` only. It therefore stays for as
* long as `restApi:v2` does, and is not part of the `3.0.0` removal set.
*
* That is a decision with a trigger, not an open-ended promise. Revisit it
* when either holds: `b24.actions.v3.aggregate` is verified against a live
* portal and loses its `@experimental` tag across the common modules (a v3
* count then exists, and `getTotal()` has a replacement for the first time),
* or Bitrix24 announces a `restApi:v2` sunset date (the field it reads goes
* away regardless). Until one of those happens there is nothing to migrate
* callers to, which is the whole reason it is still here.
*
* Note this trigger is specific to the readers. {@link AjaxResult.getNext} and
* {@link AjaxResult.fetchNext} already have a working replacement, so nothing
* about `aggregate` maturing changes anything for them — a `restApi:v2` sunset
* is their only exit condition.
*/
getTotal(): number;
getStatus(): number;
getQuery(): Readonly<AjaxQuery>;
/**
* Alias for {@link AjaxResult.getNext}, returning `null` where that returns
* `false`.
*
* **`restApi:v2` only** — see {@link AjaxResult.getNext}, including the throw
* on a `restApi:v3` client, which this inherits.
*/
fetchNext(http: TypeHttp): Promise<AjaxResult<T> | null>;
/**
* Re-runs this result's own query with `params.start` set to the `next` offset
* the `restApi:v2` envelope reported, and resolves to the following page.
* Returns `false` when this result is unsuccessful or has no `next`.
*
* `restApi:v2` only, and permanently so. Unlike the readers above, this one
* acts on the envelope, and `restApi:v3` has no `next` to act on — so it
* throws rather than silently returning `false`, which would be
* indistinguishable from "last page". That throw is not a transitional
* measure; it is the honest answer for a protocol that does not have this
* operation.
*
* For new code prefer `b24.actions.v{2,3}.callList.make` (collect everything)
* or `b24.actions.v{2,3}.fetchList.make` (async generator, one page per
* iteration — the same page-by-page control this gives, without the manual
* offset bookkeeping, and it works under both protocol versions). This method
* is kept because it works under `restApi:v2` and deleting it would break
* running code for no gain, not because it is the better tool.
*
* @throws {SdkError} `JSSDK_CORE_METHOD_NOT_SUPPORT_IN_API_V3` when called against a `restApi:v3` HTTP client.
*/
getNext(http: TypeHttp): Promise<AjaxResult<T> | false>;
setData(): never;
}
/**
* The eight — and only eight — comparison operators the Bitrix24 REST API v3
* filter grammar accepts. Anything else is rejected server-side with
* `UNKNOWNFILTEROPERATOREXCEPTION`.
*/
type FilterV3Operator = '=' | '!=' | '>' | '>=' | '<' | '<=' | 'in' | 'between';
/**
* A single condition in short-form: `[field, operator, value]`.
*/
type FilterV3Condition = [string, FilterV3Operator, unknown];
/**
* A logical group of conditions / nested groups. `logic` defaults to `'and'`;
* `negative: true` wraps the whole group in a NOT.
*/
interface FilterV3Group {
logic?: 'and' | 'or';
negative?: boolean;
conditions: FilterV3Node[];
}
type FilterV3Node = FilterV3Condition | FilterV3Group;
/**
* Typed builder for Bitrix24 REST API **v3** filters (the array-of-triples
* dialect with AND/OR/NOT groups — see the v3 reference §3). Produces exactly
* the structures the server accepts, so a bad operator or a malformed
* `in` / `between` value fails fast on the client instead of as a server 400.
*
* @example
* import { FilterV3 as F } from '@bitrix24/b24jssdk'
*
* // status = NEW AND (id in [1,2] OR id > 100)
* const filter = F.build(
* F.eq('status', 'NEW'),
* F.or(
* F.in('id', [1, 2]),
* F.gt('id', 100)
* )
* )
* await b24.actions.v3.call.make({ method: 'tasks.task.list', params: { filter } })
*/
declare const FilterV3: Readonly<{
/** `field = value` */
eq(field: string, value: unknown): FilterV3Condition;
/** `field != value` */
ne(field: string, value: unknown): FilterV3Condition;
/** `field > value` */
gt(field: string, value: unknown): FilterV3Condition;
/** `field >= value` */
ge(field: string, value: unknown): FilterV3Condition;
/** `field < value` */
lt(field: string, value: unknown): FilterV3Condition;
/** `field <= value` */
le(field: string, value: unknown): FilterV3Condition;
/** `field in [values]` — `values` must be a non-empty array. */
in(field: string, values: unknown[]): FilterV3Condition;
/** `field between [from, to]` — inclusive range of exactly two defined operands. */
between(field: string, from: unknown, to: unknown): FilterV3Condition;
/** Combine nodes with AND (for nesting inside an OR; the top level is already AND). */
and(...conditions: FilterV3Node[]): FilterV3Group;
/** Combine nodes with OR. */
or(...conditions: FilterV3Node[]): FilterV3Group;
/**
* Negate a condition or group (wraps it in a NOT). A bare condition is wrapped
* in a single-item AND group so the `negative` flag has somewhere to live.
* Returns a fresh group (the input's `conditions` array is copied, not shared).
*/
not(node: FilterV3Node): FilterV3Group;
/**
* Assemble the top-level filter array (its elements are AND-joined) ready to
* pass as `params.filter`. Falsy nodes are skipped, so you can inline
* conditionals: `F.build(F.eq('a', 1), flag && F.gt('b', 2))`.
*
* Always wrap with `build` (or an array) even for a single condition —
* `params.filter` must be an array, so pass `build(F.eq('a', 1))`, not the bare
* `F.eq('a', 1)`. Each surviving node is shape-checked, so a forgotten spread
* (`build([F.eq(...)])`) or a hand-rolled malformed triple fails fast here
* instead of as an opaque server error.
*/
build(...nodes: Array<FilterV3Node | false | null | undefined>): FilterV3Node[];
}>;
/**
* Types for HTTP communication with the Bitrix24 REST API: call parameters (filtering, ordering,
* pagination for both v2 and v3), batch command formats, and the core `TypeHttp` client interface.
*/
/**
* `restApi:v2` filter — a prefix-operator dialect keyed by field, where the
* operator is encoded in the key, e.g. `{ '>id': 100, '%NAME': 'Iv' }`.
*/
type TypeFilterV2 = Record<string, unknown>;
/**
* `restApi:v3` filter — an array of `[field, operator, value]` triples (joined
* with AND at the top level), e.g. `[['id', '>', 100], ['stageId', '=', 'NEW']]`.
* Nested AND/OR/NOT groups are allowed too, so the output of the `FilterV3`
* builder (`FilterV3.build(...)`) assigns directly.
*/
type TypeFilterV3 = Array<[string, string, unknown] | FilterV3Group>;
type TypeCallParams = {
order?: Record<string, 'ASC' | 'DESC' | 'asc' | 'desc' | string>;
filter?: any;
select?: string[];
params?: any;
/**
* Used only in Api:V2
*/
start?: number;
/**
* Used only in Api:V3
*/
pagination?: {
limit?: number;
/**
* Minimum 1
*/
page?: number;
/**
* You need to use either `page` or `offset`. There's no point in using both.
*/
offset?: number;
};
/**
* Used only in Api:V3 — keyset (`tail`) pagination cursor.
* `value` is the last seen value of `field`; `0` (or the type minimum) on the
* first page. `order` defaults to `asc`; `limit` shares the 50/1000 rule of
* `pagination`.
*/
cursor?: {
field: string;
value: number | string;
order?: 'ASC' | 'DESC' | 'asc' | 'desc' | string;
limit?: number;
};
[key: string]: any;
};
/**
* Per-version specialisation of {@link TypeCallParams} that types the request-side
* `filter` for `restApi:v2` (prefix-operator object) and drops the v3-only
* `pagination` / `cursor` fields. The permissive `[key: string]: any` index
* signature is retained, so existing call sites keep compiling.
*/
type TypeCallParamsV2 = Omit<TypeCallParams, 'filter' | 'pagination' | 'cursor'> & {
filter?: TypeFilterV2;
};
/**
* Per-version specialisation of {@link TypeCallParams} that types the request-side
* `filter` for `restApi:v3` and drops the v2-only `start` field. The preferred
* v3 shape is the array of triples / groups ({@link TypeFilterV3}); the v2-style
* object ({@link TypeFilterV2}) is still accepted for backward compatibility.
* The permissive `[key: string]: any` index signature is retained, so existing
* call sites keep compiling.
*/
type TypeCallParamsV3 = Omit<TypeCallParams, 'filter' | 'start'> & {
filter?: TypeFilterV3 | TypeFilterV2;
};
/**
* What the transport sends for a `batch` CALL — not call params.
*
* `TypeHttp.call` types its `params` as {@link TypeCallParams}, and the batch
* request rides through it: `{ halt, cmd }` is neither a filter nor a select,
* and it type-checks today only because of the permissive index signature. This
* type names the shape so the intent is visible at the two callsites that build
* it (`core/http/v2.ts`, `core/http/v3.ts`), and so the eventual narrowing of
* that index signature has something to point at.
*
* `cmd` is `unknown` because its shape is mode-specific — a string array or a
* `Record<string, string>` of `method?query` lines, depending on whether the
* caller used array or named commands. `buildCommands` owns that decision.
*
* `restApi:v3` has no envelope: it sends the commands as the request body, with
* no `halt` (per-command `parallel` replaces it), so there is nothing to name on
* that side — see the comment at its callsite in `core/http/v3.ts`.
*/
type BatchRequestEnvelopeV2 = {
/** `1` stops the batch at the first failing command, `0` runs them all. */
halt: 0 | 1;
cmd: unknown;
};
/**
* Options for batch calls
*/
interface ICallBatchOptions {
/**
* Whether to stop execution on the first error
* @default true
*/
isHaltOnError?: boolean;
/**
* Unique request identifier for tracking. Used for query deduplication and debugging.
*/
requestId?: string;
}
/**
* Result of the batch call
*/
interface ICallBatchResult<T = unknown> {
result?: Map<string | number, AjaxResult<T>>;
time?: PayloadTime;
}
type BatchCommandV3 = {
method: string;
query?: Record<string, unknown>;
as?: string;
parallel?: boolean;
};
type CommandTuple<M extends string = string, P = undefined | TypeCallParams> = [M, P?];
/**
* Object form of a batch command. The `as`, `parallel`, and `params.cursor` / `params.pagination`
* fields are supported in API v3 only; `params.start` is the v2 equivalent for offset pagination.
*/
interface CommandObject<M extends string = string, P = undefined | TypeCallParams> {
method: M;
params?: P;
as?: string;
parallel?: boolean;
}
type CommandUniversal<M extends string = string, P = undefined | TypeCallParams> = CommandTuple<M, P> | CommandObject<M, P>;
type BatchCommandsArrayUniversal<M extends string = string, P = undefined | TypeCallParams> = CommandTuple<M, P>[];
type BatchCommandsObjectUniversal<M extends string = string, P = undefined | TypeCallParams> = CommandObject<M, P>[];
type BatchNamedCommandsUniversal<K extends string | number | symbol = string, M extends string = string, P = undefined | TypeCallParams> = Record<K, CommandObject<M, P> | CommandTuple<M, P>>;
type BatchCommandsUniversal<M extends string = string, P = undefined | TypeCallParams> = CommandUniversal<M, P>[];
/**
* Interface for Request id generator
*/
interface IRequestIdGenerator {
getRequestId(): string;
getHeaderFieldName(): string;
getQueryStringParameterName(): string;
getQueryStringSdkParameterName(): string;
}
/**
* Interface for HTTP client
*/
type TypeHttp = {
apiVersion: ApiVersion;
ajaxClient: AxiosInstance;
setLogger(logger: LoggerInterface): void;
getLogger(): LoggerInterface;
/**
* Executing batch queries
*/
batch<T = unknown>(calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal | BatchNamedCommandsUniversal, options?: ICallBatchOptions): Promise<Result<ICallBatchResult<T>>>;
/**
* Calling the RestApi function
* @param method - REST API method name
* @param params - Parameters for the method.
* @param requestId - Request id
* @returns Promise with AjaxResult
*/
call<T = unknown>(method: string, params: TypeCallParams, requestId?: string): Promise<AjaxResult<T>>;
/**
* Sets the restriction parameters
*/
setRestrictionManagerParams(params: RestrictionParams): Promise<void>;
/**
* Returns the current constraint settings
*/
getRestrictionManagerParams(): RestrictionParams;
/**
* Returns job statistics
*/
getStats(): RestrictionManagerStats & {
adaptiveDelayAvg: number;
errorCounts: Record<string, number>;
totalRequests: number;
successfulRequests: number;
failedRequests: number;
totalDuration: number;
byMethod: Map<string, {
count: number;
totalDuration: number;
}>;
lastErrors: {
method: string;
error: string;
timestamp: number;
}[];
};
/**
* Resets limiters and statistics
*/
reset(): Promise<void>;
/**
* On|Off warning about client-side query execution
* @param {boolean} value
* @param {string} message
*/
setClientSideWarning(value: boolean, message: string): void;
};
/**
* User fields for scope:user_brief
* @link https://dev.1c-bitrix.ru/rest_help/users/index.php
*/
type UserBrief = {
readonly [key: string]: string | boolean | null | readonly number[];
readonly ID: NumberString;
readonly XML_ID: string | null;
readonly ACTIVE: boolean;
readonly NAME: string | null;
readonly LAST_NAME: string | null;
readonly SECOND_NAME: string | null;
readonly TITLE: string | null;
readonly IS_ONLINE: BoolString;
readonly TIME_ZONE: string | null;
readonly TIME_ZONE_OFFSET: NumberString | null;
readonly TIMESTAMP_X: string;
readonly DATE_REGISTER: ISODate;
readonly PERSONAL_PROFESSION: string | null;
readonly PERSONAL_GENDER: GenderString;
readonly PERSONAL_BIRTHDAY: string | null;
readonly PERSONAL_PHOTO: string | null;
readonly PERSONAL_CITY: string | null;
readonly PERSONAL_STATE: string | null;
readonly PERSONAL_COUNTRY: string | null;
readonly WORK_POSITION: string | null;
readonly WORK_CITY: string | null;
readonly WORK_STATE: string | null;
readonly WORK_COUNTRY: string | null;
readonly LAST_ACTIVITY_DATE: string;
readonly UF_EMPLOYMENT_DATE: ISODate | string;
readonly UF_TIMEMAN: string | null;
readonly UF_SKILLS: string | null;
readonly UF_INTERESTS: string | null;
readonly UF_DEPARTMENT: readonly number[];
readonly UF_PHONE_INNER: NumberString | null;
};
/**
* User fields for scope:user_basic
*/
type UserBasic = UserBrief & {
readonly EMAIL: string | null;
readonly PERSONAL_WWW: string | null;
readonly PERSONAL_ICQ: string | null;
readonly PERSONAL_PHONE: string | null;
readonly PERSONAL_FAX: string | null;
readonly PERSONAL_MOBILE: string | null;
readonly PERSONAL_PAGER: string | null;
readonly PERSONAL_STREET: string | null;
readonly PERSONAL_ZIP: string | null;
readonly WORK_COMPANY: string | null;
readonly WORK_PHONE: string | null;
readonly UF_SKILLS: string | null;
readonly UF_WEB_SITES: string | null;
readonly UF_XING: string | null;
readonly UF_LINKEDIN: string | null;
readonly UF_FACEBOOK: string | null;
readonly UF_TWITTER: string | null;
readonly UF_SKYPE: string | null;
readonly UF_DISTRICT: string | null;
readonly USER_TYPE: 'employee';
};
type StatusClose = {
isOpenAtNewWindow: boolean;
isClose: boolean;
};
/**
* CRM Entity Types
* @link https://dev.1c-bitrix.ru/rest_help/crm/constants.php
*/
declare enum EnumCrmEntityType {
undefined = "UNDEFINED",
lead = "CRM_LEAD",
deal = "CRM_DEAL",
contact = "CRM_CONTACT",
company = "CRM_COMPANY",
oldInvoice = "CRM_INVOICE",
invoice = "CRM_SMART_INVOICE",
quote = "CRM_QUOTE",
requisite = "CRM_REQUISITE",
order = "ORDER"
}
declare enum EnumCrmEntityTypeId {
undefined = 0,
lead = 1,
deal = 2,
contact = 3,
company = 4,
oldInvoice = 5,
invoice = 31,
quote = 7,
requisite = 8,
order = 14
}
declare enum EnumCrmEntityTypeShort {
undefined = "?",
lead = "L",
deal = "D",
contact = "C",
company = "CO",
oldInvoice = "I",
invoice = "SI",
quote = "Q",
requisite = "RQ",
order = "O"
}
/**
* Converts a numeric CRM entity type ID to its corresponding short string code.
* Returns `EnumCrmEntityTypeShort.undefined` when the ID has no matching entry.
*/
declare function getEnumCrmEntityTypeShort(id: EnumCrmEntityTypeId): EnumCrmEntityTypeShort;
/**
* Data Types and Object Structure in the REST API Catalog
* @link https://apidocs.bitrix24.com/api-reference/catalog/data-types.html
*/
declare enum CatalogProductType {
undefined = 0,
product = 1,
service = 7,
sku = 3,
skuEmpty = 6,
offer = 4,
offerEmpty = 5
}
declare enum CatalogProductImageType {
undefined = "UNDEFINED",
detail = "DETAIL_PICTURE",
preview = "PREVIEW_PICTURE",
morePhoto = "MORE_PHOTO"
}
declare enum CatalogRoundingRuleType {
undefined = 0,
mathematical = 1,
roundingUp = 2,
roundingDown = 4
}
interface CatalogCatalog {
id: number;
iblockId: number;
iblockTypeId: string | 'CRM_PRODUCT_CATALOG';
lid: string;
name: string;
productIblockId?: number;
skuPropertyId?: number;
subscription?: BoolString;
vatId: number;
}
interface BaseProduct {
id: number;
iblockId: number;
sort: number;
name: string;
active: BoolString;
available: BoolString;
code: string;
xmlId: string;
barcodeMulti: BoolString;
bundle: BoolString;
canBuyZero?: BoolString;
type: number;
vatId: number;
vatIncluded: BoolString;
weight?: number;
height?: number;
length?: number;
width?: number;
createdBy: number;
modifiedBy: number;
dateActiveFrom?: ISODate;
dateActiveTo?: ISODate;
dateCreate: ISODate;
timestampX: ISODate;
iblockSectionId?: number;
measure?: number;
previewText?: string;
previewTextType?: TextType;
detailText?: string;
detailTextType?: TextType;
previewPicture?: object;
detailPicture?: object;
subscribe: 'Y' | 'N' | 'D';
quantityTrace: 'Y' | 'N' | 'D';
purchasingCurrency: string;
purchasingPrice: number;
quantity: number;
quantityReserved: number;
[key: string]: any;
}
interface CatalogProduct extends BaseProduct {
type: CatalogProductType.product;
}
interface CatalogProductSku extends BaseProduct {
type: CatalogProductType.sku | CatalogProductType.skuEmpty;
}
interface CatalogProductOffer extends BaseProduct {
type: CatalogProductType.offer | CatalogProductType.offerEmpty;
}
interface CatalogProductService extends Omit<BaseProduct, 'quantityReserved' | 'quantity' | 'purchasingPrice' | 'purchasingCurrency' | 'quantityTrace' | 'subscribe' | 'weight' | 'height' | 'length' | 'width' | 'canBuyZero' | 'barcodeMulti'> {
type: CatalogProductType.service;
}
interface CatalogSection {
id: number;
xmlId: string;
code: string;
iblockId: number;
sort: number;
iblockSectionId: number;
name: string;
active: BoolString;
description: string;
descriptionType: TextType;
}
interface CatalogProductImage {
id: number;
name: string;
productId: number;
type: typeof CatalogProductImageType[keyof typeof CatalogProductImageType];
createTime?: ISODate;
downloadUrl?: string;
detailUrl?: string;
}
interface CatalogStore {
id: number;
code: string;
xmlId: string;
sort: number;
address: string;
title: string;
active: BoolString;
description?: string;
gpsN: number;
gpsS: number;
imageId: object;
dateModify: ISODate;
dateCreate: ISODate;
userId: number;
modifiedBy: number;
phone: string;
email: string;
schedule: string;
issuingCenter: BoolString;
}
interface CatalogMeasure {
id: number;
code: string;
isDefault: BoolString;
measureTitle: string;
symbol: string;
symbolIntl: string;
symbolLetterIntl: string;
}
interface CatalogRatio {
id: number;
productId: number;
ratio: number;
isDefault: BoolString;
}
interface CatalogPriceType {
id: number;
xmlId: string;
sort: number;
name: string;
base: BoolString;
createdBy: number;
modifiedBy: number;
dateCreate: ISODate;
timestampX: ISODate;
}
interface CatalogVat {
id: number;
name: string;
active: BoolString;
rate: number;
sort: number;
timestampX: ISODate;
}
interface CatalogPriceTypeLang {
id: number;
catalogGroupId: number;
name: string;
lang: string;
}
interface CatalogLanguage {
lid: string;
name: string;
active: BoolString;
}
interface CatalogRoundingRule {
id: number;
catalogGroupId: number;
price: number;
roundType: typeof CatalogRoundingRuleType[keyof typeof CatalogRoundingRuleType];
roundPrecision: number;
createdBy: number;
modifiedBy: number;
dateCreate: ISODate;
dateModify: ISODate;
}
interface CatalogExtra {
id: number;
name: string;
percentage: number;
}
declare enum ProductRowDiscountTypeId {
undefined = 0,
absolute = 1,
percentage = 2
}
interface CrmItemProductRow {
id: number;
ownerId: number;
ownerType: typeof EnumCrmEntityTypeShort[keyof typeof EnumCrmEntityTypeShort];
productId: number;
productName: string;
sort: number;
price: number;
priceAccount: number;
priceExclusive: number;
priceNetto: number;
priceBrutto: number;
customized: BoolString;
quantity: number;
measureCode: string;
measureName: string;
taxRate: number | null;
taxIncluded: BoolString;
discountRate: number;
discountSum: number;
discountTypeId: typeof ProductRowDiscountTypeId[keyof typeof ProductRowDiscountTypeId];
xmlId: string;
type: typeof CatalogProductType[keyof typeof CatalogProductType];
storeId: number;
}
interface CrmItemDelivery {
id: number;
accountNumber: string;
deducted: BoolString;
dateDeducted?: ISODate;
deliveryId: number;
deliveryName: string;
priceDelivery: number;
}
interface CrmItemPayment {
id: number;
accountNumber: string;
paid: BoolString;
datePaid?: ISODate;
empPaidId?: number;
sum: number;
currency: string;
paySystemId: number;
paySystemName: string;
}
/**
* UF embedding properties interface
*
* @link https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=99&LESSON_ID=8633
*/
interface IPlacementUF {
/**
* UF ID
*/
FIELD_NAME: string;
/**
* The identifier of the entity to which the field is bound
*/
ENTITY_ID: EnumCrmEntityType;
/**
* The identifier of the entity element whose field value is being edited
*/
ENTITY_VALUE_ID: NumberString;
/**
* The mode in which the field is called
*/
MODE: PlacementViewMode;
/**
* Field Requirement Flag
*/
MANDATORY: BoolString;
/**
* Field multiplicity flag
*/
MULTIPLE: BoolString;
/**
* Current value of the field. For a multiple field, an array of values.
*/
VALUE: any;
/**
* External field code
*/
XML_ID: string;
}
/**
* List of supported languages in B24.Cloud
*
* It is worth remembering that there will be 1-2 languages for the B24.Box
*/
declare enum B24LangList {
ru = "ru",
id = "id",
ms = "ms",
de = "de",
en = "en",
la = "la",
fr = "fr",
in = "in",
it = "it",
pl = "pl",
br = "br",
vn = "vn",
tr = "tr",
kz = "kz",
ua = "ua",
ar = "ar",
th = "th",
sc = "sc",
tc = "tc",
ja = "ja"
}
declare const B24LocaleMap: Record<B24LangList, string>;
/**
* Data Types and Object Structure in the REST API bizproc activity and robot.
* Covers handler parameter shapes, property type enumerations, and descriptor interfaces used
* when registering or handling custom workflow activities and robots via the REST API.
* @link https://apidocs.bitrix24.com/api-reference/bizproc/bizproc-activity/index.html
* @link https://apidocs.bitrix24.com/api-reference/bizproc/bizproc-robot/index.html
*/
interface ActivityHandlerParams {
event_token: string;
workflow_id: string;
code: string;
document_id: string[];
document_type: string[];
properties?: Record<string, string>;
use_subscription: BoolString;
timeout_duration: string;
ts: string;
[key: string]: any;
auth: HandlerAuthParams;
}
type ActivityPropertyType = 'bool' | 'date' | 'datetime' | 'double' | 'int' | 'select' | 'string' | 'text' | 'user';
interface ActivityProperty {
Name: string | Partial<Record<B24LangList, string>>;
Description?: string | Record<string, string>;
Type: ActivityPropertyType;
Options?: Record<string | number, string>;
Required?: BoolString;
Multiple?: BoolString;
Default?: any;
}
interface ActivityConfig {
CODE: string;
HANDLER: string;
NAME: string | Partial<Record<B24LangList, string>>;
DESCRIPTION?: string | Partial<Record<B24LangList, string>>;
DOCUMENT_TYPE?: [string, string, string];
PROPERTIES?: Record<string, ActivityProperty>;
RETURN_PROPERTIES?: Record<string, ActivityProperty>;
FILTER?: {
INCLUDE?: Array<string | string[]>;
EXCLUDE?: Array<string | string[]>;
};
USE_PLACEMENT?: BoolString;
PLACEMENT_HANDLER?: string;
USE_SUBSCRIPTION?: BoolString;
AUTH_USER_ID?: number;
}
interface ActivityOrRobotConfig extends Omit<ActivityConfig, 'HANDLER' | 'PLACEMENT_HANDLER' | 'NAME'> {
type: 'activity' | 'robot';
NAME?: ActivityConfig['NAME'];
HANDLER?: ActivityConfig['HANDLER'];
PLACEMENT_HANDLER?: ActivityConfig['PLACEMENT_HANDLER'];
}
/**
* Data Types and Object Structure in the REST API bizproc.
* Provides enumerations for Bitrix24 edition variants, bizproc document base types, and CRM
* document types used when registering activities/robots or starting business-process workflows.
* @link https://apidocs.bitrix24.com/api-reference/bizproc/bizproc-activity/bizproc-activity-add.html
* @link https://apidocs.bitrix24.com/api-reference/bizproc/bizproc-robot/bizproc-robot-add.html
*/
/**
* @link https://apidocs.bitrix24.com/api-reference/bizproc/bizproc-activity/bizproc-activity-add.html
*/
declare enum EnumBitrix24Edition {
undefined = "undefined",
b24 = "b24",
box = "box"
}
declare enum EnumBizprocBaseType {
undefined = "undefined",
crm = "crm",
disk = "disk",
lists = "lists"
}
/**
* @link https://apidocs.bitrix24.com/api-reference/bizproc/bizproc-workflow-start.html
*/
declare enum EnumBizprocDocumentType {
undefined = "undefined",
lead = "CCrmDocumentLead",
company = "CCrmDocumentCompany",
contact = "CCrmDocumentContact",
deal = "CCrmDocumentDeal",
invoice = "Bitrix\\Crm\\Integration\\BizProc\\Document\\SmartInvoice",
quote = "Bitrix\\Crm\\Integration\\BizProc\\Document\\Quote",
order = "Bitrix\\Crm\\Integration\\BizProc\\Document\\Order",
dynamic = "Bitrix\\Crm\\Integration\\BizProc\\Document\\Dynamic",
disk = "Bitrix\\Disk\\BizProcDocument",
lists = "BizprocDocument",
listsList = "Bitrix\\Lists\\BizprocDocumentLists"
}
declare function convertBizprocDocumentTypeToCrmEntityTypeId(documentType: EnumBizprocDocumentType): EnumCrmEntityTypeId;
/**
* @link https://apidocs.bitrix24.com/api-reference/bizproc/bizproc-activity/bizproc-activity-add.html
*/
declare function getDocumentType(documentType: EnumBizprocDocumentType, entityId?: number): string[];
/**
* @link https://apidocs.bitrix24.com/api-reference/bizproc/bizproc-workflow-start.html
*/
declare function getDocumentId(documentType: EnumBizprocDocumentType, id: number, dynamicId?: number): string[];
/**
* @link https://apidocs.bitrix24.com/api-reference/bizproc/bizproc-workflow-start.html
*/
declare function getDocumentTypeForFilter(documentType: EnumBizprocDocumentType): string[];
/**
* Data Types and Object Structure in the REST API event handler.
* Defines parameter shapes for incoming Bitrix24 event notifications, including
* app-install events and auth payloads delivered to registered event handler endpoints.
* @link https://apidocs.bitrix24.com/api-reference/events/index.html
*/
interface EventHandlerParams {
event: string;
event_handler_id: string;
ts: string;
[key: string]: any;
auth?: HandlerAuthParams;
}
interface EventOnAppInstallHandlerParams extends EventHandlerParams {
data: {
VERSION: string;
ACTIVE: BoolString;
INSTALLED: BoolString;
LANGUAGE_ID: string;
};
auth: HandlerAuthParams;
}
/**
* @todo fix this application_token
* @see https://apidocs.bitrix24.com/api-reference/events/safe-event-handlers.html
*/
interface EventOnAppUnInstallHandlerParams {
event: string;
event_handler_id: string;
ts: string;
[key: string]: any;
auth: {
domain: string;
client_endpoint: string;
server_endpoint: string;
member_id: string;
application_token: string;
};
}
type TypePullMessage = {
command: string;
params: Record<string, any>;
extra: Record<string, any>;
};
type TypePullClientMessageBody = {
module_id: string;
command: string;
params: any;
extra?: {
revision_web?: number;
sender?: {
type: SenderType;
};
server_time_unix?: number;
server_time_ago?: number;
};
};
declare enum ConnectionType {
Undefined = "undefined",
WebSocket = "webSocket",
LongPolling = "longPolling"
}
type TypeConnector = {
setLogger(logger: LoggerInterface): void;
destroy(): void;
connect(): void;
disconnect(code: number, reason: string): void;
send(buffer: ArrayBuffer | string): boolean;
connected: boolean;
connectionPath: string;
};
type ConnectorParent = {
session: TypePullClientSession;
getConnectionPath(connectionType: ConnectionType): string;
getPublicationPath(): string;
setLastMessageId(lastMessageId: string): void;
isProtobufSupported(): boolean;
isJsonRpc(): boolean;
};
type ConnectorCallbacks = {
onOpen: () => void;
onDisconnect: (response: {
code: number;
reason: string;
}) => void;
onError: (error: Error) => void;
onMessage: (response: string | ArrayBuffer) => void;
};
type ConnectorConfig = {
parent: ConnectorParent;
onOpen?: () => void;
onDisconnect?: (response: {
code: number;
reason: string;
}) => void;
onError?: (error: Error) => void;
onMessage?: (response: string | ArrayBuffer) => void;
};
type StorageManagerParams = {
userId?: number;
siteId?: string;
};
type TypeStorageManager = {
setLogger(logger: LoggerInterface): void;
getLogger(): LoggerInterface;
set(name: string, value: any): void;
get(name: string, defaultValue: any): any;
remove(name: string): void;
compareKey(eventKey: string, userKey: string): boolean;
};
declare enum LsKeys {
PullConfig = "bx-pull-config",
WebsocketBlocked = "bx-pull-websocket-blocked",
LongPollingBlocked = "bx-pull-longpolling-blocked",
LoggingEnabled = "bx-pull-logging-enabled"
}
type SharedConfigCallbacks = {
onWebSocketBlockChanged: (response: {
isWebSocketBlocked: boolean;
}) => void;
};
type SharedConfigParams = {
storage?: TypeStorageManager;
onWebSocketBlockChanged?: (response: {
isWebSocketBlocked: boolean;
}) => void;
};
declare enum PullStatus {
Online = "online",
Offline = "offline",
Connecting = "connect"
}
declare enum SenderType {
Unknown = 0,
Client = 1,
Backend = 2
}
declare enum SubscriptionType {
Server = "server",
Client = "client",
Online = "online",
Status = "status",
Revision = "revision"
}
type TypeSubscriptionOptions = {
/**
* Subscription type
*/
type?: SubscriptionType;
/**
* Name of the module
*/
moduleId?: string;
/**
* Name of the command
*/
command?: null | string;
/**
* Function, that will be called for incoming messages
*/
callback: Function;
};
interface UserStatusCallback {
(params: {
userId: number;
isOnline: boolean;
}): void;
}
interface CommandHandlerFunctionV1 {
(data: Record<string, any>, info?: {
type: SubscriptionType;
moduleId?: string;
}): void;
}
interface CommandHandlerFunctionV2 {
(params: Record<string, any>, extra: Record<string, any>, command: string, info?: {
type: SubscriptionType;
moduleId: string;
}): void;
}
interface TypeSubscriptionCommandHandler {
getModuleId: () => string;
getSubscriptionType?: () => SubscriptionType;
getMap?: () => Record<string, CommandHandlerFunctionV2>;
[key: string]: CommandHandlerFunctionV2 | undefined;
}
type TypePullClientEmitConfig = {
type: SubscriptionType;
moduleId?: string;
data?: Record<string, any>;
};
declare enum CloseReasons {
NORMAL_CLOSURE = 1000,
SERVER_DIE = 1001,
CONFIG_REPLACED = 3000,
CHANNEL_EXPIRED = 3001,
SERVER_RESTARTED = 3002,
CONFIG_EXPIRED = 3003,
MANUAL = 3004,
STUCK = 3005,
WRONG_CHANNEL_ID = 4010
}
declare enum SystemCommands {
CHANNEL_EXPIRE = "CHANNEL_EXPIRE",
CONFIG_EXPIRE = "CONFIG_EXPIRE",
SERVER_RESTART = "SERVER_RESTART"
}
declare enum ServerMode {
Shared = "shared",
Personal = "personal"
}
type RpcError = {
code: number;
message: string;
};
declare const ListRpcError: {
readonly Parse: RpcError;
readonly InvalidRequest: RpcError;
readonly MethodNotFound: RpcError;
readonly InvalidParams: RpcError;
readonly Internal: RpcError;
};
type JsonRpcRequest = {
method: string;
params: any;
id: number;
};
type RpcCommand = {
jsonrpc: string;
method: string;
params: any;
id: number;
};
type RpcRequest = RpcCommand & {};
type RpcCommandResult = {
jsonrpc?: string;
id?: number;
/**
* @fix this TypeRpcResponseAwaiters.resolve(response)
*/
result?: any;
error?: RpcError;
};
declare enum RpcMethod {
Publish = "publish",
GetUsersLastSeen = "getUsersLastSeen",
Ping = "ping",
ListChannels = "listChannels",
SubscribeStatusChange = "subscribeStatusChange",
UnsubscribeStatusChange = "unsubscribeStatusChange"
}
type TypeRpcResponseAwaiters = {
/**
* @fix this RpcCommandResult.result
*/
resolve: (response: any) => void;
reject: (error: string | RpcError) => void;
timeout: number;
};
type TypeJsonRpcConfig = {
connector: TypeConnector;
handlers: Record<string, (params: any) => RpcCommandResult>;
};
type TypePublicIdDescriptor = {
id?: string;
user_id?: NumberString;
public_id?: string;
signature?: string;
start: ISODate;
end: ISODate;
type?: string;
};
type TypeChanel = {
userId: number;
publicId: string;
signature: string;
start: Date;
end: Date;
};
type TypeChannelManagerParams = {
b24: TypeB24;
getPublicListMethod: string;
};
type TypePullClientSession = {
mid: null | string;
tag: null | string;
time: null | number;
history: any;
lastMessageIds: string[];
messageCount: number;
};
type TypeSessionEvent = {
mid: string;
tag?: string;
time?: number;
text: Record<string, any> | TypePullClientMessageBody;
};
type TypePullClientParams = {
b24: TypeB24;
skipCheckRevision?: boolean;
restApplication?: string;
siteId?: string;
guestMode?: boolean;
guestUserId?: number;
userId?: number;
serverEnabled?: boolean;
configGetMethod?: string;
getPublicListMethod?: string;
skipStorageInit?: boolean;
configTimestamp?: number;
};
type TypePullClientConfig = {
/**
* @fix this
*/
clientId: null;
api: {
revision_mobile: number;
revision_web: number;
};
channels: {
private?: TypePublicIdDescriptor;
shared?: TypePublicIdDescriptor;
};
publicChannels: Record<string, TypePublicIdDescriptor>;
server: {
timeShift: number;
config_timestamp: number;
long_polling: string;
long_pooling_secure: string;
mode: string;
publish: string;
publish_enabled: boolean;
publish_secure: string;
server_enabled: boolean;
version: number;
websocket: string;
websocket_enabled: boolean;
websocket_secure: string;
};
jwt: null | string;
exp: number;
};
type TypePullClientMessageBatch = {
userList?: number[];
channelList?: (string | {
publicId: string;
signature: string;
})[];
body: TypePullClientMessageBody;
expiry?: number;
};
/**
* Factory for creating constraint parameters
*/
declare class ParamsFactory {
/**
* Default parameters for regular tariffs
*
* @see Http.#restrictionParams
*/
static getDefault(): RestrictionParams;
/**
* Parameters for the Enterprise plan
*/
static getEnterprise(): RestrictionParams;
/**
* Parameters for bulk data processing
*/
static getBatchProcessing(): RestrictionParams;
/**
* Real-time parameters
*/
static getRealtime(): RestrictionParams;
/**
* Tariff plan based parameters
*/
static fromTariffPlan(plan: string): RestrictionParams;
}
/**
* Rate limiting (Leaky Bucket) with adaptive control
*/
declare class RateLimiter implements ILimiter {
#private;
private _logger;
constructor(config: RateLimitConfig);
getTitle(): string;
setLogger(logger: LoggerInterface): void;
getLogger(): LoggerInterface;
/**
* @inheritDoc
*/
canProceed(requestId: string, _method: string, _params?: any): Promise<boolean>;
/**
* @inheritDoc
*/
waitIfNeeded(requestId: string, _method: string, _params?: any): Promise<number>;
/**
* Error handler.
* If there are a lot of errors, we'll lower the limits.
*/
handleExceeded(requestId: string): Promise<number>;
/**
* Successful request handler.
* If everything is OK, we'll restore the limits.
*/
updateStats(requestId: string, method: string, _data: any): Promise<void>;
/**
* @inheritDoc
*/
reset(): Promise<void>;
/**
* @inheritDoc
*/
getStats(): {
tokens: number;
burstLimit: number;
originalBurstLimit: number;
drainRate: number;
originalDrainRate: number;
refillIntervalMs: number;
lastRefill: number;
pendingRequests: number;
recentErrors: number;
recentSuccesses: number;
};
/**
* @inheritDoc
*/
setConfig(config: RateLimitConfig): Promise<void>;
}
interface OperatingStats {
operating: number;
/**
* reset time (timestamp in ms)
*/
operating_reset_at: number;
lastUpdated: number;
}
/**
* Enforces the Bitrix24 per-method operating-time budget.
*
* Bitrix24 charges each REST call against a rolling 10-minute CPU-time
* quota (`operating` field in the response). This limiter tracks that
* quota per method and blocks further calls (via {@link ILimiter.canProceed})
* until the reset timestamp has passed, preventing `QUERY_LIMIT_EXCEEDED`
* errors caused by heavy requests exhausting the portal's operating budget.
*/
declare class OperatingLimiter implements ILimiter {
#private;
private _logger;
getTitle(): string;
constructor(config: OperatingLimitConfig);
setLogger(logger: LoggerInterface): void;
getLogger(): LoggerInterface;
get limitMs(): number;
getMethodStat(method: string): undefined | OperatingStats;
canProceed(requestId: string, method: string, params?: any): Promise<boolean>;
waitIfNeeded(requestId: string, method: string, params?: any): Promise<number>;
/**
* Returns the time until the method's operating limit is released (in ms)
* The analysis is based on the previous function call.
* It's important to understand that we're talking about locks of up to 10 minutes.
* This is a fairly strict lock based on the limit:
* - not reached - no lock
* - reached - lock until the unlock time + 1 second
*/
getTimeToFree(requestId: string, method: string, params?: any, _error?: any): Promise<number>;
/**
* Updates operating time statistics for the method
*/
updateStats(requestId: string, method: string, data: PayloadTime): Promise<void>;
reset(): Promise<void>;
getStats(): {
heavyRequestCount: number;
operatingStats: {
[method: string]: number;
};
};
setConfig(config: OperatingLimitConfig): Promise<void>;
}
/**
* Inserts proactive delays based on observed server load.
*
* Unlike hard limiters, `AdaptiveDelayer` never blocks a request outright —
* {@link canProceed} always returns `true`. Instead, {@link waitIfNeeded}
* calculates a back-off delay derived from the current operating-time
* consumption reported by {@link OperatingLimiter} and the configured
* {@link AdaptiveConfig}, smoothing request throughput before quota limits
* are actually hit.
*/
declare class AdaptiveDelayer implements ILimiter {
#private;
private _logger;
getTitle(): string;
constructor(config: AdaptiveConfig, operatingLimiter: OperatingLimiter);
setLogger(logger: LoggerInterface): void;
getLogger(): LoggerInterface;
canProceed(_requestId: string, _method: string, _params?: any): Promise<boolean>;
/**
* Returns an adaptive delay based on previous experience
*/
waitIfNeeded(requestId: string, method: string, params?: any): Promise<number>;
updateStats(_requestId: string, _method: string, _data: any): Promise<void>;
reset(): Promise<void>;
getStats(): {
adaptiveDelays: number;
totalAdaptiveDelay: number;
adaptiveDelayAvg: number;
};
setConfig(config: AdaptiveConfig): Promise<void>;
incrementAdaptiveDelays(): void;
}
/**
* Central coordinator for all outbound request throttling.
*
* Composes a {@link RateLimiter} (requests-per-second cap), an
* {@link OperatingLimiter} (Bitrix24 operating-time budget), and an
* {@link AdaptiveDelayer} (back-off based on observed server load) into a
* single façade consumed by {@link AbstractHttp}. Tracks aggregate stats
* (retries, consecutive errors, limit hits) and propagates a shared logger
* to all three sub-limiters.
*/
declare class RestrictionManager {
#private;
private _logger;
constructor(params: RestrictionParams);
setLogger(logger: LoggerInterface): void;
getLogger(): LoggerInterface;
applyOperatingLimits(requestId: string, method: string, params?: any): Promise<void>;
/**
* Checks and waits for the rate limit
* The loop is needed for parallel requests (Promise.all())
*/
checkRateLimit(requestId: string, method: string): Promise<void>;
updateStats(requestId: string, method: string, timeData: any): Promise<void>;
handleError(requestId: string, method: string, params: any, error: any, attempt: number): Promise<number>;
/**
* Built-in hard error codes (always throw, never retry).
*
* Includes authorization and fatal codes that must never be silently retried.
* Use `RestrictionParams.hardErrorCodes` to extend this list with custom codes.
*/
static readonly BUILT_IN_HARD_ERROR_CODES: readonly string[];
/**
* Built-in soft error codes (returned as `AjaxResult` with error, never thrown).
*
* Use `RestrictionParams.softErrorCodes` to extend this list with custom codes.
*/
static readonly BUILT_IN_SOFT_ERROR_CODES: readonly string[];
/**
* Codes that cause the SDK to throw immediately.
*
* Composed of:
* - `BUILT_IN_HARD_ERROR_CODES` (always included)
* - `NETWORK_ERROR` and `REQUEST_TIMEOUT` when `retryOnNetworkError === false`
* - `RestrictionParams.hardErrorCodes` (user-provided extensions)
*/
get exceptionCodeForHard(): string[];
/**
* Codes returned as `AjaxResult` with an `AjaxError` payload instead of thrown.
*
* Composed of:
* - `BUILT_IN_SOFT_ERROR_CODES` (always included)
* - `RestrictionParams.softErrorCodes` (user-provided extensions)
*/
get exceptionCodeForSoft(): string[];
incrementError(method: string): void;
resetErrors(method: string): void;
incrementStats(stat: keyof Pick<RestrictionManagerStats, 'retries' | 'consecutiveErrors' | 'limitHits'>): void;
/**
* Returns job statistics
*/
getStats(): RestrictionManagerStats & {
adaptiveDelayAvg: number;
errorCounts: Record<string, number>;
};
/**
* Resets limiters and statistics
*/
reset(): Promise<void>;
setConfig(params: RestrictionParams): Promise<void>;
getParams(): RestrictionParams;
/**
* Public access to the delay function
*/
waiteDelay(ms: number): Promise<void>;
}
/**
* Decides which REST API version a method is routed through.
*
* The SDK no longer maintains a hardcoded v3 method allowlist. A portal's set of
* v3 methods is large and version/edition-dependent (the authoritative list is
* the portal's own OpenAPI document, `rest.documentation.openapi`), so gating on
* a static list both lagged behind the server and blocked valid methods. The
* server is now the single source of truth: an unknown v3 method simply comes
* back as `METHODNOTFOUNDEXCEPTION`.
*
* Consequences:
* - `actions.v3.*` no longer pre-flight-rejects a method — it is sent to the v3
* endpoint and the server validates it.
* - v3 is opt-in only via the explicit `actions.v3.*` surface; version
* auto-detection therefore defaults to v2 (the universal endpoint).
*/
declare class VersionManager {
static create(): VersionManager;
/**
* List of supported API versions.
* The highest version must be first.
*/
getAllApiVersions(): ApiVersion[];
/**
* Retained for backward compatibility. The SDK no longer keeps a v3 method
* allowlist, so support is not decided client-side any more — always returns
* `true`. Method existence is validated by the server.
*/
isSupport(_version: ApiVersion, _method: string): boolean;
/**
* Returns the API version to use when the caller did not specify one. With the
* allowlist removed there is no client-side signal that a method is a v3
* method, so this defaults to v2 (the universal endpoint). Use the explicit
* `actions.v3.*` surface to call a method on v3.
*/
automaticallyObtainApiVersion(_method: string): ApiVersion;
/**
* Batch counterpart of {@link automaticallyObtainApiVersion}. Defaults to v2;
* call `actions.v3.batch.make` explicitly to run a batch on v3.
*/
automaticallyObtainApiVersionForBatch(_calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal | BatchNamedCommandsUniversal): ApiVersion;
}
declare const versionManager: VersionManager;
/**
* Abstract base class for all SDK entry points (B24Frame, B24Hook, etc.).
* Owns the HTTP clients for REST API v2 and v3, the actions surface via {@link ActionsManager},
* and built-in tools via {@link ToolsManager}.
* Concrete subclasses must implement authentication and HTTP transport initialization.
*/
declare abstract class AbstractB24 implements TypeB24 {
/**
* Maximum length for batch response.
*
* @deprecated This const is deprecated and will be removed in version `3.0.0`
* @removed 3.0.0
*/
static readonly batchSize = 50;
protected _isInit: boolean;
protected _httpV2: null | TypeHttp;
protected _httpV3: null | TypeHttp;
protected _logger: LoggerInterface;
protected _actionsManager: ActionsManager;
protected _toolsManager: ToolsManager;
protected constructor();
/**
* @inheritDoc
*/
get isInit(): boolean;
init(): Promise<void>;
destroy(): void;
abstract get auth(): AuthActions;
get actions(): ActionsManager;
get tools(): ToolsManager;
/**
* @inheritDoc
*/
abstract getTargetOrigin(): string;
/**
* @inheritDoc
*/
abstract getTargetOriginWithPath(): Map<ApiVersion, string>;
/**
* Calls the Bitrix24 REST API method.
*
* @deprecated This method is deprecated and will be removed in version `3.0.0`
* - for `restApi:v3` use {@link CallV3.make `b24.actions.v3.call.make(options)`}
* - for `restApi:v2` use {@link CallV2.make `b24.actions.v2.call.make(options)`}
*
* @removed 3.0.0
* @memo Only for `restApi:v2`
*/
callMethod(method: string, params?: object, start?: number): Promise<AjaxResult>;
/**
* Calls a Bitrix24 REST API list method to retrieve all data.
*
* @deprecated This method is deprecated and will be removed in version `3.0.0`
* - for `restApi:v3` use {@link CallListV3.make `b24.actions.v3.callList.make(options)`}
* - for `restApi:v2` use {@link CallListV2.make `b24.actions.v2.callList.make(options)`}
*
* @removed 3.0.0
* @memo Only for `restApi:v2`
*/
callListMethod(method: string, params?: object, progress?: null | ((progress: number) => void), customKeyForResult?: string | null): Promise<Result>;
/**
* Calls a Bitrix24 REST API list method and returns an async generator.
*
* @deprecated This method is deprecated and will be removed in version `3.0.0`
* - for `restApi:v3` use {@link FetchListV3.make `b24.actions.v3.fetchList.make(options)`}
* - for `restApi:v2` use {@link FetchListV2.make `b24.actions.v2.fetchList.make(options)`}
*
* @removed 3.0.0
* @memo Only for `restApi:v2`
*/
fetchListMethod(method: string, params?: any, idKey?: string, customKeyForResult?: string | null): AsyncGenerator<any[]>;
/**
* Executes a batch request to the Bitrix24 REST API.
*
* @deprecated This method is deprecated and will be removed in version `3.0.0`
* - for `restApi:v3` use {@link BatchV3.make `b24.actions.v3.batch.make(options)`}
* - for `restApi:v2` use {@link BatchV2.make `b24.actions.v2.batch.make(options)`}
*
* @removed 3.0.0
* @memo Only for `restApi:v2`
*/
callBatch(calls: Array<any> | object, isHaltOnError?: boolean, returnAjaxResult?: boolean): Promise<Result>;
/**
* Executes a batch request to the Bitrix24 REST API with automatic chunking for any number of commands.
*
* @deprecated This method is deprecated and will be removed in version `3.0.0`
* - for `restApi:v3` use {@link BatchByChunkV3.make `b24.actions.v3.batchByChunk.make(options)`}
* - for `restApi:v2` use {@link BatchByChunkV2.make `b24.actions.v2.batchByChunk.make(options)`}
*
* @removed 3.0.0
* @memo Only for `restApi:v2`
*/
callBatchByChunk(calls: Array<any>, isHaltOnError: boolean): Promise<Result>;
/**
* @inheritDoc
*/
getHttpClient(version: ApiVersion): TypeHttp;
/**
* @inheritDoc
*/
setHttpClient(version: ApiVersion, client: TypeHttp): void;
setLogger(logger: LoggerInterface): void;
getLogger(): LoggerInterface;
/**
* @inheritDoc
*/
setRestrictionManagerParams(params: RestrictionParams): Promise<void>;
/**
* Returns settings for http connection
* @protected
*/
protected _getHttpOptions(): null | object;
/**
* Generates an object not initialized error
* @protected
*/
protected _ensureInitialized(): void;
}
declare class RequestIdGenerator implements IRequestIdGenerator {
getQueryStringParameterName(): string;
getQueryStringSdkParameterName(): string;
getQueryStringSdkTypeParameterName(): string;
private generate;
getRequestId(): string;
getHeaderFieldName(): string;
}
type AjaxResponse<T = unknown> = {
status: number;
payload: SuccessPayload<T>;
};
type TypePrepareParams = TypeCallParams & {
data?: Record<string, any>;
auth?: string;
};
/**
* Abstract base class for all Bitrix24 REST API HTTP transports.
*
* Provides shared infrastructure used by {@link HttpV2} and {@link HttpV3}: Axios instance
* lifecycle, auth token management (including coalesced refresh on 401), rate/operating/adaptive
* limiting via {@link RestrictionManager}, request-id generation, structured logging with
* payload truncation, and request metrics. Concrete subclasses implement version-specific
* batch strategies.
*
* @link https://bitrix24.github.io/b24jssdk/
*/
declare abstract class AbstractHttp implements TypeHttp {
protected _clientAxios: AxiosInstance;
protected _authActions: AuthActions;
protected _requestIdGenerator: RequestIdGenerator;
protected _restrictionManager: RestrictionManager;
/**
* In-flight token refresh, shared so concurrent 401s coalesce into a single
* `refreshAuth()` round-trip — avoids OAuth refresh-token reuse errors when a
* burst of requests expires together. (#182)
*/
protected _pendingRefresh: Promise<AuthData> | null;
protected _logger: LoggerInterface;
protected _isClientSideWarning: boolean;
protected _clientSideWarningMessage: string;
protected _version: ApiVersion;
protected _metrics: {
totalRequests: number;
successfulRequests: number;
failedRequests: number;
totalDuration: number;
byMethod: Map<string, {
count: number;
totalDuration: number;
}>;
lastErrors: Array<{
method: string;
error: string;
timestamp: number;
}>;
};
constructor(authActions: AuthActions, options?: null | object, restrictionParams?: Partial<RestrictionParams>);
get apiVersion(): ApiVersion;
get ajaxClient(): AxiosInstance;
setLogger(logger: LoggerInterface): void;
getLogger(): LoggerInterface;
setRestrictionManagerParams(params: RestrictionParams): Promise<void>;
getRestrictionManagerParams(): RestrictionParams;
/**
* @inheritDoc
*/
getStats(): RestrictionManagerStats & {
adaptiveDelayAvg: number;
errorCounts: Record<string, number>;
totalRequests: number;
successfulRequests: number;
failedRequests: number;
totalDuration: number;
byMethod: Map<string, {
count: number;
totalDuration: number;
}>;
lastErrors: {
method: string;
error: string;
timestamp: number;
}[];
};
/**
* @inheritDoc
*/
reset(): Promise<void>;
protected _updateMetrics(method: string, isSuccess: boolean, duration: number, error?: unknown): void;
abstract batch<T = unknown>(calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal | BatchNamedCommandsUniversal, options?: ICallBatchOptions): Promise<Result<ICallBatchResult<T>>>;
protected _validateParams(requestId: string, method: string, params: TypeCallParams): void;
/**
* Calling the RestApi function
* @param method - REST API method name
* @param params - Parameters for the method.
* @param requestId - Request id
* @returns Promise with AjaxResult
*/
call<T = unknown>(method: string, params: TypeCallParams, requestId?: string): Promise<AjaxResult<T>>;
protected _convertToAjaxError(requestId: string, error: unknown, method: string, params: TypeCallParams): AjaxError;
protected _convertAxiosErrorToAjaxError(requestId: string, axiosError: AxiosError, method: string, params: TypeCallParams): AjaxError;
protected _convertUnknownErrorToAjaxError(requestId: string, error: unknown, method: string, params: TypeCallParams): AjaxError;
/**
* Performs a single call with
* - 401 error handling
* - rate limit check
* - updating operating statistics
*/
protected _executeSingleCall<T = unknown>(requestId: string, method: string, params: TypeCallParams): Promise<AjaxResult<T>>;
protected _ensureAuth(requestId: string): Promise<AuthData>;
/**
* Refresh the auth token, coalescing concurrent callers onto a single
* in-flight `refreshAuth()` so a burst of 401s triggers exactly one refresh
* round-trip. The slot clears once the refresh settles. (#182)
*/
protected _refreshAuth(): Promise<AuthData>;
protected _makeRequestWithAuthRetry<T>(requestId: string, method: string, params: TypeCallParams, authData: AuthData): Promise<AjaxResponse<T>>;
protected _makeAxiosRequest<T>(requestId: string, method: string, params: TypeCallParams, authData: AuthData): Promise<AjaxResponse<T>>;
protected _isAuthError(error: unknown): boolean;
protected _createAjaxResultFromResponse<T>(response: AjaxResponse<T>, requestId: string, method: string, params: TypeCallParams): Promise<AjaxResult<T>>;
/**
* Turns an error the transport already built into the soft `AjaxResult` a
* caller receives, for the codes in `RestrictionManager.exceptionCodeForSoft`.
*
* It used to rebuild the error from a synthetic answer holding only `code` and
* `message`, so the portal's real body was discarded here — which is why
* `validation` was unreachable even though `_convertAxiosErrorToAjaxError` had
* just parsed it (#423).
*
* The error is now **carried** rather than re-derived: the synthetic `answer`
* is kept so `_data` still describes the failure for anything reading it, but
* it is no longer what produces the error — which also means the two can no
* longer disagree. `validation` is deliberately not copied into that synthetic
* answer: nothing parses it back out, so it would be dead weight that a future
* refactor could mistake for the source of truth.
*
* The carried error keeps its `originalError` — the raw `AxiosError`, whose
* `config.url` holds the webhook secret. It is non-enumerable (see
* `SdkError`), so spreads and `JSON.stringify` still cannot reach it, but it
* is now readable via `result.getErrors()` on this path as well as on the
* throwing one. That is deliberate: the two paths differ only in how the error
* is delivered, and a caller debugging one should not find less on the other.
*/
protected _createAjaxResultWithErrorFromResponse<T>(ajaxError: AjaxError, requestId: string, method: string, params: TypeCallParams): AjaxResult<T>;
/**
* Builds the request URL: the method path plus the SDK telemetry query params
* (`bx24_request_id` / `bx24_sdk_ver` / `bx24_sdk_type` — request tracing and
* SDK identification, not auth material).
*
* Carve-out for the legacy positional `task.*` methods (`task.commentitem.*`,
* `task.checklistitem.*`, `task.elapseditem.*`, …): these read the request
* **query string positionally**, so appending the telemetry params shifts
* `Param #0` and the server rejects the call —
* `WRONG_ARGUMENTS: Param #0 (taskId) ... expected integer, but given
* something else`. Verified live against a portal: the same
* `task.commentitem.getlist` / `task.checklistitem.getlist` call succeeds
* without the telemetry params and fails with them; modern `tasks.task.*`
* (named params) is unaffected. So telemetry is omitted only for methods whose
* name STARTS WITH `task.`.
*
* Shared by v2 and v3 (rather than per-transport): once the v3 method
* allowlist was dropped (#259) a positional `task.*` method can be routed via
* `actions.v3.*` too, so v3 needs the same suppression — keeping the rule in
* one place stops the two transports drifting apart again (#207).
*
* The match is anchored (`^task\.`): only legacy positional `task.*` methods
* are suppressed. Modern named-param methods `tasks.task.*` / `bizproc.task.*`
* do NOT start with `task.`, so they KEEP telemetry and stay traceable — the
* boundary was pinned live in #271/#272 (`tasks.task.list` works WITH
* telemetry; legacy `task.*` breaks WITH it). Bitrix24 method names are
* lowercase by convention, so the case-sensitive match is sufficient.
*
* @see https://apidocs.bitrix24.com/settings/how-to-call-rest-api/data-encoding.html#order-of-parameters
*/
protected _prepareMethod(requestId: string, method: string, baseUrl: string): string;
/**
* Processes function parameters and adds authorization
*/
protected _prepareParams(authData: AuthData, params: TypeCallParams): TypePrepareParams;
/**
* @inheritDoc
*/
setClientSideWarning(value: boolean, message: string): void;
/**
* Tests whether the code is executed on the client side
* @return {boolean}
* @protected
*/
protected isServerSide(): boolean;
/**
* Get the BX24 account address with the path based on the API version
*/
getBaseUrl(): string;
/**
* Redaction contract: runs caller params through {@link redactSensitiveParams}
* (see `redact.ts`) so credential-bearing keys are masked before they reach any
* logger context. (#39, #73)
* @see redactSensitiveParams
*/
protected _sanitizeParams(params: TypeCallParams): Record<string, unknown>;
/**
* Redaction contract: params are redacted via {@link _sanitizeParams} →
* {@link redactSensitiveParams} before logging. (#73)
* @see redactSensitiveParams
*/
protected _logRequest(requestId: string, method: string, params: TypeCallParams): void;
protected _logAttempt(requestId: string, method: string, attempt: number, maxRetries: number): void;
protected _logRefreshingAuthToken(requestId: string): void;
protected _logAuthErrorDetected(requestId: string): void;
protected _logSuccessfulRequest(requestId: string, method: string, duration: number): void;
protected _logFailedRequest(requestId: string, method: string, attempt: number, maxRetries: number, error: AjaxError): void;
protected _logAttemptRetryWaiteDelay(requestId: string, method: string, wait: number, attempt: number, maxRetries: number): void;
protected _logAllAttemptsExhausted(requestId: string, method: string, attempt: number, maxRetries: number): void;
protected _logBatchStart(requestId: string, calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal | BatchNamedCommandsUniversal, options: ICallBatchOptions): void;
protected _logBatchCompletion(requestId: string, total: number, errors: number): void;
protected _checkClientSideWarning(requestId: string): void;
}
/**
* HTTP transport for Bitrix24 REST API v2.
*
* Extends {@link AbstractHttp} with v2-specific batch execution: dispatches
* `batch` calls through {@link InteractionBatchV2} and selects either
* {@link ProcessingAsArrayV2} or {@link ProcessingAsObjectV2} depending on
* the shape of the commands argument.
*
* @link https://bitrix24.github.io/b24jssdk/
*/
declare class HttpV2 extends AbstractHttp implements TypeHttp {
constructor(authActions: AuthActions, options?: null | object, restrictionParams?: Partial<RestrictionParams>);
batch<T = unknown>(calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal | BatchNamedCommandsUniversal, options?: ICallBatchOptions): Promise<Result<ICallBatchResult<T>>>;
}
/**
* HTTP transport for Bitrix24 REST API v3.
*
* Extends {@link AbstractHttp} with v3-specific batch execution: dispatches
* `batch` calls through {@link InteractionBatchV3} and selects either
* {@link ProcessingAsArrayV3} or {@link ProcessingAsObjectV3} depending on
* the shape of the commands argument. Use this transport when the target
* Bitrix24 portal supports the REST v3 protocol.
*
* @link https://bitrix24.github.io/b24jssdk/
* @link https://apidocs.bitrix24.com/api-reference/rest-v3/index.html
*/
declare class HttpV3 extends AbstractHttp implements TypeHttp {
constructor(authActions: AuthActions, options?: null | object, restrictionParams?: Partial<RestrictionParams>);
batch<T = unknown>(calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal | BatchNamedCommandsUniversal, options?: ICallBatchOptions): Promise<Result<ICallBatchResult<T>>>;
}
/**
* Locale-aware number formatter built on `Intl.NumberFormat`.
*
* A singleton — obtain it through `useFormatter()` rather than constructing
* it directly (the constructor is guarded and throws `TypeError`). Integers
* are formatted with no fraction digits and non-integers with exactly two.
*/
declare class FormatterNumbers {
private static isInternalConstructing;
private static instance;
private _defLocale;
private constructor();
/**
* Returns the shared `FormatterNumbers` singleton, creating it on first use.
*
* @returns The shared instance.
*/
static getInstance(): FormatterNumbers;
/**
* Sets the default locale used by {@link format} when no explicit locale is
* passed. Affects every consumer of the shared instance.
*
* @param locale - A BCP 47 locale tag (e.g. `'de'`, `'ru'`).
*/
setDefLocale(locale: string): void;
/**
* Formats a number for the given (or default) locale.
*
* The locale falls back to the value set via {@link setDefLocale}, then to
* `navigator.language`, then to `'en'`. Integers get no fraction digits and
* non-integers exactly two. For `ru`-based locales the decimal comma is
* normalised to a dot.
*
* @param value - The number to format.
* @param locale - Optional BCP 47 locale tag overriding the default.
* @returns The formatted number.
*
* @example
* ```ts
* formatterNumber.format(1234.5) // '1,234.50'
* formatterNumber.format(1234.5, 'de') // '1.234,50'
* ```
*/
format(value: number, locale?: string): string;
}
declare class IbanSpecification {
/**
* the code of the country
*/
readonly countryCode: string;
/**
* the length of the IBAN
*/
readonly length: number;
/**
* the structure of the underlying BBAN (for validation and formatting)
*/
readonly structure: string;
/**
* an example valid IBAN
*/
readonly example: string;
private _cachedRegex;
constructor(countryCode: string, length: number, structure: string, example: string);
/**
* Check if the passed iban is valid, according to this specification.
*
* @param {string} iban the iban to validate
* @returns {boolean} true if valid, false otherwise
*/
isValid(iban: string): boolean;
/**
* Convert the passed IBAN to a country-specific BBAN.
*
* @param iban the IBAN to convert
* @param separator the separator to use between BBAN blocks
* @returns {string} the BBAN
*/
toBBAN(iban: string, separator: string): string;
/**
* Convert the passed BBAN to an IBAN for this country specification.
* Please note that <i>"generation of the IBAN shall be the exclusive responsibility of the bank/branch servicing the account"</i>.
* This method implements the preferred algorithm described in http://en.wikipedia.org/wiki/International_Bank_Account_Number#Generating_IBAN_check_digits
*
* @param bban the BBAN to convert to IBAN
* @returns {string} the IBAN
*/
fromBBAN(bban: string): string;
/**
* Check of the passed BBAN is valid.
* This function only checks the format of the BBAN (length and compliance with alphanumeric specifications) but does not
* verify the check digit.
*
* @param bban the BBAN to validate
* @returns {boolean} true if the passed bban is a valid BBAN, according to this specification, false otherwise
*/
isValidBBAN(bban: string): boolean;
/**
* Lazy-loaded regex (parse the structure and construct the regular expression the first time we need it for validation)
*/
private _regex;
/**
* Parse the BBAN structure used to configure each IBAN Specification and returns a matching regular expression.
* A structure is composed of blocks of three characters (one letter and two digits).
* Each block represents
* a logical group in the typical representation of the BBAN.
* For each group, the letter indicates which characters
* are allowed in this group, and the following 2-digits number tells the length of the group.
*
* @param {string} structure the structure to parse
* @returns {RegExp}
*/
private _parseStructure;
/**
* Prepare an IBAN for mod 97 computation by moving the first 4 chars to the end and transforming the letters to
* numbers (A = 10, B = 11, ..., Z = 35), as specified in ISO13616.
*
* @param {string} iban the IBAN
* @returns {string} the prepared IBAN
*/
private _iso13616Prepare;
/**
* Calculates MOD 97 10 of the passed IBAN as specified in ISO7064.
*
* @param iban
* @returns {number} MOD
*/
private _iso7064Mod9710;
}
declare class FormatterIban {
private static isInternalConstructing;
private static instance;
private _countries;
private constructor();
/**
* @return FormatterIban
*/
static getInstance(): FormatterIban;
addSpecification(IBAN: IbanSpecification): void;
/**
* Check if an IBAN is valid.
*
* @param {string} iban the IBAN to validate.
* @returns {boolean} true if the passed IBAN is valid, false otherwise
*/
isValid(iban: string): boolean;
printFormat(iban: string, separator?: string): string;
electronicFormat(iban: string): string;
/**
* Convert an IBAN to a BBAN.
*
* @param iban
* @param {string} [separator] the separator to use between the blocks of the BBAN, defaults to ' '
* @returns {string|*} Convert an IBAN to a BBAN.
*/
toBBAN(iban: string, separator?: string): string;
/**
* Convert the passed BBAN to an IBAN for this country specification.
* Please note that <i>"generation of the IBAN shall be the exclusive responsibility of the bank/branch servicing the account"</i>.
* This method implements the preferred algorithm described in http://en.wikipedia.org/wiki/International_Bank_Account_Number#Generating_IBAN_check_digits
*
* @param countryCode the country of the BBAN
* @param bban the BBAN to convert to IBAN
* @returns {string} the IBAN
*/
fromBBAN(countryCode: string, bban: string): string;
/**
* Check the validity of the passed BBAN.
*
* @param countryCode the country of the BBAN
* @param bban the BBAN to check the validity of
*/
isValidBBAN(countryCode: string, bban: string): boolean;
}
/**
* Composable that exposes the shared number and IBAN formatters used across the SDK.
*
* Both formatters are singletons (`FormatterNumbers.getInstance()` / `FormatterIban.getInstance()`),
* so calling `useFormatter()` multiple times always returns the same underlying instances.
*
* On every call, the returned `formatterIban` is (re-)populated with the full list of IBAN
* country specifications (all countries from the official IBAN registry, several non-official
* countries that follow the IBAN structure, and the French regional/administrative subdivisions
* GF, GP, MQ, RE, PF, TF, YT, NC, BL, MF, PM). Because `formatterIban` is a singleton and
* `addSpecification` simply overwrites the entry for a given country code, re-registering the
* same specifications on subsequent calls is a cheap no-op.
*
* `formatterNumber` is a `FormatterNumbers` instance that wraps `Intl.NumberFormat` for
* locale-aware number formatting (see `FormatterNumbers.format`).
*
* `formatterIban` is a `FormatterIban` instance used to validate and pretty-print IBANs, and to
* convert between IBAN and BBAN representations (see `FormatterIban.isValid`,
* `FormatterIban.printFormat`, `FormatterIban.electronicFormat`, `FormatterIban.toBBAN`,
* `FormatterIban.fromBBAN`, `FormatterIban.isValidBBAN`, `FormatterIban.addSpecification`).
*
* @returns An object with `formatterNumber` (`FormatterNumbers` singleton) and `formatterIban`
* (`FormatterIban` singleton, pre-loaded with IBAN country specifications).
*
* @example
* ```ts
* import { useFormatter } from '@bitrix24/b24jssdk'
*
* const { formatterNumber, formatterIban } = useFormatter()
*
* formatterIban.printFormat('GB29NWBK60161331926819') // 'GB29 NWBK 6016 1331 9268 19'
* formatterIban.isValid('DE89370400440532013000') // true
* formatterNumber.format(1234.567) // '1,234.57'
* ```
*/
declare const useFormatter: () => {
formatterNumber: FormatterNumbers;
formatterIban: FormatterIban;
};
/**
* A `$ref` substitution marker: pulls a single value from an earlier batch
* command's context by dotted path (reference §8).
*/
interface BatchRef {
$ref: string;
}
/**
* A `$refArray` substitution marker: collects one field across the `items[]` of
* an earlier list/tail command into an array (reference §8).
*/
interface BatchRefArray {
$refArray: string;
}
/**
* Helpers for the v3 batch `$ref` / `$refArray` substitution markers (reference
* §8). The **server** performs the substitution: these helpers just build the
* marker objects you drop into a later command's `params` (the SDK forwards
* `params` to the wire `query`), with a little client-side validation. Reference
* an earlier command by its `as` alias — or by its numeric index if you omit `as`.
* Only `item` (get) and `items` (list/tail) results land in context; `add` → id
* and `update` → bool results do not.
*
* **v3 only.** Substitution is a v3 batch feature. Dropped into a v2 batch
* (`actions.v2.batch.make`) the markers are NOT substituted — they are encoded
* as literal filter values and silently yield wrong/empty results.
*
* **Security:** the `path` selects from the batch's own response context, but do
* not build it from untrusted end-user input — a crafted path could read context
* the caller did not intend to expose to the next command.
*
* @example
* import { BatchRefV3 as R } from '@bitrix24/b24jssdk'
*
* const response = await b24.actions.v3.batch.make({
* calls: [
* { method: 'tasks.task.list', as: 'tasks', params: { select: ['id'] } },
* {
* method: 'tasks.task.comment.list',
* // server substitutes the array of ids collected from the first command's items[]
* params: { filter: [['taskId', 'in', R.refArray('tasks.id')]] }
* }
* ]
* })
*/
declare const BatchRefV3: Readonly<{
/**
* `{ $ref: path }` — substitute a single value from context, e.g.
* `ref('newTask.item.id')`. `add` → id / `update` → bool results are NOT in
* context (reference §8); only `item` (get) and `items` (list/tail) are.
*/
ref(path: string): BatchRef;
/**
* `{ $refArray: path }` — collect one field across the `items[]` of an earlier
* list/tail command, e.g. `refArray('tasks.id')`. The path MUST contain a dot
* (`alias.field`); the server rejects a dot-less path with INVALIDSELECTEXCEPTION.
*/
refArray(path: string): BatchRefArray;
}>;
/**
* Server-side Bitrix24 client based on an inbound webhook URL.
*
* Use this class to make REST API calls from a backend service using a
* pre-configured webhook. The webhook URL embeds a secret access key and
* therefore **must never be used in browser or mobile code** — instantiating
* `B24Hook` automatically enables a client-side warning for every HTTP call.
*
* @example
* ```ts
* const b24 = B24Hook.fromWebhookUrl('https://your_domain.bitrix24.com/rest/1/abc123xyz/')
* const result = await b24.actions.v2.call.make({ method: 'user.current' })
* ```
*
* @link https://bitrix24.github.io/b24jssdk/docs/hook/
*/
declare class B24Hook extends AbstractB24 implements TypeB24 {
#private;
constructor(b24HookParams: B24HookParams, options?: {
restrictionParams?: Partial<RestrictionParams>;
});
get auth(): AuthActions;
/**
* Disables warning about client-side query execution
*/
offClientSideWarning(): void;
/**
* @inheritDoc
*/
getTargetOrigin(): string;
/**
* @inheritDoc
*/
getTargetOriginWithPath(): Map<ApiVersion, string>;
/**
* Creates a `B24Hook` instance from a webhook URL.
*
* Accepts both REST API v2 and v3 webhook formats:
* - v2: `https://your_domain.bitrix24.com/rest/{userId}/{secret}`
* - v3: `https://your_domain.bitrix24.com/rest/api/{userId}/{secret}`
*
* Validates that the URL uses HTTPS, has the correct path structure, and
* contains a numeric user ID. Throws a descriptive `Error` on any violation
* without echoing the URL (which contains the secret).
*
* @param url - Full webhook URL as shown in the Bitrix24 admin panel.
* @param options - Optional restriction parameters (rate limits, etc.).
* @returns A ready-to-use `B24Hook` instance.
* @throws {SdkError} If the URL is empty (`JSSDK_HOOK_URL_EMPTY`), unparseable
* (`JSSDK_HOOK_URL_INVALID`), not HTTPS (`JSSDK_HOOK_URL_NOT_HTTPS`),
* malformed (`JSSDK_HOOK_URL_MALFORMED`), or the userId segment is not
* numeric (`JSSDK_HOOK_URL_USER_ID_NOT_NUMERIC`).
*/
static fromWebhookUrl(url: string, options?: {
restrictionParams?: Partial<RestrictionParams>;
}): B24Hook;
}
/**
* Authorization Manager
*/
declare class AuthHookManager implements AuthActions {
#private;
constructor(b24HookParams: B24HookParams);
/**
* @see Http.#prepareParams
*/
getAuthData(): false | AuthData;
refreshAuth(): Promise<AuthData>;
getUniq(prefix: string): string;
/**
* @inheritDoc
*/
getTargetOrigin(): string;
/**
* Get the account address BX24 with path
* - ver2 `https://your_domain.bitrix24.com/rest/{id}/{webhook}`
* - ver3` https://your_domain.bitrix24.com/rest/api/{id}/{webhook}`
*/
getTargetOriginWithPath(): Map<ApiVersion, string>;
/**
* We believe that hooks are created only by the admin
*/
get isAdmin(): boolean;
}
/**
* List of commands for the B24 parent window
*/
declare enum MessageCommands {
getInitData = "getInitData",
setInstallFinish = "setInstallFinish",
setInstall = "setInstall",
refreshAuth = "refreshAuth",
setAppOption = "setAppOption",
setUserOption = "setUserOption",
resizeWindow = "resizeWindow",
reloadWindow = "reloadWindow",
setTitle = "setTitle",
setScroll = "setScroll",
openApplication = "openApplication",
closeApplication = "closeApplication",
openPath = "openPath",
imCallTo = "imCallTo",
imPhoneTo = "imPhoneTo",
imOpenMessenger = "imOpenMessenger",
imOpenHistory = "imOpenHistory",
selectUser = "selectUser",
selectAccess = "selectAccess",
selectCRM = "selectCRM",
/**
* @memo this not work. Need test
*/
showAppForm = "showAppForm",
getInterface = "getInterface",
placementBindEvent = "placementBindEvent"
}
/**
* Application Frame Data Manager
*/
declare class AppFrame {
#private;
constructor(queryParams: B24FrameQueryParams);
/**
* Initializes the data received from the parent window message.
* @param data
*/
initData(data: MessageInitData): AppFrame;
/**
* Returns the sid of the application relative to the parent window like this `9c33468728e1d2c8c97562475edfd96`
*/
getAppSid(): string;
/**
* Get the account address BX24 (https://your_domain.bitrix24.com)
*/
getTargetOrigin(): string;
/**
* Get the account address BX24 with path
* - ver2 `https://your_domain.bitrix24.com/rest/`
* - ver3` https://your_domain.bitrix24.com/rest/api/`
*/
getTargetOriginWithPath(): Map<ApiVersion, string>;
/**
* Returns the localization of the B24 interface
* @return {B24LangList} - default `B24LangList.en`
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/bx24-get-lang.html
*/
getLang(): B24LangList;
}
/**
* Parent Window Request Parameters
* - `isRawValue?: boolean` if true then JSON.stringify will not be executed
* - `isSafely?: boolean` auto completion mode Promise.resolve()
* - `safelyTime?: number` after what time (900 ms) should it be automatically resolved Promise
* - `callBack?: () => void` for placement event
* - `requestId?: string` Unique request identifier for tracking. Used for query deduplication and debugging.
*/
interface SendParams {
isRawValue?: boolean;
isSafely?: boolean;
safelyTime?: number;
callBack?: (...args: any[]) => void;
requestId?: string;
[index: string]: any;
}
/**
* Parent Window Communication Manager at B24
*/
declare class MessageManager {
#private;
protected _logger: LoggerInterface;
private readonly runCallbackHandler;
constructor(appFrame: AppFrame);
setLogger(logger: LoggerInterface): void;
getLogger(): LoggerInterface;
/**
* Subscribe to the onMessage event of the parent window
*/
subscribe(): void;
/**
* Unsubscribe from the onMessage event of the parent window, and tear the
* manager down.
*
* Removing the listener is not enough. Every in-flight `send()` is waiting on
* a promise that only the listener could settle, so dropping the listener
* alone strands each of them **forever** — with its `isSafely` timer still
* armed and its entry still in the callback map. `B24Frame.destroy()` calls
* this, so an SPA that mounts and unmounts the frame accumulated one such set
* per cycle (#146; the same class of leak as #222 in `PullClient`).
*
* Pending sends are therefore **rejected**, not left hanging, with
* `JSSDK_FRAME_DISPOSED` — mirroring how a disposed `PullClient` rejects
* `start()` with `PULL_DISPOSED`. A caller awaiting a command that can no
* longer be answered should learn that; silence is the one outcome it cannot
* act on.
*
* Note the consequence: a `send()` whose result was discarded without a
* `.catch()` turns into an unhandled rejection at teardown. Most SDK commands
* pass `isSafely`, which settles them on their own timer, so they are normally
* already gone by the time this runs — but **not all of them do**.
* `ParentManager.closeApplication()` and `SliderManager.closeSliderAppPage()`
* deliberately pass `isSafely: false` ("everything will be closed, and timeout
* will not be able to do anything"), and those are exactly the calls made as
* an app tears itself down — the likeliest race with this method. The awaited
* commands (`getInitData`, `refreshAuth`, the dialog selectors) send without
* `isSafely` too, but their callers await them, so the rejection surfaces
* where it can be handled.
*
* A caller that fires `closeApplication()` without awaiting it should attach
* `.catch(() => {})` if it also tears the frame down in the same breath.
*/
unsubscribe(): void;
/**
* Send message to parent window
* The answer (if) we will get in _runCallback
*
* @param command
* @param params
*/
send(command: string | MessageCommands, params?: null | SendParams): Promise<any>;
/**
* Fulfilling a promise based on messages from the parent window
*
* @param event
* @private
*/
_runCallback(event: MessageEvent): void;
}
/**
* Parent window manager
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/
*/
declare class ParentManager {
#private;
constructor(messageManager: MessageManager);
get message(): MessageManager;
/**
* The method closes the open modal window with the application
*
* @return {Promise<void>}
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/bx24-close-application.html
*/
closeApplication(): Promise<void>;
/**
* Sets the size of the frame containing the application to the size of the frame's content.
*
* @return {Promise<void>}
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/bx24-fit-window.html
*
* @memo in certain situations it may not be executed (placement of the main window after installing the application), in this case isSafely mode will work
*/
fitWindow(): Promise<any>;
/**
* Sets the size of the frame containing the application to the size of the frame's content.
*
* @param {number} width
* @param {number} height
*
* @return {Promise<void>}
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/bx24-resize-window.html
*
* @memo in certain situations it may not be executed, in this case isSafely mode will be triggered
*/
resizeWindow(width: number, height: number): Promise<void>;
/**
* Automatically resize `document.body` of frame with application according to frame content dimensions
* If you pass appNode, the height will be calculated relative to it
*
* @param {HTMLElement|null} appNode
* @param {number} minHeight
* @param {number} minWidth
*
* @return {Promise<void>}
*/
resizeWindowAuto(appNode?: null | HTMLElement, minHeight?: number, minWidth?: number): Promise<void>;
/**
* This function returns the inner dimensions of the application frame
*
* @return {Promise<{scrollWidth: number; scrollHeight: number}>}
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/bx24-get-scroll-size.html
*/
getScrollSize(): {
scrollWidth: number;
scrollHeight: number;
};
/**
* Scrolls the parent window
*
* @param {number} scroll should specify the vertical scrollbar position (0 - scroll to the very top)
* @return {Promise<void>}
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/bx24-scroll-parent-window.html
*/
scrollParentWindow(scroll: number): Promise<void>;
/**
* Reload the page with the application (the whole page, not just the frame).
*
* @return {Promise<void>}
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/bx24-reload-window.html
*/
reloadWindow(): Promise<void>;
/**
* Sets the in-layout page title (the `#pagetitle` element the portal renders around the app).
*
* Does NOT change the browser tab title (`document.title`): the portal applies this command to
* `#pagetitle`, never to the tab. To set the browser tab title, open the view as a slider via
* `SliderManager.openSliderAppPage` with a `bx24_title` option.
*
* @param {string} title
*
* @return {Promise<void>}
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/bx24-set-title.html
*/
setTitle(title: string): Promise<void>;
/**
* Initiates a call via internal communication.
*
* **Fire-and-forget.** The portal's bridge handler is declared as
* `function(params)` — it does not accept the callback argument the message
* layer offers, so it never reports back. The returned promise means "the
* command was posted", not "the call started"; it resolves on the SDK's own
* `isSafely` timer, and the accompanying `stop by timeout` log line is the
* normal outcome rather than a fault. See {@link ParentManager} — the same
* holds for every `im*` method here. (#331)
*
* The portal reaches the current API underneath: `BXIM.callTo` →
* `Messenger.Public.startVideoCall`. The deprecation warning in the portal
* console is emitted by the portal's own compatibility layer, not by this
* call, and an application cannot avoid it — the newer names are not part of
* the placement's command vocabulary.
*
* @param {number} userId The identifier of the account user
* @param {boolean} isVideo true - video call, false - audio call. Optional parameter.
*
* @return {Promise<void>} resolves once the command has been posted.
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/bx24-im-call-to.html
*/
imCallTo(userId: number, isVideo?: boolean): Promise<void>;
/**
* Makes a call to the phone number.
*
* **Fire-and-forget** — see {@link imCallTo} for what the returned promise
* does and does not mean.
*
* `params` is forwarded for the phone manager, matching the second argument of
* the portal's `Messenger.startPhoneCall(number, params)`. The portal's bridge
* handler currently enumerates fields by hand and reads only `phone`, so this
* is dropped on the way today; sending it costs nothing (an unknown field is
* ignored) and starts working without an application change once the portal
* forwards it. (#331)
*
* @param {string} phone Phone number. The number can be in the format: `+44 20 1234 5678` or `x (xxx) xxx-xx-xx`
* @param {Record<string, unknown>} [params] Extra call parameters for the phone manager.
*
* @return {Promise<void>} resolves once the command has been posted.
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/bx24-im-phone-to.html
*/
imPhoneTo(phone: string, params?: Record<string, unknown>): Promise<void>;
/**
* Opens the messenger window
* userId or chatXXX - chat, where XXX is the chat identifier, which can simply be a number.
* sgXXX - group chat, where XXX is the social network group number (the chat must be enabled in this group).
*
* XXXX** - open line, where XXX is the code obtained via the Rest method imopenlines.network.join.
*
* If nothing is passed, the chat interface will open with the last opened dialog.
*
* **Fire-and-forget** — see {@link imCallTo} for what the returned promise
* does and does not mean.
*
* `messageId` matches the second argument of the portal's
* `Messenger.openChat(dialogId, messageId)`, which focuses a specific message.
* The portal's bridge handler reads only `dialogId` today, so it is dropped on
* the way; sending it is free and starts working without an application change
* once the portal forwards it. (#331)
*
* @param {number|`chat${number}`|`sg${number}`|`imol|${number}`|undefined} dialogId
* @param {number} [messageId] Message to focus once the chat opens.
*
* @return {Promise<void>} resolves once the command has been posted.
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/bx24-im-open-messenger.html
* @link https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=93&LESSON_ID=20152&LESSON_PATH=7657.7883.8025.20150.20152
*
*/
imOpenMessenger(dialogId: number | `chat${number}` | `sg${number}` | `imol|${number}` | undefined, messageId?: number): Promise<void>;
/**
* Opens the history window
* Identifier of the dialog:
*
* userId or chatXXX - chat, where XXX is the chat identifier, which can simply be a number.
* imol|XXXX - open line, where XXX is the session number of the open line.
*
* **Fire-and-forget** — see {@link imCallTo} for what the returned promise
* does and does not mean.
*
* Note the portal routes this differently from the other three: its
* compatibility layer calls the opener directly, bypassing
* `Messenger.Public`. For an ordinary `dialogId` it lands in `openChat`, which
* is what the deprecation notice recommends; for an open-line id
* (`imol|…`) it takes a separate branch whose public equivalent is
* `openLinesHistory`, not `openChat`. (#331)
*
* @param {number|`chat${number}`|`imol|${number}`} dialogId
*
* @return {Promise<void>} resolves once the command has been posted.
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/bx24-im-open-history.html
*/
imOpenHistory(dialogId: number | `chat${number}` | `imol|${number}`): Promise<void>;
}
/**
* Manager for working with application settings via communication with the parent window
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/options/index.html
*/
declare class OptionsManager$1 {
#private;
constructor(messageManager: MessageManager);
/**
* Initializes the data received from the parent window message.
* @param data
*/
initData(data: MessageInitData): OptionsManager$1;
/**
* Getting application option
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/options/bx24-app-option-get.html
*/
appGet(option: string): any;
/**
* Updates application data through the parent window
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/options/bx24-app-option-set.html
*/
appSet(option: string, value: any): Promise<void>;
/**
* Getting user option
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/options/bx24-user-option-get.html
*/
userGet(option: string): any;
/**
* Updates user data through the parent window
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/options/bx24-user-option-set.html
*/
userSet(option: string, value: any): Promise<void>;
}
type SelectedUser = {
/**
* user identifier
*/
id: NumberString;
/**
* formatted username
*/
name: string;
photo: string;
position: string;
url: string;
/**
* The flag indicates that the selected user is a subordinate of the current user
*/
sub: boolean;
/**
* The flag indicates that the selected user is the manager of the current user
*/
sup: boolean;
};
type SelectedAccess = {
/**
* access permission identifier. Examples of identifiers:
* - U1 — user with identifier 1
* - IU1 — employees with identifier 1
* - DR2 — all department and subdepartment employees with identifier 2
* - D6 — all department employees with identifier 6
* - G2 — group with identifier 2 (all visitors)
* - SG4 — social network group with identifier 4
* - AU — all authorized users
* - CR — current user
*/
id: `AU` | `CR` | `U${number}` | `IU${number}` | `DR${number}` | `D${number}` | `G${number}` | `SG${number}`;
/**
* name of the access permission
*/
name: string;
};
type SelectCRMParamsEntityType = 'lead' | 'contact' | 'company' | 'deal' | 'quote';
type SelectCRMParamsValue = {
lead?: number[];
contact?: number[];
company?: number[];
deal?: number[];
quote?: number[];
};
type SelectCRMParams = {
/**
* Which types of objects to display in the dialog. Possible values:
* - lead — Leads
* - contact — Contacts
* - company — Companies
* - deal — Deals
* - quote — Estimates
*/
entityType: SelectCRMParamsEntityType[];
/**
* Whether multiple objects can be selected. Default is `false`
*/
multiple: boolean;
/**
* Which objects to initially add to the selected in the dialog. Works only if `multiple = true`
*/
value?: SelectCRMParamsValue;
};
type SelectedCRMEntity = {
id: string;
type: SelectCRMParamsEntityType;
place: string;
title: string;
desc: string;
url: string;
};
type SelectedCRM = {
lead?: (SelectedCRMEntity & {
id: `L_${number}`;
})[];
contact?: (SelectedCRMEntity & {
id: `C_${number}`;
image: string;
})[];
company?: (SelectedCRMEntity & {
id: `CO_${number}`;
image: string;
})[];
deal?: (SelectedCRMEntity & {
id: `D_${number}`;
})[];
quote?: (SelectedCRMEntity & {
id: `Q_${number}`;
})[];
};
/**
* Select dialog manager
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/system-dialogues/index.html
*/
declare class DialogManager {
#private;
constructor(messageManager: MessageManager);
/**
* Method displays the standard single user selection dialog
* It only shows company employees
*
* @return {Promise<null|SelectedUser>}
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/system-dialogues/bx24-select-user.html
*/
selectUser(): Promise<null | SelectedUser>;
/**
* Method displays the standard multiple user selection dialog
* It only shows company employees
*
* @return {Promise<SelectedUser[]>}
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/system-dialogues/bx24-select-users.html
*/
selectUsers(): Promise<SelectedUser[]>;
/**
* Method displays a standard access permission selection dialog
*
* @param {string[]} blockedAccessPermissions
* @return {Promise<SelectedAccess[]>}
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/system-dialogues/bx24-select-access.html
*/
selectAccess(blockedAccessPermissions?: string[]): Promise<SelectedAccess[]>;
/**
* Invokes the system dialog for selecting CRM entities
* (leads, contacts, companies, deals, quotes).
*
* The resolved `SelectedCRM` object contains a separate bucket per
* entity type. Each present bucket is a real `Array`, so consumers can
* use `.length`, `.map()`, `for..of`, etc. directly. Buckets for entity
* types that were not selected (or not requested via `entityType`) are
* left `undefined` rather than being set to an empty array.
*
* Note: the parent window historically returned each bucket as a
* `Record<string, SelectedCRMEntity>` (e.g. `{ 0: {...}, 1: {...} }`).
* The SDK normalizes that response to a real array before returning it.
*
* @param {SelectCRMParams} [params] - Filter and behavior options.
* - `entityType`: which entity types are shown in the dialog.
* - `multiple`: allow multiple selection (default `false`).
* - `value`: pre-selected entities (only applied when `multiple` is `true`).
* @return {Promise<SelectedCRM>} Resolves to an object whose properties
* (`lead`, `contact`, `company`, `deal`, `quote`) are arrays of
* {@link SelectedCRMEntity} objects.
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/system-dialogues/bx24-select-crm.html
*/
selectCRM(params?: SelectCRMParams): Promise<SelectedCRM>;
}
/**
* Sliders Manager
*/
declare class SliderManager {
#private;
constructor(appFrame: AppFrame, messageManager: MessageManager);
/**
* Returns the URL relative to the domain name and path
*/
getUrl(path?: string): URL;
/**
* Get the account address BX24
*/
getTargetOrigin(): string;
/**
* When the method is called, a pop-up window with the application frame will be opened.
*
* Settings are passed via `bx24_`-prefixed keys (e.g. `bx24_title`, `bx24_width`).
* `bx24_title` sets the slider title; the portal also reflects it to the browser tab title
* (`document.title`) — unlike `ParentManager.setTitle`, which only updates the in-layout `#pagetitle`.
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/bx24-open-application.html
*/
openSliderAppPage(params?: any): Promise<any>;
/**
* The method closes the open modal window with the application
*
* @return {Promise<void>}
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/bx24-close-application.html
*/
closeSliderAppPage(): Promise<void>;
/**
* Opens the specified path inside the portal in the slider.
* @param {URL} url
* @param {number} width - Number in the range from 1640 to 1200, from 1200 to 950, from 950 to 900, from 900 ...
* @return {Promise<StatusClose>}
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/bx24-open-path.html
* @memo /^\/(crm\/(deal|lead|contact|company|type)|marketplace|company\/personal\/user\/[0-9]+|workgroups\/group\/[0-9]+)\//
*/
openPath(url: URL, width?: number): Promise<StatusClose>;
}
/**
* Placement Manager
*
* @see https://apidocs.bitrix24.com/api-reference/widgets/ui-interaction/index.html
*/
declare class PlacementManager {
#private;
constructor(messageManager: MessageManager);
/**
* Initializes the data received from the parent window message.
* @param data
*/
initData(data: MessageInitData): PlacementManager;
/**
* Symlink on `placement`
* For backward compatibility
*/
get title(): string;
get placement(): string;
get isDefault(): boolean;
get options(): any;
get isSliderMode(): boolean;
/**
* Get Information About the JS Interface of the Current Embedding Location
*
* @return {Promise<any>}
*
* @link https://apidocs.bitrix24.com/api-reference/widgets/ui-interaction/bx24-placement-get-interface.html
*/
getInterface(): Promise<any>;
/**
* Set Up the Interface Event Handler
* @param {string} eventName
* @param {(...args: any[]) => void} callBack
* @return {Promise<any>}
*
* @link https://apidocs.bitrix24.com/api-reference/widgets/ui-interaction/bx24-placement-bind-event.html
*/
bindEvent(eventName: string, callBack: (...args: any[]) => void): Promise<any>;
/**
* Call the Registered Interface Command
*
* @link https://apidocs.bitrix24.com/api-reference/widgets/ui-interaction/bx24-placement-call.html
*
* @memo The `setValue` command is special: the parent window calls `JSON.parse(value)`
* on the received payload, so `value` MUST be a JSON-serialized string
* (e.g. `JSON.stringify('test')` or `JSON.stringify({ a: 1 })`).
* Prefer {@link PlacementManager.setValue} which serializes for you.
*
* @throws {TypeError} when `command === 'setValue'` and `parameters.value` is not a string.
*/
call(command: 'setValue', parameters: {
value: string;
}): Promise<any>;
call(command: string, parameters?: Record<string, any>): Promise<any>;
/**
* Set Value for the Current Embedding Location
*
* Convenience wrapper around `placement.call('setValue', ...)` that handles
* JSON serialization. Pass any value (string, number, boolean, object, array)
* — it will be serialized via `JSON.stringify` before being sent to the
* parent window, which performs `JSON.parse` on receipt.
*
* @param { unknown } value Any JSON-serializable value
* @return { Promise<any> }
*
* @link https://apidocs.bitrix24.com/api-reference/widgets/ui-interaction/bx24-placement-call.html
*
* @example
* await b24.placement.setValue('test')
* await b24.placement.setValue({ id: 1, title: 'demo' })
*/
setValue(value: unknown): Promise<any>;
/**
* Set Up the Interface Event Handler
* @param {string} command
* @param {null | string | Record<string, any>} parameters
* @param {(...args: any[]) => void} callBack
*
* @return {Promise<any>}
*/
callCustomBind(command: string, parameters: (null | string | Record<string, any>) | undefined, callBack: (...args: any[]) => void): Promise<any>;
}
/**
* Bitrix24 client for applications embedded in an iframe (frame placement).
*
* Replaces the legacy `api.bitrix24.com` JS library. Initialise via the
* `initializeB24Frame()` factory, which performs the postMessage handshake
* with the parent Bitrix24 page and resolves once the app frame is ready.
*
* Key capabilities:
* - REST API calls (v2 & v3) with automatic token refresh on 401 responses.
* - Access to install/first-run flags (`isInstallMode`, `isFirstRun`).
* - UI helpers via `parent`, `dialog`, `slider`, and `placement` managers.
* - Per-app option storage through `options` manager.
*
* @link https://api.bitrix24.com/api/v1/
* @link https://bitrix24.github.io/b24jssdk/docs/frame/
* @see /bitrix/js/rest/applayout.js
*/
declare class B24Frame extends AbstractB24 implements TypeB24 {
#private;
constructor(queryParams: B24FrameQueryParams, options?: {
restrictionParams?: Partial<RestrictionParams>;
});
setLogger(logger: LoggerInterface): void;
get isFirstRun(): boolean;
get isInstallMode(): boolean;
get parent(): ParentManager;
get auth(): AuthActions;
get slider(): SliderManager;
get placement(): PlacementManager;
get options(): OptionsManager$1;
get dialog(): DialogManager;
init(): Promise<void>;
/**
* Destructor.
* Removes an event subscription
*/
destroy(): void;
/**
* Signals that the installer or application setup has finished running.
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/system-functions/bx24-install-finish.html
*/
installFinish(): Promise<any>;
/**
* @inheritDoc
*/
getTargetOrigin(): string;
/**
* @inheritDoc
*/
getTargetOriginWithPath(): Map<ApiVersion, string>;
/**
* Returns the sid of the application relative to the parent window like this `9c33468728e1d2c8c97562475edfd96`
*/
getAppSid(): string;
/**
* Returns the localization of the B24 interface
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/bx24-get-lang.html
*/
getLang(): B24LangList;
}
/**
* Authorization Manager
*/
declare class AuthManager implements AuthActions {
#private;
constructor(appFrame: AppFrame, messageManager: MessageManager);
/**
* Initializes the data received from the parent window message.
* @param data
*/
initData(data: MessageInitData): AuthManager;
/**
* Returns authorization data
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/system-functions/bx24-get-auth.html
*/
getAuthData(): false | AuthData;
/**
* Updates authorization data through the parent window
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/system-functions/bx24-refresh-auth.html
*/
refreshAuth(): Promise<AuthData>;
getUniq(prefix: string): string;
/**
* Determines whether the current user has administrator rights
*
* @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/bx24-is-admin.html
*/
get isAdmin(): boolean;
/**
* @inheritDoc
*/
getTargetOrigin(): string;
/**
* @inheritDoc
*/
getTargetOriginWithPath(): Map<ApiVersion, string>;
}
declare class RefreshTokenError extends SdkError {
}
/**
* OAuth Authorization Manager
*
* @link https://apidocs.bitrix24.com/settings/oauth/index.html
* @link https://bitrix24.github.io/b24jssdk/docs/oauth/
*/
declare class AuthOAuthManager implements AuthActions {
#private;
constructor(b24OAuthParams: B24OAuthParams, oAuthSecret: B24OAuthSecret);
/**
* Returns authorization data
* @see Http.#prepareParams
*/
getAuthData(): false | AuthData;
/**
* Updates authorization data
*/
refreshAuth(): Promise<AuthData>;
setCallbackRefreshAuth(cb: CallbackRefreshAuth): void;
removeCallbackRefreshAuth(): void;
setCustomRefreshAuth(cb: CustomRefreshAuth): void;
removeCustomRefreshAuth(): void;
getUniq(prefix: string): string;
/**
* @inheritDoc
*/
getTargetOrigin(): string;
/**
* @inheritDoc
*/
getTargetOriginWithPath(): Map<ApiVersion, string>;
/**
* Determines whether the current user has administrator rights
*/
get isAdmin(): boolean;
initIsAdmin(http: TypeHttp, requestId?: string): Promise<void>;
}
/**
* Server-side Bitrix24 client for OAuth 2.0 applications (local and distributed).
*
* Manages access- and refresh-token lifecycle: the underlying `AuthOAuthManager`
* automatically refreshes the access token when it expires, using the supplied
* `oAuthSecret` (client ID + client secret). Like `B24Hook`, this class is
* **server-side only** — OAuth secrets must not be exposed in browser code.
*
* @example
* ```ts
* const b24 = new B24OAuth(authOptions, { clientId: '...', clientSecret: '...' })
* const result = await b24.actions.v2.call.make({ method: 'crm.lead.list' })
* ```
*
* @link https://apidocs.bitrix24.com/settings/oauth/index.html
* @link https://bitrix24.github.io/b24jssdk/docs/oauth/
*/
declare class B24OAuth extends AbstractB24 implements TypeB24 {
#private;
constructor(authOptions: B24OAuthParams, oAuthSecret: B24OAuthSecret, options?: {
restrictionParams?: Partial<RestrictionParams>;
});
/**
* Used to initialize information about the current user.
*/
initIsAdmin(requestId?: string): Promise<void>;
/**
* Sets an asynchronous Callback to receive updated authorization data
* @param cb
*/
setCallbackRefreshAuth(cb: CallbackRefreshAuth): void;
/**
* Removes Callback to receive updated authorization data
*/
removeCallbackRefreshAuth(): void;
/**
* Sets an asynchronous function for custom get new refresh token
* @param cb
*/
setCustomRefreshAuth(cb: CustomRefreshAuth): void;
/**
* Removes function for custom get new refresh token
*/
removeCustomRefreshAuth(): void;
/**
* Disables warning about client-side query execution
*/
offClientSideWarning(): void;
get auth(): AuthActions;
/**
* @inheritDoc
*/
getTargetOrigin(): string;
/**
* @inheritDoc
*/
getTargetOriginWithPath(): Map<ApiVersion, string>;
}
declare abstract class AbstractHelper {
protected _b24: TypeB24;
protected _data: any;
protected _logger: LoggerInterface;
constructor(b24: TypeB24);
setLogger(logger: LoggerInterface): void;
getLogger(): LoggerInterface;
/**
* Initializes the data received
*/
initData(_data: any): Promise<void>;
abstract get data(): any;
}
declare class ProfileManager extends AbstractHelper {
protected _data: null | TypeUser;
/**
* @inheritDoc
*/
initData(data: TypeUser): Promise<void>;
get data(): TypeUser;
}
declare class AppManager extends AbstractHelper {
protected _data: null | TypeApp;
/**
* @inheritDoc
*/
initData(data: TypeApp): Promise<void>;
get data(): TypeApp;
get statusCode(): string;
}
declare class PaymentManager extends AbstractHelper {
protected _data: null | TypePayment;
/**
* @inheritDoc
*/
initData(data: TypePayment): Promise<void>;
get data(): TypePayment;
}
declare class LicenseManager extends AbstractHelper {
protected _data: null | TypeLicense;
/**
* @inheritDoc
*/
initData(data: TypeLicense): Promise<void>;
get data(): TypeLicense;
/**
* Set RestrictionManager params by license
* @link https://apidocs.bitrix24.com/api-reference/common/system/app-info.html
*/
makeRestrictionManagerParams(): Promise<void>;
}
type CurrencyFormatInit = {
DECIMALS: NumberString;
DEC_POINT: string;
FORMAT_STRING: string;
FULL_NAME: string;
HIDE_ZERO: BoolString;
THOUSANDS_SEP?: string;
THOUSANDS_VARIANT: string;
};
type CurrencyInit = {
AMOUNT: NumberString;
AMOUNT_CNT: NumberString;
BASE: BoolString;
CURRENCY: string;
DATE_UPDATE: ISODate;
DECIMALS: NumberString;
DEC_POINT: string;
FORMAT_STRING: string;
FULL_NAME: string;
LID: string;
SORT: NumberString;
THOUSANDS_SEP?: string;
LANG?: Record<string, CurrencyFormatInit>;
};
type CurrencyInitData = {
currencyBase: string;
currencyList: CurrencyInit[];
};
type CurrencyData = {
currencyBase: string;
currencyList: Map<string, Currency>;
};
declare class CurrencyManager extends AbstractHelper {
/**
* @inheritDoc
*/
initData(data: CurrencyInitData): Promise<void>;
loadData(): Promise<void>;
get data(): CurrencyData;
setBaseCurrency(currencyBase: string): void;
get baseCurrency(): string;
setCurrencyList(list?: CurrencyInit[]): void;
getCurrencyFullName(currencyCode: string, langCode: string): string;
getCurrencyLiteral(currencyCode: string, langCode?: string): string;
get currencyList(): string[];
format(value: number, currencyCode: string, langCode: string): string;
}
declare class OptionsManager extends AbstractHelper {
protected _data: Map<string, any>;
protected _type: 'app' | 'user';
static getSupportTypes(): TypeOption[];
static prepareArrayList(list: any): any[];
constructor(b24: TypeB24, type: 'app' | 'user');
get data(): Map<string, any>;
reset(): void;
/**
* @inheritDoc
*/
initData(data: any): Promise<void>;
getJsonArray(key: string, defValue?: any[]): any[];
getJsonObject(key: string, defValue?: object): object;
getFloat(key: string, defValue?: number): number;
getInteger(key: string, defValue?: number): number;
getBoolYN(key: string, defValue?: boolean): boolean;
getBoolNY(key: string, defValue?: boolean): boolean;
getString(key: string, defValue?: string): string;
getDate(key: string, defValue?: null | DateTime): null | DateTime;
encode(value: any): string;
decode(data: string, defaultValue: any): any;
protected getMethodSave(): string;
save(options: any, optionsPull?: {
moduleId: string;
command: string;
params: any;
}, requestId?: string): Promise<Result>;
}
/**
* A universal class that is used to manage the initial application data
*/
declare class B24HelperManager {
private readonly _b24;
private _isInit;
private _profile;
private _app;
private _payment;
private _license;
private _currency;
private _appOptions;
private _userOptions;
private _b24PullClient;
private _pullClientUnSubscribe;
private _pullClientModuleId;
protected _logger: LoggerInterface;
constructor(b24: TypeB24);
setLogger(logger: LoggerInterface): void;
getLogger(): LoggerInterface;
destroy(): void;
loadData(dataTypes?: LoadDataType[], requestId?: string): Promise<void>;
private parseUserData;
private parseAppData;
private parsePaymentData;
private parseLicenseData;
private parseCurrencyData;
private parseOptionsData;
get isInit(): boolean;
get forB24Form(): TypeB24Form;
/**
* Get the account address BX24 (https://your_domain.bitrix24.com)
*/
get hostName(): string;
get profileInfo(): ProfileManager;
get appInfo(): AppManager;
get paymentInfo(): PaymentManager;
get licenseInfo(): LicenseManager;
get currency(): CurrencyManager;
get appOptions(): OptionsManager;
get userOptions(): OptionsManager;
get isSelfHosted(): boolean;
/**
* Returns the increment step of fields of type ID
* @memo in a cloud step = 2 in box step = 1
*
* @returns {number}
*/
get primaryKeyIncrementValue(): number;
/**
* Defines specific URLs for a Bitrix24 box or cloud
*/
get b24SpecificUrl(): Record<keyof typeof TypeSpecificUrl, string>;
usePullClient(prefix?: string, userId?: number): B24HelperManager;
private initializePullClient;
subscribePullClient(callback: (message: TypePullMessage) => void, moduleId?: string): B24HelperManager;
startPullClient(): void;
getModuleIdPullClient(): string;
private _destroyPullClient;
private ensureInitialized;
}
declare const useB24Helper: () => {
initB24Helper: ($b24: TypeB24, dataTypes?: LoadDataType[], requestId?: string) => Promise<B24HelperManager>;
isInitB24Helper: () => boolean;
destroyB24Helper: () => void;
getB24Helper: () => B24HelperManager;
usePullClient: () => void;
useSubscribePullClient: (callback: (message: TypePullMessage) => void, moduleId?: string) => void;
startPullClient: () => void;
};
declare class PullClient implements ConnectorParent {
private _logger;
private _restClient;
private _status;
private _context;
private readonly _guestMode;
private readonly _guestUserId;
private _userId;
private _configGetMethod;
private _getPublicListMethod;
private _siteId;
private _enabled;
private _unloading;
private _starting;
private _debug;
private _connectionAttempt;
private _connectionType;
private _skipStorageInit;
private _skipCheckRevision;
private _subscribers;
private _watchTagsQueue;
private _watchUpdateInterval;
private _watchForceUpdateInterval;
private _configTimestamp;
private _session;
private _connectors;
private _isSecure;
private _config;
private _storage;
private _sharedConfig;
private _channelManager;
private _jsonRpcAdapter;
/**
* @depricate
*/
private _reconnectTimeout;
private _restartTimeout;
private _restoreWebSocketTimeout;
private _checkInterval;
private _offlineTimeout;
private _watchUpdateTimeout;
private _pingWaitTimeout;
private readonly _timerFields;
private _windowListeners;
private _isManualDisconnect;
private _disposed;
private _loggingEnabled;
private _onPingTimeoutHandler;
private _onBeforeUnloadHandler;
private _onOfflineHandler;
private _onOnlineHandler;
private _userStatusCallbacks;
private _connectPromise;
private _startingPromise;
private _startGeneration;
/**
* @param params
*/
constructor(params: TypePullClientParams);
setLogger(logger: LoggerInterface): void;
getLogger(): LoggerInterface;
/**
* Terminal teardown: removes the window listeners, cancels every pending timer,
* persists the session for a quick re-init, and disconnects. Irreversible — a
* destroyed client schedules no further work and `start()` rejects with
* `PULL_DISPOSED`; create a new instance to reconnect.
*/
destroy(): void;
private init;
get connector(): null | TypeConnector;
get status(): PullStatus;
/**
* @param status
*/
set status(status: PullStatus);
get session(): TypePullClientSession;
/**
* Creates a subscription to incoming messages.
*
* @param {TypeSubscriptionOptions | TypeSubscriptionCommandHandler} params
* @returns { () => void } - Unsubscribe callback function
*/
subscribe(params: TypeSubscriptionOptions | TypeSubscriptionCommandHandler): () => void;
/**
* @param {TypeSubscriptionCommandHandler} handler
* @returns {() => void} - Unsubscribe callback function
*/
private attachCommandHandler;
/**
* Connects the client and begins receiving events.
*
* @param config
* @throws Rejects with `{ ex: { error: 'PULL_DISPOSED' } }` when called after
* `destroy()` — a destroyed client cannot be restarted; create a new instance.
*/
start(config?: null | (TypePullClientConfig & {
skipReconnectToLastSession?: boolean;
})): Promise<boolean>;
/**
* @param disconnectCode
* @param disconnectReason
*/
restart(disconnectCode?: number | CloseReasons, disconnectReason?: string): void;
stop(disconnectCode?: number | CloseReasons, disconnectReason?: string): void;
private clearAllTimers;
private armTimeout;
private addWindowListener;
private removeAllWindowListeners;
reconnect(disconnectCode: number | CloseReasons, disconnectReason: string, delay?: number): void;
/**
* @param lastMessageId
*/
setLastMessageId(lastMessageId: string): void;
/**
* Send a single message to the specified users.
*
* @param users User ids of the message receivers.
* @param moduleId Name of the module to receive a message,
* @param command Command name.
* @param {object} params Command parameters.
* @param [expiry] Message expiry time in seconds.
* @return {Promise}
*/
sendMessage(users: number[], moduleId: string, command: string, params: any, expiry?: number): Promise<any>;
/**
* Send a single message to the specified public channels.
*
* @param publicChannels Public ids of the channels to receive a message.
* @param moduleId Name of the module to receive a message,
* @param command Command name.
* @param {object} params Command parameters.
* @param [expiry] Message expiry time in seconds.
* @return {Promise}
*/
sendMessageToChannels(publicChannels: string[], moduleId: string, command: string, params: any, expiry?: number): Promise<any>;
/**
* @param debugFlag
*/
capturePullEvent(debugFlag?: boolean): void;
/**
* @param loggingFlag
*/
enableLogging(loggingFlag?: boolean): void;
/**
* Returns list channels that the connection is subscribed to.
*
* @returns {Promise}
*/
listChannels(): Promise<any>;
/**
* Returns "last seen" time in seconds for the users.
* Result format: Object{userId: int}
* If the user is currently connected - will return 0.
* If the user is offline - will return the diff between the current timestamp and the last seen timestamp in seconds.
* If the user was never online - the record for the user will be missing from the result object.
*
* @param {integer[]} userList List of user ids.
* @returns {Promise}
*/
getUsersLastSeen(userList: number[]): Promise<Record<number, number>>;
/**
* Pings server.
* In case of success promise will be resolved, otherwise - rejected.
*
* @param {number} timeout Request timeout in seconds
* @returns {Promise}
*/
ping(timeout?: number): Promise<void>;
/**
* @param userId {number}
* @param callback {UserStatusCallback}
* @returns {Promise}
*/
subscribeUserStatusChange(userId: number, callback: UserStatusCallback): Promise<void>;
/**
* @param {number} userId
* @param {UserStatusCallback} callback
* @returns {Promise}
*/
unsubscribeUserStatusChange(userId: number, callback: UserStatusCallback): Promise<void>;
getRevision(): number | null;
getServerVersion(): number;
getServerMode(): string | null;
getConfig(): null | TypePullClientConfig;
getDebugInfo(): any;
/**
* @process
* @param connectionType
*/
getConnectionPath(connectionType: ConnectionType): string;
/**
* @process
*/
getPublicationPath(): string;
isConnected(): boolean;
isWebSocketSupported(): boolean;
isWebSocketAllowed(): boolean;
isWebSocketEnabled(): boolean;
isPublishingSupported(): boolean;
isPublishingEnabled(): boolean;
isProtobufSupported(): boolean;
isJsonRpc(): boolean;
isSharedMode(): boolean;
/**
* @param {TypePullClientEmitConfig} params
* @returns {boolean}
*/
private emit;
/**
* @process
*
* @param message
*/
private broadcastMessage;
/**
* @process
*
* @param messages
*/
private broadcastMessages;
/**
* Sends batch of messages to the multiple public channels.
*
* @param messageBatchList Array of messages to send.
* @return void
*/
private sendMessageBatch;
/**
* @param messageBatchList
* @param publicIds
*/
private encodeMessageBatch;
/**
* @memo fix return type
* @param users
* @param publicIds
*/
private createMessageReceivers;
/**
* @param userId
* @param isOnline
*/
private emitUserStatusChange;
private restoreUserStatusSubscription;
private loadConfig;
/**
* @param config
*/
private isConfigActual;
private startCheckConfig;
private stopCheckConfig;
private checkConfig;
/**
* @param config
* @param allowCaching
*/
private setConfig;
private setPublicIds;
/**
* @param serverRevision
*/
private checkRevision;
private disconnect;
private restoreWebSocketConnection;
/**
* @param connectionDelay
*/
private scheduleReconnect;
private scheduleRestoreWebSocketConnection;
/**
* @returns {Promise}
*/
private connect;
/**
* @param disconnectCode
* @param disconnectReason
* @param restartDelay
*/
private scheduleRestart;
/**
* @param messageFields
*/
private handleRpcIncomingMessage;
/**
* @param events
*/
private handleIncomingEvents;
/**
* @param event
*/
private updateSessionFromEvent;
/**
* @process
*
* @param command
* @param message
*/
private handleInternalPullEvent;
/**
* @param response
*/
private onIncomingMessage;
private onLongPollingOpen;
/**
* @param response
*/
private onLongPollingDisconnect;
/**
* @param error
*/
private onLongPollingError;
/**
* @param response
*/
private onWebSocketBlockChanged;
private onWebSocketOpen;
/**
* @param response
*/
private onWebSocketDisconnect;
/**
* @param error
*/
private onWebSocketError;
/**
* @param pullEvent
*/
private extractMessages;
/**
* @param pullEvent
*/
private extractProtobufMessages;
/**
* @param pullEvent
*/
private extractPlainTextMessages;
/**
* Converts message id from byte[] to string
* @param {Uint8Array} encodedId
* @return {string}
*/
private decodeId;
/**
* Converts message id from hex-encoded string to byte[]
* @param {string} id Hex-encoded string.
* @return {Uint8Array}
*/
private encodeId;
private onOffline;
private onOnline;
private onBeforeUnload;
private persistSession;
/**
* @param status
* @param delay
*/
private sendPullStatusDelayed;
/**
* @param status
*/
private sendPullStatus;
/**
* @memo if private?
* @param tagId
* @param force
*/
private extendWatch;
/**
* @param force
*/
private updateWatch;
/**
* @param tagId
*/
private clearWatch;
private onJsonRpcPing;
private updatePingWaitTimeout;
private clearPingWaitTimeout;
private onPingTimeout;
/**
* Returns reconnect delay in seconds
*
* @param attemptNumber
* @return {number}
*/
private getConnectionAttemptDelay;
/**
* @param mid
*/
private checkDuplicate;
private trimDuplicates;
/**
* @param message
*/
private logMessage;
/**
* @param message
* @param force
*/
private logToConsole;
/**
* @param message
*/
private addMessageToStat;
/**
* @param text
*/
private showNotification;
/**
* @memo may be need to use onCustomEvent
* @memo ? force
*/
private onCustomEvent;
}
declare function initializeB24Frame(options?: {
version?: ApiVersion;
restrictionParams?: Partial<RestrictionParams>;
}): Promise<B24Frame>;
export { AbstractB24, AbstractLogger, AdaptiveDelayer, AjaxError, AjaxResult, ApiVersion, AppFrame, AuthHookManager, AuthManager, AuthOAuthManager, B24Frame, B24HelperManager, B24Hook, B24LangList, B24LocaleMap, B24OAuth, PullClient as B24PullClientManager, BatchRefV3, Browser, CatalogProductImageType, CatalogProductType, CatalogRoundingRuleType, CloseReasons, ConnectionType, ConsolaAdapter, ConsoleHandler, ConsoleV2Handler, DataType, DialogManager, EnumAppStatus, EnumBitrix24Edition, EnumBizprocBaseType, EnumBizprocDocumentType, EnumCrmEntityType, EnumCrmEntityTypeId, EnumCrmEntityTypeShort, Environment, FilterV3, HttpV2, HttpV3, JsonFormatter, LineFormatter, ListRpcError, LoadDataType, LogLevel, Logger, LoggerBrowser, LoggerFactory, LoggerType, LsKeys, MemoryHandler, MessageCommands, MessageManager, NullLogger, OperatingLimiter, OptionsManager$1 as OptionsManager, ParamsFactory, ParentManager, PlacementManager, ProductRowDiscountTypeId, PullStatus, RateLimiter, RefreshTokenError, RestrictionManager, Result, RpcMethod, SdkError, SenderType, ServerMode, SliderManager, StatusDescriptions, StreamHandler, SubscriptionType, SystemCommands, TelegramFormatter, TelegramHandler, Text$1 as Text, Type, TypeOption, TypeSpecificUrl, WinstonAdapter, convertBizprocDocumentTypeToCrmEntityTypeId, getDocumentId, getDocumentType, getDocumentTypeForFilter, getEnumCrmEntityTypeShort, getEnumValue, getEnvironment, initializeB24Frame, isArrayOfArray, memoryUsageProcessor, omit, pick, pidProcessor, useB24Helper, useFormatter, versionManager };
export type { ActivityConfig, ActivityHandlerParams, ActivityOrRobotConfig, ActivityProperty, ActivityPropertyType, AdaptiveConfig, AjaxErrorParams, AjaxQuery, AnswerError, AuthActions, AuthData, B24FrameQueryParams, B24HookParams, B24OAuthParams, B24OAuthSecret, BatchCommandV3, BatchCommandsArrayUniversal, BatchCommandsObjectUniversal, BatchCommandsUniversal, BatchNamedCommandsUniversal, BatchPayload, BatchPayloadResult, BatchRef, BatchRefArray, BatchRequestEnvelopeV2, BoolString, CallBatchResult, CallbackRefreshAuth, CatalogCatalog, CatalogExtra, CatalogLanguage, CatalogMeasure, CatalogPriceType, CatalogPriceTypeLang, CatalogProduct, CatalogProductImage, CatalogProductOffer, CatalogProductService, CatalogProductSku, CatalogRatio, CatalogRoundingRule, CatalogSection, CatalogStore, CatalogVat, CommandHandlerFunctionV1, CommandHandlerFunctionV2, CommandObject, CommandTuple, CommandUniversal, ConnectorCallbacks, ConnectorConfig, ConnectorParent, ConsolaAdapterOptions, ConsoleHandlerOptions, CrmItemDelivery, CrmItemPayment, CrmItemProductRow, Currency, CurrencyFormat, CustomRefreshAuth, EventHandlerParams, EventOnAppInstallHandlerParams, EventOnAppUnInstallHandlerParams, Fields, FilterV3Condition, FilterV3Group, FilterV3Node, FilterV3Operator, Formatter, GenderString, GetPayload, Handler, HandlerAuthParams, HandlerOptions, HandlerRefreshAuth, IB24BatchOptions, ICallBatchOptions, ICallBatchResult, ILimiter, IPlacementUF, IRequestIdGenerator, IResult, ISODate, JsonRpcRequest, ListPayload, LogLevelName, LogRecord, LoggerInterface, MemoryHandlerOptions, MessageInitData, MultiField, MultiFieldArray, NumberString, OperatingLimitConfig, Payload, PayloadOAuthToken, PayloadTime, PlacementViewMode, Processor, RateLimitConfig, RefreshAuthData, RestrictionManagerStats, RestrictionParams, RpcCommand, RpcCommandResult, RpcError, RpcRequest, SdkErrorDetails, SelectCRMParams, SelectCRMParamsEntityType, SelectCRMParamsValue, SelectedAccess, SelectedCRM, SelectedCRMEntity, SelectedUser, SendParams, SharedConfigCallbacks, SharedConfigParams, StatusClose, StorageManagerParams, StreamHandlerOptions, SuccessPayload, TelegramHandlerOptions, TextType, TypeApp, TypeB24, TypeB24Form, TypeCallParams, TypeCallParamsV2, TypeCallParamsV3, TypeChanel, TypeChannelManagerParams, TypeConnector, TypeDescriptionError, TypeDescriptionErrorV3, TypeEnumAppStatus, TypeFilterV2, TypeFilterV3, TypeHttp, TypeJsonRpcConfig, TypeLicense, TypePayment, TypePublicIdDescriptor, TypePullClientConfig, TypePullClientEmitConfig, TypePullClientMessageBatch, TypePullClientMessageBody, TypePullClientParams, TypePullClientSession, TypePullMessage, TypeRpcResponseAwaiters, TypeSessionEvent, TypeStorageManager, TypeSubscriptionCommandHandler, TypeSubscriptionOptions, TypeUser, UserBasic, UserBrief, UserFieldType, UserStatusCallback, ValidationDetail, WinstonAdapterOptions };