v2.2.0

Http (TypeHttp)

Low-level transport interface returned by b24.getHttpClient(version). Direct access to the axios-based clients, restriction params, statistics, and reset.
You normally use actions.v2.* / actions.v3.* and never touch TypeHttp directly. Reach for it when you need raw call / batch, custom limiter tuning, or runtime stats.

TypeHttp is the contract implemented by HttpV2 and HttpV3. Each B24Frame / B24Hook / B24OAuth owns one instance per REST API version. Reach them through:

import { ApiVersion } from '@bitrix24/b24jssdk'

const v2 = $b24.getHttpClient(ApiVersion.v2)
const v3 = $b24.getHttpClient(ApiVersion.v3)

Properties

PropertyTypeDescription
apiVersionApiVersionApiVersion.v2 or ApiVersion.v3.
ajaxClientAxiosInstanceUnderlying axios instance. Reuse it for non-REST calls to the same origin.

Logger

setLogger(logger: LoggerInterface): void
getLogger(): LoggerInterface

Lets you swap a debug logger into a single client without affecting the rest of the SDK. See Logger.

Calling REST

call

call<T = unknown>(
  method: string,
  params: TypeCallParams,
  requestId?: string
): Promise<AjaxResult<T>>

Low-level single-method call. Higher-level helpers (actions.v2.call.make, callList, fetchList) build on top.

batch

batch<T = unknown>(
  calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal | BatchNamedCommandsUniversal,
  options?: ICallBatchOptions
): Promise<Result<ICallBatchResult<T>>>

Low-level batch call. Three input shapes are accepted:

  • Array of tuples: [ [method, params], [method, params] ]
  • Array of objects: [ { method, params, as?, parallel? }, ... ]
  • Named map: { key1: { method, params }, key2: [method, params] }

params is the only key read for a command's arguments — writing them under query, the portal's own wire name, loses them silently. See the warning on the BatchV3 and BatchV2 pages — the two transports lose them by different routes.

For most use cases call actions.v2.batch.make / actions.v3.batch.make, which handle the response unwrapping and returnAjaxResult.

BatchRequestEnvelopeV2 is exported alongside these types but is not something you construct. It names what the restApi:v2 transport puts on the wire for a batch — { halt, cmd } — which reaches call through a parameter typed TypeCallParams and type-checks only because of that type's permissive index signature. It is documented here so an exported symbol is not a mystery, not because a caller needs it. restApi:v3 has no envelope: the commands are the request body, a bare top-level JSON array. That leaves nowhere in the body for a credential — the portal reads every top-level entry as a command — so a webhook keeps its secret in the URL and a server-side B24OAuth sends the token in an Authorization: Bearer header. A browser cannot send that header (the portal's CORS preflight does not allow it), which is why a v3 batch does not work from B24Frame; see BatchV3 Limitations.

Configuring the axios instance

ajaxClient is the live axios instance the transport uses. There are two ways in. httpOptions at construction is merged over the SDK's own defaults, which is where adapter belongs; anything else you can change after the client exists, through defaults:

import { B24Hook } from '@bitrix24/b24jssdk'

const b24 = B24Hook.fromWebhookUrl(
  'https://your-portal.bitrix24.com/rest/1/SECRET',
  { httpOptions: { adapter: 'xhr' } }
)

A frame app passes the same option to initializeB24Frame(), which forwards it to the B24Frame constructor unchanged — and a browser is where adapter earns its keep, since that is the runtime whose adapter changed. The first call wins: a later initializeB24Frame() returns the frame already built and ignores its options.

import { initializeB24Frame } from '@bitrix24/b24jssdk'

const $b24 = await initializeB24Frame({ httpOptions: { adapter: 'xhr' } })

httpOptions is a deliberately narrow slice of AxiosRequestConfigTypeHttpOptions: adapter, timeout, timeoutErrorMessage, proxy, httpAgent, httpsAgent, maxRedirects, maxContentLength, maxBodyLength, decompress, withCredentials. baseURL, transformRequest, paramsSerializer and validateStatus are how the SDK talks to the portal, and overriding them breaks it quietly — a transformRequest here replaces the request body wholesale, with no error on either side and a portal-side failure only — so they are not offered, and a key outside the list is dropped at construction, with the dropped names logged (never their values). The type alone would not do it: excess-property checking does not fire on a variable, and plain JavaScript has no compiler at all. They remain reachable through defaults below, where it reads as the deliberate act it is.

The list keeps out what breaks the SDK by accident — it is not a security boundary.adapter replaces the transport wholesale, which is strictly more than the excluded transformRequest could do, and proxy / httpAgent route token-bearing traffic wherever you point them. Both are on the list, because adapter is the reason it exists. The filter also reaches the two REST transports only: the OAuth token-refresh client builds its own axios instance, so adapter, timeout and proxy do not apply to the request that posts client_secret to the OAuth server. :: headers is the one exception, and not an offered one: TypeHttpOptions does not accept it, so httpOptions: { headers: … } is a compile error. The merge itself survives for the path that predates the type — a direct new HttpV2(...), or a call from untyped JavaScript — as it has since #144.
import { ApiVersion } from '@bitrix24/b24jssdk'

const http = $b24.getHttpClient(ApiVersion.v3)

http.ajaxClient.defaults.timeout = 120_000
http.ajaxClient.defaults.proxy = { host: '10.0.0.1', port: 3128 }
Four things the SDK sets and you should know before overriding them:
  • timeout: 30_000 and a matching timeoutErrorMessage. Raise it for a long-running report method rather than raising the retry count. The message is read by the XHR and Node adapters only; on fetch axios composes its own (timeout of 30000ms exceeded, code ETIMEDOUT rather than ECONNABORTED). The SDK classifies both as a timeout either way.
  • User-Agent, on server-side runtimes only — a browser and a worker forbid the header, so it is not set in either.
  • Content-Type: application/json, per request rather than on the instance. The portal reads a filter boolean only from a JSON body, and axios was supplying that content type by default rather than by intent — see Filtering. Because it is set per request, ajaxClient.defaults.headers no longer reaches SDK traffic; your own requests through this instance are unaffected, including a FormData body, whose multipart boundary axios still computes. A request interceptor you install on this instance still outranks it — that runs after the config is assembled — so an interceptor that sets Content-Type changes the encoding of SDK traffic too, and with it the boolean-filter behaviour above.
  • adapter: 'fetch', in a browser or a worker only. Left alone, axios walks ['xhr', 'http', 'fetch'] and takes the first supported entry, which is XHR wherever XMLHttpRequest exists. Outside a browser nothing is asked for.
Two things follow from the adapter, if you touch this instance yourself. A test suite running under jsdom counts as a browser here, so a double that stubs XMLHttpRequest stops intercepting SDK traffic — pass httpOptions: { adapter: 'xhr' } in that suite. And axios gates onUploadProgress on request streaming, which only Chromium over HTTP/2 supports: your own uploads through ajaxClient get no progress events in Firefox or Safari, where XHR always delivered them. Same opt-out.
maxRedirects is forced to 0 on one request, and only one. A restApi:v3 batch on a non-hook transport outside a browser carries the access token in an Authorization: Bearer header, and a redirect would take it along: follow-redirects strips the header when the host changes, but keeps it for the same host and for a subdomain. A credential in the body was safe here by accident — a 301/302 turns POST into GET and drops the body, so the token that used to sit in auth never travelled.By default the constraint is per-request, not on the instance: nothing else the SDK sends is affected, and a redirect elsewhere in your traffic still works. A portal that does redirect this one request gets a legible 301 instead of a silent hop with a bearer token attached.In a browser the sibling branch behaves differently, and since the fetch adapter arrived it is no longer inert. There the token rides in the query string rather than a header, maxRedirects: 0 is set for the same reason, and fetch reads it as redirect: 'manual' where XHR ignored it outright. What comes back is an opaque response — status: 0, empty body, no headers — and axios resolves that: settle returns early on any falsy status, before validateStatus is consulted, and the fetch adapter has no status-0 guard of its own (XHR did). Left at that, the refused request would answer as a silently empty success, so the SDK raises JSSDK_HTTP_REDIRECT_BLOCKED itself — only on the request that asked for maxRedirects: 0, so an ordinary status-0 network failure is unaffected. Same narrow scope: a restApi:v3 batch on a non-hook transport.If you know your redirect target and want the hop anyway, a transport subclass can return maxRedirects from _prepareRequestConfig and it wins — the value is a default, applied before the per-request config is spread over it, not a lock. Setting ajaxClient.defaults.maxRedirects does not reach it: a per-request config outranks the instance default in axios.

Limiter Configuration

setRestrictionManagerParams(params: RestrictionParams): Promise<void>
getRestrictionManagerParams(): RestrictionParams

Update or read the restriction policy on this client. The setter replaces the parameters you name and leaves the rest alone, with the nested limiter blocks replaced whole — see Updating the parameters. The getter returns a copy. To change both v2 and v3 at once, use b24.setRestrictionManagerParams(...).

See Limiters for the params shape and presets (ParamsFactory.getDefault(), getBatchProcessing(), getRealtime(), fromTariffPlan()).

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 }[]
}

Snapshot of the limiter + per-method counters. Useful for dashboards. See Limiters → Monitoring for the full breakdown.

Reset

reset(): Promise<void>

Clears the limiter state and statistics. Typical use: after a destructive incident response or in long-running daemons that want a clean window.

Client-Side Warning

setClientSideWarning(value: boolean, message: string): void

B24Hook and B24OAuth enable a runtime warning when used in a browser-like runtime — the main thread or any worker (their secrets must never reach the client, and a worker's bundle is as public as the page's). Toggle it from the parent class via b24.offClientSideWarning(); this method is the underlying primitive.