Для AI-агентов: markdown этой страницы — /docs-content/onec/operation.md индекс документации — /llms.txt
Получить результат операции 1С
GET /v1/onec/operations/{operationId}
Отдаёт состояние операции, поставленной этим же ключом, и её результат, когда 1С прислала данные. Пока чтение идёт, ответ несёт только состояние.
Операции других ключей, пользователей и порталов отвечают так же, как неизвестный идентификатор.
Параметры
| Параметр | Тип | Обяз. | Описание |
|---|---|---|---|
operationId (path) |
string | да | Идентификатор из ответа POST /v1/onec/tools/{method}/call — поле data.operationId, а заголовок Location — путь чтения этой операции, идентификатор стоит его последним сегментом |
Примеры
curl — личный ключ
curl https://vibecode.bitrix24.tech/v1/onec/operations/cl9x2k4t70000qz8h3m1vb7ry \
-H "X-Api-Key: YOUR_API_KEY"
curl — OAuth-приложение
curl https://vibecode.bitrix24.tech/v1/onec/operations/cl9x2k4t70000qz8h3m1vb7ry \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN"
JavaScript — личный ключ
const operationId = 'cl9x2k4t70000qz8h3m1vb7ry'
const res = await fetch(`https://vibecode.bitrix24.tech/v1/onec/operations/${operationId}`, {
headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})
const { data } = await res.json()
console.log(data.status, data.result?.rows?.length)
JavaScript — OAuth-приложение
const operationId = 'cl9x2k4t70000qz8h3m1vb7ry'
const res = await fetch(`https://vibecode.bitrix24.tech/v1/onec/operations/${operationId}`, {
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
})
const { data } = await res.json()
Поля ответа
| Поле | Тип | Описание |
|---|---|---|
success |
boolean | Всегда true при успехе |
data.operationId |
string | Идентификатор операции |
data.type |
string | Вид операции. Для чтения данных — getData |
data.status |
string | pending, running, succeeded, failed, cancelled или expired |
data.createdAt |
string | Когда операция создана, ISO 8601 |
data.finishedAt |
string | null | Когда операция завершилась, ISO 8601. null, пока она не в терминальном состоянии |
data.expiresAt |
string | До какого момента операция ждёт выполнения, ISO 8601 |
data.result |
object | Данные из 1С. Приходит только при status: "succeeded" |
data.result.columns |
array | Имена колонок в порядке, в котором их вернула 1С |
data.result.rows |
array | Строки выборки, объект на строку с колонками в ключах |
data.result.truncated |
boolean | Выборка оборвана по limit — за ней есть ещё строки |
data.result.nextOffset |
integer | null | Позиция для следующего вызова при truncated: true, иначе null |
data.result.total |
integer | Всего строк под фильтром. Приходит, когда 1С отдала это число |
data.error |
object | Отказ. Приходит только при status: "failed" |
data.error.code |
string | Код отказа от 1С, например ACCESS_DENIED или UNKNOWN_FILTER |
data.error.message |
string | Текст отказа от 1С |
Пример ответа
Чтение выполнено:
{
"success": true,
"data": {
"operationId": "cl9x2k4t70000qz8h3m1vb7ry",
"type": "getData",
"status": "succeeded",
"createdAt": "2026-09-14T12:00:00.000Z",
"finishedAt": "2026-09-14T12:00:04.000Z",
"expiresAt": "2026-09-14T12:15:00.000Z",
"result": {
"columns": ["Код"],
"rows": [{ "Код": "000012" }],
"truncated": false,
"nextOffset": null
}
}
}
1С ещё не взяла операцию в работу:
{
"success": true,
"data": {
"operationId": "cl9x2k4t70000qz8h3m1vb7ry",
"type": "getData",
"status": "pending",
"createdAt": "2026-09-14T12:00:00.000Z",
"finishedAt": null,
"expiresAt": "2026-09-14T12:15:00.000Z"
}
}
1С отказала в чтении:
{
"success": true,
"data": {
"operationId": "cl9x2k4t70000qz8h3m1vb7ry",
"type": "getData",
"status": "failed",
"createdAt": "2026-09-14T12:00:00.000Z",
"finishedAt": "2026-09-14T12:00:03.000Z",
"expiresAt": "2026-09-14T12:15:00.000Z",
"error": {
"code": "ACCESS_DENIED",
"message": "Нет прав"
}
}
}
Пример ответа при ошибке
404 — идентификатор неизвестен либо операция создана другим ключом, пользователем или порталом:
{
"success": false,
"error": {
"code": "ONEC_OPERATION_NOT_FOUND",
"message": "Operation not found."
}
}
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 404 | ONEC_OPERATION_NOT_FOUND |
Операции с таким идентификатором нет, либо она создана другим ключом, пользователем или порталом |
| 404 | ONEC_OPERATION_NOT_FOUND |
Идентификатор не той формы — от 20 до 40 строчных латинских букв и цифр |
| 404 | ROUTE_NOT_FOUND |
Интеграция 1С на портале недоступна — ответ совпадает с ответом на неизвестный путь |
| 410 | ONEC_OPERATION_GONE |
Результат уже не хранится: с момента завершения прошло больше суток |
| 401 | MISSING_API_KEY |
Не передан заголовок X-Api-Key |
| 429 | RATE_LIMITED |
Превышен лимит запросов — повторите после времени из заголовка Retry-After |
| 503 | user_self_deletion_pending |
Владелец ключа удаляет свою учётную запись на портале. Заголовок Retry-After равен 604800 — столько длится отсрочка удаления |
Полный список общих ошибок API — Ошибки.
Известные особенности
Терминальных состояний четыре, и клиент обязан разобрать все. succeeded несёт result, failed несёт error, а cancelled и expired не несут ни того, ни другого: первое означает, что операцию снял портал — отключение 1С, смена настроек или потеря доступа к учётной записи, второе — что 1С не прислала данные до expiresAt.
Статус expired вычисляется на чтении. Операция, которая осталась незавершённой и перешагнула expiresAt, читается как expired, даже если в этот момент её состояние в очереди ещё не обновилось.
Результат не переживает сутки. Данные, которые нужны дольше, сохраняйте у себя при первом успешном чтении.
Интервал опроса считается от лимита. На чтение операций отведено 120 запросов в минуту, поэтому опрос раз в секунду в одном потоке укладывается в лимит. Действующее для ключа значение приходит в заголовке ответа x-ratelimit-limit — оно ниже суммарного, потому что лимит делится между репликами. Общие правила — Лимиты и оптимизация.
Ответ не кэшируется. Каждый ответ приходит с Cache-Control: no-store, поэтому промежуточные кэши не отдадут устаревшее состояние операции.
Готовый цикл опроса. Ниже — чтение одной операции до терминального состояния с растущей паузой и разбором всех четырёх исходов.
const BASE = 'https://vibecode.bitrix24.tech/v1'
const headers = { 'X-Api-Key': 'YOUR_API_KEY' }
async function waitForOperation(operationId, { firstDelayMs = 1000, maxDelayMs = 5000 } = {}) {
let delay = firstDelayMs
for (;;) {
const res = await fetch(`${BASE}/onec/operations/${operationId}`, { headers })
if (res.status === 410) {
throw new Error('Результат операции больше не хранится')
}
if (res.status === 429) {
const retryAfter = Number(res.headers.get('Retry-After') ?? 5)
await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000))
continue
}
if (!res.ok) {
const { error } = await res.json()
throw new Error(`${res.status} ${error.code}`)
}
const { data } = await res.json()
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, maxDelayMs)
}
}
const result = await waitForOperation('cl9x2k4t70000qz8h3m1vb7ry')
console.log(result.columns, result.rows.length, result.nextOffset)