Обнаружение v3-методов (OpenAPI)

Используйте rest.documentation.openapi, чтобы получить собственный машиночитаемый список всех доступных методов REST API v3 портала — источник истины, на который SDK опирается вместо захардкоженного allowlist. Особенно полезно для AI-агентов и кодогенерации.

Обзор

rest.documentation.openapi — это v3 REST-метод, который возвращает собственный OpenAPI 3.0.0-документ портала — единое машиночитаемое описание каждого метода REST API v3, существующего на конкретном портале, с полями тела запроса (и примерами значений) и конвертом ответа для каждого.

Это источник истины по доступности v3-методов. SDK намеренно не держит захардкоженный список v3-методов (прежний allowlist и отставал от сервера, и блокировал валидные методы); вместо этого $b24.actions.v3.* отправляет любой метод на сервер и даёт ему решать. Когда нужно узнать, что там на самом деле — какие методы, какие поля — вы спрашиваете сам портал этим вызовом.

Документ отражает модули, установленные на этом портале, и scope, которыми владеет ваш токен, поэтому два портала могут вернуть разные наборы методов. Всегда считайте его специфичным для портала, а не глобальным каталогом.

Вызов через SDK

Это обычный v3-вызов — без специального хелпера:

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}`) // напр. "3.0.0"
}

Как выглядит документ

Стандартный объект OpenAPI 3.0.0. Части, которые важны на практике:

ПолеЧто содержит
openapiстрока версии спецификации, напр. "3.0.0"
info{ title: "Bitrix24 REST V3 API", version }
tagsодна запись на модульhumanresources, mail, main, note, rest, tasks, timeman, …
pathsодна запись на метод, с ключом /method.name (напр. /tasks.task.list)

Каждый paths['/method.name'] несёт операции postget) с массивом tags (модуль-владелец), JSON-схему requestBody, описывающую принимаемые параметры — часто с полем example, перечисляющим реальные имена полей, — и схему responses для конверта { result }.

// Форма (сокращённо) — поля, которые читаете на практике
type OpenApiDoc = {
  openapi: string // напр. "3.0.0"
  info: { title: string, version: string } // title: "Bitrix24 REST V3 API"
  tags: Array<{ name: string, description: string }> // одна запись на модуль
  paths: Record<string, {
    // с ключом "/method.name", напр. "/tasks.task.list"
    post?: {
      tags?: string[] // модуль-владелец
      requestBody?: { content: { 'application/json': { schema: unknown } } }
    }
    get?: { tags?: string[] }
  }>
}

Почему это важно для AI-агентов

Документ — самый чистый способ для LLM или генератора кода работать с порталом без догадок:

  • Обнаружение — перечислить, какие именно v3-методы существуют, до генерации вызова, вместо галлюцинации имени метода, который вернёт METHODNOTFOUNDEXCEPTION.
  • Правильные поля — читать реальные имена select / параметров из схемы requestBody каждого метода (и её example) вместо их выдумывания.
  • Типизация / кодогенерация — скормить схему генератору, чтобы получить типизированные обёртки, или сузить $b24.actions.v3.call.make<T>() правильным T.
  • Учёт портала — поскольку ответ на каждый портал свой, агент может подстроиться под реально присутствующие модули и scope, а не под общее предположение.
Документ большой (часто 100 КБ+) и только в ответе — он не меняется между вызовами в рамках сессии. Запросите его один раз, закэшируйте и обращайтесь к закэшированному объекту. Не запрашивайте его при каждом взаимодействии.

Обработка ошибок

rest.documentation.openapi — обычный v3-вызов, поэтому следует стандартному контракту AjaxResult — всегда проверяйте isSuccess перед чтением документа:

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

if (!response.isSuccess) {
  // напр. у токена нет scope или портал недоступен
  console.error(new Error(`Error: ${response.getErrorMessages().join('; ')}`))
} else {
  const doc = response.getData()?.result
  console.log(`OpenAPI ${doc?.openapi}`)
}

Примеры

Перечислить все доступные методы

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`)

Методы, сгруппированные по модулю

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', …]

Проверить, существует ли конкретный метод

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}`)

Альтернативы и рекомендации