The types in types/payloads.ts model the JSON envelope Bitrix24 wraps around every REST response. Most application code never touches these directly — the actions.v{2,3}.* helpers unwrap them and hand you SuccessPayload via AjaxResult.getData(). They are documented here because they are re-exported from @bitrix24/b24jssdk and describe the raw wire shape.
{ result, time } for both restApi:v2 and restApi:v3. The differences below are confined to the list and batch envelopes, whose extra pagination fields are v2-only.rest.documentation.openapi answers with the OpenAPI document at the top level — no result, no time — measured on an on-premise build, a cloud portal and a cloud sandbox. AjaxResult.getData() wraps such a body so result is the document itself; time has nothing to fill it with and stays undefined.PayloadTime
The timing block attached to every response envelope. Present on both v2 and v3.
The two operating* counters are optional, and their absence is the normal state on a self-hosted portal rather than an edge case: the portal adds them only when the operating limiter is active, which on-premise reads the rest module option load_limiter_active — default N, and nothing in the product ever sets it. The SDK skips its operating-time bookkeeping in that case and does not invent a 0, which would be indistinguishable from a real "nothing consumed yet".
type PayloadTime = {
readonly start: number
readonly finish: number
readonly duration: number
readonly processing: number
readonly date_start: ISODate
readonly date_finish: ISODate
readonly operating_reset_at?: number // timestamp when part of the method limit is released
readonly operating?: number // execution time counted against the method limit
}
GetPayload
The envelope for a single-item read — the common { result, time } shape.
type GetPayload<P> = {
readonly result: P
readonly time?: PayloadTime
}
time is optional here, and coupled to SuccessPayload below: AjaxResult.getData() returns a SuccessPayload where the IResult contract expects a Payload, so this union member has to stay assignable from it.
ListPayload
The envelope for a v2 list method. total and next are the v2 offset-pagination fields.
type ListPayload<P> = {
readonly result: P[]
readonly total: number
readonly next?: number
readonly time: PayloadTime
}
total and next are v2-only. restApi:v3 uses cursor-based paging and has no direct counterpart for them in the same envelope. In source, ListPayload still carries a @todo ! add api3 marker — the v3 list envelope variant is not yet modelled as a distinct type. You should not need it: actions.v{2,3}.callList / fetchList walk pages internally, so consumers read the aggregated result, not next / total.BatchPayload / BatchPayloadResult
The whole HTTP body of a batch request: results, errors, totals, next-offsets and per-call timing, keyed either by the caller's command keys or positionally.
BatchPayload<C> describes the complete response body, { result: { … }, time } — it is not what AjaxResult.getData().result returns for a batch call. AjaxResult<X> already means "the body is { result: X, time }", so the inner value is described by BatchResponsePayload<T> in core/interaction/batch/abstract-interaction-batch.ts instead. Until v2.2.0 the SDK's own transport conflated the two and had to cast its way out; these types are exported for reference and are no longer used by the batch internals.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
}
BatchPayloadResult describes the v2 batch envelope and carries a @todo ! add api3 marker in source; the v3 batch variant is not yet modelled here. Prefer actions.v{2,3}.batch / batchByChunk, which parse this envelope for you.SuccessPayload
The public shape of a successful response, as returned by AjaxResult.getData(). This is the type most consumers actually see.
type SuccessPayload<P> = {
readonly result: P
readonly time?: PayloadTime
}
result is always here, because a body with no result key is wrapped — the whole body becomes result rather than being dropped. time cannot be filled in the same way, so it is optional: guard before reading a field off it.
SuccessPayload is intentionally the common { result, time } shape — identical for v2 and v3. The v2-only list fields (next, total) are deliberately excluded: they have no restApi:v3 counterpart, and the SDK's callList / fetchList helpers handle pagination internally, so consumers never read them off the envelope.
Payload
The full discriminated envelope a raw response can be — either an error description (v2 or v3) or one of the success envelopes above.
type Payload<P> =
| TypeDescriptionErrorV3 // v3 error envelope
| TypeDescriptionError // v2 error envelope
| GetPayload<P>
| ListPayload<P>
| BatchPayload<P>
Payload carries a @todo ! add api3 tail / add / update and etc marker in source: the v3-specific success variants (tail paging, add/update responses) are still being filled in. The error arms already model both versions — TypeDescriptionError (v2) and TypeDescriptionErrorV3 (v3), both defined in types/auth.ts.Related
IResult/AjaxResult—AjaxResult.getData()returnsSuccessPayload<T>on success.AjaxResult— decodes the rawPayloadenvelope, including the error arms.- Common types —
ISODateand the scalar aliases used inside these envelopes.