Для AI-агентов: markdown этой страницы — /docs-content/applications/list.md индекс документации — /llms.txt
Список приложений
GET /v1/applications
Возвращает приложения портала, которые видит владелец ключа, — свои, открытые коллегами или всё вместе. Выборка постраничная, набор полей строки совпадает с карточкой приложения.
Параметры
| Параметр | Тип | Обяз. | По умолч. | Описание |
|---|---|---|---|---|
scope (query) |
string | нет | feed |
Какие приложения вернуть: mine — свои, shared — доступные вам чужие, feed — общий список из первых двух. Значения регистрозависимы, а пустое scope= отвечает 400 INVALID_SCOPE наравне с неизвестным: параметр либо опускают, либо задают одним из трёх значений |
page (query) |
number | нет | 1 |
Номер страницы, считая с единицы. Значение меньше единицы и нечисловое читаются как 1 |
limit (query) |
number | нет | 50 |
Сколько приложений на странице, максимум 100. Большее значение приводится к 100, 0 и нечисловое — к 50, отрицательное — к 1 |
Постраничный обход строится по total, page и limit из ответа: страницы запрашиваются подряд, пока сумма полученных строк не догонит total. Страница за пределами выдачи отвечает 200 с пустым массивом data, а не ошибкой.
Считать число страниц как total / limit можно только при truncated: false. При true total перестаёт быть полным числом, страниц за ним нет, и за остатком идут в mine и shared — у них предела нет.
Примеры
curl — личный ключ
curl -H "X-Api-Key: YOUR_API_KEY" \
"https://vibecode.bitrix24.tech/v1/applications?scope=mine&limit=20"
curl — OAuth-приложение
curl -H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
"https://vibecode.bitrix24.tech/v1/applications?scope=mine&limit=20"
JavaScript — личный ключ
const res = await fetch('https://vibecode.bitrix24.tech/v1/applications?scope=mine&limit=20', {
headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})
const { data: applications, total } = await res.json()
applications.forEach(app => {
const state = app.activeOperation
? `${app.activeOperation.kind} — ${app.activeOperation.status}`
: app.server?.status ?? 'сервера нет'
console.log(`${app.name}: ${state}`)
})
console.log(`Показано ${applications.length} из ${total}`)
JavaScript — OAuth-приложение
const res = await fetch('https://vibecode.bitrix24.tech/v1/applications?scope=mine&limit=20', {
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
})
const { data: applications, total } = await res.json()
Поля ответа
| Поле | Тип | Описание |
|---|---|---|
success |
boolean | Всегда true при успехе |
data |
array | Массив приложений. Элемент массива и data одной карточки — одна и та же форма, её поля разобраны в Карточке приложения |
total |
number | Сколько приложений попало под запрошенный scope. У feed это размер выборки, а не число приложений портала — прежде чем считать по нему страницы, читайте truncated |
page |
number | Номер выданной страницы, уже приведённый к допустимому значению |
limit |
number | Размер страницы, уже приведённый к допустимому значению |
truncated |
boolean | Урезана ли выдача. Приходит всегда, в любом scope. false — total точное число. true — total это размер выборки, а не «сколько есть», и страниц за ним нет |
Пример ответа
{
"success": true,
"data": [
{
"id": "cmsw806qp0001tdskzf6mitka",
"name": "Черновик без сервера",
"description": null,
"type": "PERSONAL",
"iconUrl": null,
"createdAt": "2026-08-16T19:51:18.817Z",
"updatedAt": "2026-08-16T19:51:18.817Z",
"viewerState": "owner",
"pinned": false,
"author": { "name": "Автор приложений" },
"isEmbedded": true,
"openUrl": null,
"openTarget": null,
"server": null,
"sources": { "hasVersions": false, "latestVersionId": null, "latestSavedAt": null },
"activeOperation": null
},
{
"id": "cmsw806qi0000tdskiw2aegii",
"name": "Отчёт по сделкам",
"description": "Сводка по воронке за период",
"type": "PERSONAL",
"iconUrl": null,
"createdAt": "2026-08-16T19:51:18.810Z",
"updatedAt": "2026-08-16T19:51:18.810Z",
"viewerState": "owner",
"pinned": false,
"author": { "name": "Автор приложений" },
"isEmbedded": false,
"openUrl": "https://app-05b67cf7.vibecode.bitrix24.tech",
"openTarget": "app",
"server": {
"id": "5cbb50f9-f95f-4ddf-ba3b-b771209cb6fb",
"status": "RUNNING",
"url": "https://app-05b67cf7.vibecode.bitrix24.tech",
"kind": "STANDALONE",
"reachable": true,
"lastDeployedAt": "2026-08-16T19:50:41.302Z"
},
"sources": {
"hasVersions": true,
"latestVersionId": "v2",
"latestSavedAt": "2026-08-16T19:41:18.818Z"
},
"activeOperation": {
"kind": "deploy",
"status": "running",
"step": "build",
"startedAt": "2026-08-16T19:50:33.822Z"
}
}
],
"total": 2,
"page": 1,
"limit": 50,
"truncated": false
}
Пример ответа при ошибке
400 — значение scope вне допустимого набора:
{
"success": false,
"error": {
"code": "INVALID_SCOPE",
"message": "scope must be one of: mine, shared, feed"
}
}
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 400 | INVALID_SCOPE |
Значение scope вне набора mine, shared, feed. Сюда же попадают пустое значение и другой регистр |
| 401 | NO_PORTAL |
Ключ не привязан к порталу — фактический ответ на этот случай |
| 403 | MANAGEMENT_KEY_NO_ENTITY_ACCESS |
Управляющий ключ: нужен API-ключ или ключ авторизации |
| 403 | PORTAL_KEY_REQUIRED |
Страховка раздела: повреждённая запись ключа без владельца. Обычный «ключ без портала» — это 401 NO_PORTAL выше |
| 401 | MISSING_API_KEY |
Не передан заголовок X-Api-Key |
| 401 | INVALID_API_KEY |
Неверный или просроченный API-ключ |
| 429 | RATE_LIMITED |
Превышена частота. 60 запросов в минуту — суммарный лимит платформы, доля одной реплики сегодня 20; ориентируйтесь на X-RateLimit-Limit из ответа. Счётчик на владельца ключа. Лимит строже, чем у карточки: список рассчитан на обновление экрана, а не на опрос в цикле. Есть Retry-After — пауза в целых секундах |
| 429 | QUOTA_EXCEEDED |
Исчерпана суточная квота бесплатных вызовов ключа. Тот же статус, другая причина: ожидание не поможет |
Текст error.message всегда английский и предназначен для журналов: тексты для интерфейса стройте по error.code. Полный список общих ошибок API — Ошибки.
Известные особенности
- Выборка идёт по владельцу ключа, а не по самому ключу. В список попадают и приложения, заведённые в личном кабинете: их серверы привязаны к другим ключам того же человека, поэтому в
GET /v1/infra/serversони не видны, а здесь видны. Обратное тоже верно: сменив ключ на новый, вы увидите тот же список приложений. - Порядок строк зависит от
scope, и он полный. Уfeedсверху идут закреплённые приложения, за ними свои, затем открытые вам, и внутри каждой группы новее поupdatedAt. Уmineиsharedпорядок один — поcreatedAt, новые сверху. В обоих случаях при равных метках времени порядок доопределяется поid, и это важно для обхода: у приложений, созданных пакетно, метки совпадают, а без вторичного ключа две страницы одного обхода могли бы пересечься или пропустить приложение. - У
feedвыборка ограничена сверху, и об этом говоритtruncated. Порядок для этого списка считается на стороне сервиса, а не выборкой из базы, поэтому страница нарезается уже после сортировки, аtotalпоказывает размер выборки, а не всего портала. Признак читайте осторожно: он поднимается, когда выборка упёрлась в предел, а отличить «упёрлись» от «ровно столько и было» одним запросом нельзя, поэтому платформа ошибается в сторону признания неполноты. Ложноеtrueвы диагностируете сами — сходите за следующей страницей и получите пустую. Ложноеfalseне диагностируется никак, поэтому его и не допускают. Уmineиsharedпредела нет,total— полное число строк под фильтр,truncatedвсегдаfalse. updatedAt— не свежесть кода. Поле двигает запись в саму карточку: переименование, смена описания, отвязка удалённого сервера. Выкладка его не двигает, поэтому приложение, куда сегодня выкладывались десять раз, поupdatedAtуедет в хвостfeed. Свежесть кода —sources.latestSavedAt.- В
sharedиfeedсводка исходников почти всегда пустая. Оба блока обогащения наполняются только тому, кто приложением управляет, поэтому у чужих строкsourcesприходит пустым, аactiveOperation—null. Форма строки при этом не меняется, и отличить «данные не отдаются» от «версий нет» по самой строке нельзя. Экран, который рисует статус кода для всей выдачи, обязан это учитывать. - Пустой
shared— рабочее состояние, а не отказ. Ответ200с пустымdataиtotal: 0означает, что доступных вам чужих приложений нет. Ошибку в этом случае искать негде. requestableв списке не возвращается — ни в одномscope. В выдачу попадают только приложения, которые ваши, доступны вам через политику сервера, открыты вам лично грантом или не имеют сервера и открыты всему порталу. То есть кнопка «запросить доступ» разделу не нужна — и вести её было бы некуда: операций записи здесь нет. Значениеrequestableсуществует для полноты набора и приходит только там, где карточка отказывает:403 FORBIDDENна прямой запрос чужого закрытого приложения.- У
scopeиviewerStateразные границы. Вsharedпопадают не только приложения, доступ к которым открыли лично вам, но и приложения без сервера, открытые всему порталу, — а такая строка приходит сviewerState: "usable", не"shared". Клиент, который отбирает строки поviewerState === "shared", часть выдачи потеряет.