
# Интеграция 1С

Чтение данных из 1С по REST: приложение запрашивает выборку у портала, а её выполняет модуль Вайбкод, установленный в базе 1С. Обмен асинхронный — вызов ставит операцию, данные забираются отдельным запросом.

**Скоуп:** `vibe:onec` | **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `X-Api-Key`

[Что нужно для работы](#что-нужно-для-работы) | [Как устроен обмен](#как-устроен-обмен) | [Быстрый старт](#быстрый-старт) | [Справочник эндпоинтов](#справочник-эндпоинтов) | [Лимиты](#лимиты) | [Коды ошибок](#коды-ошибок)

## Что нужно для работы

1. **1С подключена к порталу.** Подключение живёт в кабинете, раздел «Интеграция 1С»: там выпускается ключ подключения, который вставляется в настройки модуля Вайбкод в 1С. Пока раздела на портале нет, все три эндпоинта отвечают так же, как неизвестный путь.
2. **Ключ со скоупом `vibe:onec`.** В личном ключе `vibe_api_…` скоуп выбирается при выпуске в кабинете. Ключ авторизации `vibe_app_…` работает с токеном сессии пользователя, и право `vibe:onec` открывает приложению платформенный администратор. Форматы ключей — [Ключи и авторизация](/docs/keys-auth).
3. **Сопоставление с учётной записью 1С.** Чтение данных идёт от имени учётной записи 1С, сопоставленной с пользователем портала. Сопоставления настраиваются в том же разделе кабинета. Вызов без сопоставления отвечает `403 ONEC_USER_NOT_MAPPED`.

## Как устроен обмен

Синхронного запроса к 1С нет: база может быть недостижима в момент вызова, а выборка — длиться минуты. Поэтому каждое чтение проходит три шага.

1. **Каталог.** [`GET /v1/onec/tools`](/docs/onec/tools) отдаёт инструменты, опубликованные 1С, с их методами и схемами параметров. Схема инструмента и есть список допустимых `columns` и `filters`.
2. **Постановка.** [`POST /v1/onec/tools/{method}/call`](/docs/onec/call) принимает выборку и отвечает `202` с `operationId`. Учётную запись 1С платформа выбирает сама по сопоставлению вызывающего.
3. **Чтение результата.** [`GET /v1/onec/operations/{operationId}`](/docs/onec/operation) отдаёт состояние, а при `succeeded` — колонки и строки.

## Быстрый старт

Каталог инструментов портала:

```bash
curl https://vibecode.bitrix24.tech/v1/onec/tools \
  -H "X-Api-Key: YOUR_API_KEY"
```

Постановка чтения по методу из каталога:

```bash
curl -X POST https://vibecode.bitrix24.tech/v1/onec/tools/bank.list/call \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "columns": ["Код", "Наименование"], "limit": 100 }'
```

Ответ несёт идентификатор операции:

```json
{
  "success": true,
  "data": {
    "operationId": "cl9x2k4t70000qz8h3m1vb7ry",
    "status": "pending",
    "expiresAt": "2026-09-14T12:15:00.000Z"
  }
}
```

Результат по этому идентификатору:

```bash
curl https://vibecode.bitrix24.tech/v1/onec/operations/cl9x2k4t70000qz8h3m1vb7ry \
  -H "X-Api-Key: YOUR_API_KEY"
```

## Полный пример

Сценарий целиком: взять инструмент из каталога, прочитать все страницы выборки, разобрать терминальные состояния операции.

```javascript
const BASE = 'https://vibecode.bitrix24.tech/v1'
const headers = { 'X-Api-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' }

async function api(path, init) {
  const res = await fetch(`${BASE}${path}`, { headers, ...init })
  const body = await res.json()
  if (!res.ok) throw new Error(`${res.status} ${body.error.code}`)
  return body.data
}

// 1. Каталог: берём инструмент и его допустимые колонки.
const catalog = await api('/onec/tools')
if (!catalog.loaded) throw new Error('1С ещё не присылала список инструментов')

const tool = catalog.tools.find((t) => t.method === 'bank.list') ?? catalog.tools[0]
const columns = tool.inputSchema.properties.columns.items?.enum ?? null

// 2. Постановка операции на одну страницу выборки.
async function queue(offset) {
  const data = await api(`/onec/tools/${encodeURIComponent(tool.method)}/call`, {
    method: 'POST',
    body: JSON.stringify({ ...(columns ? { columns } : {}), limit: 1000, offset }),
  })
  return data.operationId
}

// 3. Опрос до терминального состояния.
async function waitFor(operationId) {
  let delay = 1000
  for (;;) {
    const data = await api(`/onec/operations/${operationId}`)
    if (data.status === 'succeeded') return data.result
    if (data.status === 'failed') throw new Error(`1С отказала: ${data.error.code}`)
    if (data.status === 'cancelled') throw new Error('Операцию снял портал')
    if (data.status === 'expired') throw new Error('1С не прислала данные до expiresAt')
    await new Promise((resolve) => setTimeout(resolve, delay))
    delay = Math.min(delay * 2, 5000)
  }
}

// 4. Страницы: следующая позиция приходит в nextOffset.
const rows = []
let offset = 0
for (;;) {
  const result = await waitFor(await queue(offset))
  rows.push(...result.rows)
  if (!result.truncated || result.nextOffset === null) break
  offset = result.nextOffset
}

console.log(`${tool.title}: строк ${rows.length}`)
```

## Справочник эндпоинтов

| Метод | Путь | Описание |
|-------|------|----------|
| GET | [`/v1/onec/tools`](/docs/onec/tools) | Инструменты, опубликованные 1С, и состояние версии каталога |
| POST | [`/v1/onec/tools/{method}/call`](/docs/onec/call) | Поставить чтение данных инструментом |
| GET | [`/v1/onec/operations/{operationId}`](/docs/onec/operation) | Состояние операции и её результат |

## Лимиты

| Лимит | Значение |
|-------|----------|
| Строк за операцию | `limit` от 1 до 10 000, по умолчанию 1000 |
| Колонок в запросе | до 200 без повторов |
| Фильтров в запросе | до 50 ключей на объект, вложенность до 6 уровней, до 2000 значений суммарно |
| Длина строки в фильтре | до 1024 символов |
| Длина имени метода | до 100 символов |
| Хранение результата | сутки с момента завершения операции, затем `410 ONEC_OPERATION_GONE` |
| Частота запросов | 120 в минуту на чтение каталога и операций, 60 в минуту на постановку |

Действующее для ключа значение частоты приходит в заголовке ответа `x-ratelimit-limit` — оно ниже суммарного, потому что лимит делится между репликами. Общие правила — [Лимиты и оптимизация](/docs/optimization).

## Коды ошибок

### Ошибки интеграции 1С

| HTTP | Код | Описание |
|------|-----|---------|
| 400 | `ONEC_VALIDATION` | Запрос не соответствует контракту: неизвестное поле в теле, `limit` или `offset` вне диапазона, недопустимые символы в имени метода, превышены ограничения фильтров |
| 403 | `ONEC_USER_NOT_MAPPED` | У вызывающего нет действующего сопоставления с учётной записью 1С |
| 403 | `ONEC_ACCOUNT_UNAVAILABLE` | Выбранная учётная запись 1С или её назначение неактивны |
| 404 | `ONEC_NOT_CONNECTED` | На портале нет активного подключения 1С либо оно отключено |
| 404 | `ONEC_OPERATION_NOT_FOUND` | Операции с таким идентификатором нет, либо она создана другим ключом, пользователем или порталом |
| 409 | `ONEC_SETTINGS_MISSING` | Модуль Вайбкод в 1С ещё не передал свои настройки |
| 409 | `ONEC_CAPABILITY_MISSING` | Модуль не объявил чтение данных среди своих возможностей |
| 409 | `ONEC_MAPPING_CONFLICT` | Назначения по подразделениям выбирают разные учётные записи 1С |
| 409 | `ONEC_MAPPING_VERSION_CONFLICT` | Назначения изменились во время проверки доступа — повторите вызов |
| 410 | `ONEC_OPERATION_GONE` | Результат уже не хранится: с момента завершения прошло больше суток |
| 503 | `ONEC_DIRECTORY_UNAVAILABLE` | Состав подразделений Битрикс24 проверить не удалось. Операция не создана, повторите позже — это не отказ в доступе |
| 503 | `ONEC_ASSIGNMENTS_DISABLED` | Назначения пользователей 1С на портале временно выключены. Операция не создана |

### Системные ошибки

| HTTP | Код | Описание |
|------|-----|---------|
| 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` |
| 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `vibe:onec` |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | Ключ в режиме «только чтение» операции не создаёт |
| 404 | `ROUTE_NOT_FOUND` | Интеграция 1С на портале недоступна — ответ совпадает с ответом на неизвестный путь |
| 429 | `RATE_LIMITED` | Превышен лимит запросов — повторите после времени из заголовка `Retry-After` |
| 503 | `user_self_deletion_pending` | Владелец ключа удаляет свою учётную запись на портале. Заголовок `Retry-After` равен `604800` — столько длится отсрочка удаления |

Полный список общих ошибок API — [Ошибки](/docs/errors).

## Смотрите также

- [Ключи и авторизация](/docs/keys-auth)
- [Лимиты и оптимизация](/docs/optimization)
- [Ошибки](/docs/errors)
