v1.3.0

Discovering v3 methods (OpenAPI)

Use rest.documentation.openapi to fetch the portal's own machine-readable list of every available REST API v3 method — the source of truth the SDK relies on instead of a hardcoded allowlist. Especially useful for AI agents and codegen.

Overview

rest.documentation.openapi is a v3 REST method that returns the portal's ownOpenAPI 3.0.0 document — a single machine-readable description of every REST API v3 method that exists on that specific portal, with the request body fields (and example values) and the response envelope for each one.

This is the source of truth for v3 method availability. The SDK deliberately keeps no hardcoded list of v3 methods (an earlier allowlist both lagged the server and blocked valid methods); instead, $b24.actions.v3.* sends any method to the server and lets it decide. When you need to know what's actually there — which methods, which fields — you ask the portal itself with this call.

The document reflects the modules installed on this portal and the scopes your token holds, so two portals can return different method sets. Always treat it as portal-specific, not a global catalogue.

Calling it through the SDK

It's an ordinary v3 call — no special helper:

const response = await $b24.actions.v3.call.make<{ openapi: string }>({
  method: 'rest.documentation.openapi'
})

if (!response.isSuccess) {
  console.error(new Error(`Error: ${response.getErrorMessages().join('; ')}`))
} else {
  const doc = response.getData()?.result
  console.log(`OpenAPI ${doc?.openapi}`) // e.g. "3.0.0"
}

What the document looks like

A standard OpenAPI 3.0.0 object. The parts you care about in practice:

FieldWhat it holds
openapispec version string, e.g. "3.0.0"
info{ title: "Bitrix24 REST V3 API", version }
tagsone entry per modulehumanresources, mail, main, note, rest, tasks, timeman, …
pathsone entry per method, keyed by /method.name (e.g. /tasks.task.list)

Each paths['/method.name'] carries post (and get) operations with a tags array (the owning module), a requestBody JSON Schema describing the accepted parameters — often with an example field listing the real field names — and a responses schema for the { result } envelope.

// Shape (abridged) — the fields you read in practice
type OpenApiDoc = {
  openapi: string // e.g. "3.0.0"
  info: { title: string, version: string } // title: "Bitrix24 REST V3 API"
  tags: Array<{ name: string, description: string }> // one entry per module
  paths: Record<string, {
    // keyed by "/method.name", e.g. "/tasks.task.list"
    post?: {
      tags?: string[] // the owning module
      requestBody?: { content: { 'application/json': { schema: unknown } } }
    }
    get?: { tags?: string[] }
  }>
}

Why this matters for AI agents

The document is the cleanest way for an LLM or a code generator to work against a portal without guessing:

  • Discovery — enumerate exactly which v3 methods exist before generating a call, instead of hallucinating a method name that returns METHODNOTFOUNDEXCEPTION.
  • Correct fields — read the real select / parameter names from each method's requestBody schema (and its example) instead of inventing them.
  • Typing / codegen — feed the schema into a generator to produce typed wrappers, or narrow $b24.actions.v3.call.make<T>() with the right T.
  • Portal-aware — because the answer is per-portal, an agent can adapt to the modules and scopes actually present rather than to a generic assumption.
The document is large (often 100 KB+) and response-only — it does not change between calls within a session. Fetch it once, cache it, and query the cached object. Don't request it on every interaction.

Error Handling

rest.documentation.openapi is a normal v3 call, so it follows the standard AjaxResult contract — always check isSuccess before reading the document:

const response = await $b24.actions.v3.call.make<{ openapi: string }>({
  method: 'rest.documentation.openapi'
})

if (!response.isSuccess) {
  // e.g. the token lacks the scope, or the portal is unreachable
  console.error(new Error(`Error: ${response.getErrorMessages().join('; ')}`))
} else {
  const doc = response.getData()?.result
  console.log(`OpenAPI ${doc?.openapi}`)
}

Examples

List every available method

const response = await $b24.actions.v3.call.make<{
  paths: Record<string, unknown>
}>({ method: 'rest.documentation.openapi' })

const methods = Object.keys(response.getData()?.result?.paths ?? {})
  .map(path => path.replace(/^\//, '')) // "/tasks.task.list" → "tasks.task.list"

console.log(`${methods.length} v3 methods available`)

Methods grouped by module

type OpenApiDoc = {
  paths: Record<string, { post?: { tags?: string[] } }>
}

const doc = (await $b24.actions.v3.call.make<OpenApiDoc>({
  method: 'rest.documentation.openapi'
})).getData()?.result

const byModule = new Map<string, string[]>()
for (const [path, ops] of Object.entries(doc?.paths ?? {})) {
  const moduleName = ops.post?.tags?.[0] ?? 'unknown'
  const list = byModule.get(moduleName) ?? []
  list.push(path.replace(/^\//, ''))
  byModule.set(moduleName, list)
}

console.log([...byModule.keys()]) // ['humanresources', 'mail', 'main', 'note', 'rest', 'tasks', 'timeman', …]

Check whether a specific method exists

const doc = (await $b24.actions.v3.call.make<{ paths: Record<string, unknown> }>({
  method: 'rest.documentation.openapi'
})).getData()?.result

const exists = Boolean(doc?.paths?.['/note.collection.list'])
console.log(`note.collection.list on v3: ${exists}`)

Alternatives and Recommendations