
## Обновить приложение

`PATCH /v1/apps/:id`

Изменяет свойства приложения. Передавайте только те поля, которые нужно изменить.

## Параметры

| Параметр | Тип | Обяз. | Описание |
|----------|-----|:-----:|---------|
| `id` (path) | string | да | Идентификатор приложения из [создания](/docs/apps/create) или [списка](/docs/apps/list) |

## Поля запроса (body)

| Поле | Тип | Описание |
|------|-----|---------|
| `title` | string | Название, от 1 до 255 символов. У приложения в каталоге предел — 100 символов |
| `description` | string \| null | Описание, до 2000 символов |
| `appUrl` | string | Адрес приложения, только `http://` или `https://`. Пустая строка сохраняется как `null` |
| `scopes` | array | Набор скоупов приложения, минимум один. Изменение платформенных скоупов `vibe:*` переносится в активные ключи приложения — см. «Известные особенности» |
| `redirectUris` | array | Адреса перенаправления для OAuth |
| `placements` | array | Места встраивания. Список кодов — [Доступные места](/docs/apps/placements/available). Привязать или снять место по одному, не публикуя приложение заново, — [Места встраивания](/docs/apps/placements) |
| `placementResizeEnabled` | boolean | Подстраивать высоту iframe встройки под контент приложения. Значение по умолчанию — `false`. Перед включением разрешите источник платформы в своей директиве `frame-ancestors` — условие описано в разделе [Приложение в Битрикс24](/docs/infra/app-runtime) |

`handlerUrl` менять нельзя — поле в теле приводит к `400 HANDLER_URL_READONLY`.

## Примеры

### curl — личный ключ

```bash
curl -X PATCH https://vibecode.bitrix24.tech/v1/apps/APP_ID \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "appUrl": "https://app-abc12345.vibecode.bitrix24.tech/dashboard" }'
```

### curl — OAuth-приложение

```bash
curl -X PATCH https://vibecode.bitrix24.tech/v1/apps/APP_ID \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "appUrl": "https://app-abc12345.vibecode.bitrix24.tech/dashboard" }'
```

### JavaScript — личный ключ

```javascript
const res = await fetch('https://vibecode.bitrix24.tech/v1/apps/APP_ID', {
  method: 'PATCH',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    appUrl: 'https://app-abc12345.vibecode.bitrix24.tech/dashboard',
  }),
})

const { data } = await res.json()
```

### JavaScript — OAuth-приложение

```javascript
const res = await fetch('https://vibecode.bitrix24.tech/v1/apps/APP_ID', {
  method: 'PATCH',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    appUrl: 'https://app-abc12345.vibecode.bitrix24.tech/dashboard',
  }),
})

const { data } = await res.json()
```

## Поля ответа

| Поле | Тип | Описание |
|------|-----|---------|
| `data` | object | Приложение после обновления. Набор полей совпадает с ответом [создания](/docs/apps/create), без `rawKey` |
| `data.updatedAt` | string | Дата изменения, ISO 8601 |
| `warnings` | array | Появляется при частичной синхронизации мест встраивания — это коды, которые не удалось привязать, а также места, которые не удалось снять. Про снятие строка приходит по-разному в зависимости от раскатки — разбор во врезке под таблицей ошибок. Отдельная строка приходит, когда новое название потеряло не-ASCII символы по дороге: она называет поле, а само переименование выполняется. Набор строк открытый — незнакомую строку показывайте как есть, а не отбрасывайте |

## Пример ответа

```json
{
  "success": true,
  "data": {
    "id": "33c4d5e6-f7a8-49b0-1234-5c6d7e8f9012",
    "title": "Дашборд продаж",
    "description": "Обновлено",
    "scopes": ["crm", "user", "placement"],
    "handlerUrl": "https://vibecode.bitrix24.tech/v1/bitrix-handler",
    "appUrl": "https://app-abc12345.vibecode.bitrix24.tech/dashboard",
    "redirectUris": [
      "https://vibecode.bitrix24.tech/oauth/complete",
      "http://localhost"
    ],
    "bitrixClientId": "local.7c3d4e5f6a7b80.55556666",
    "prefix": "vibe_app_local_7c3",
    "suffix": "6666",
    "authorId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "portalId": "8b1f0e2a-3c4d-5e6f-7a8b-9c0d1e2f3a4b",
    "createdAt": "2026-06-24T09:12:45.781Z",
    "updatedAt": "2026-06-24T09:13:36.974Z",
    "placements": []
  }
}
```

## Пример ответа при ошибке

404 — приложение не найдено:

```json
{
  "success": false,
  "error": {
    "code": "APP_NOT_FOUND",
    "message": "Application not found"
  }
}
```

## Ошибки

| HTTP | Код | Описание |
|------|-----|---------|
| 400 | `HANDLER_URL_READONLY` | В теле передан `handlerUrl` — поле задаёт платформа и менять его нельзя |
| 400 | `NO_USER_TOKEN` | Смена `placements` или переименование опубликованного приложения без токена пользователя на облачном портале |
| 400 | `TITLE_TOO_LONG_FOR_CATALOG` | Новое название длиннее 100 символов у приложения, добавленного в каталог |
| 403 | `UNAUTHORIZED` | Ключ не принадлежит автору или владельцу приложения |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | Запрос меняет `scopes`, а идёт ключом в режиме «только чтение». Остальные поля такой ключ менять может. Подробнее — [Режим доступа](/docs/keys-auth/access-mode) |
| 403 | `SCOPE_GRANT_REQUIRES_CONSENT` | Запрос идёт ключом с зафиксированным набором прав и добавляет в `scopes` платформенный скоуп `vibe:*`, которого у самого вызывающего ключа нет. Список таких скоупов приходит в `error.details.unconsented`. Снятие скоупов проходит всегда, добавление — только в пределах прав вызывающего ключа. Набор зафиксирован у [партнёрского](/docs/partner-connect) ключа, проектного ключа [Cowork](/docs/cowork), личного ключа из формы кабинета и ключа, выписанного с `exactScopes: true` — [Менеджмент-ключи](/docs/management-keys). Как отличить такой ключ — [Создать приложение](/docs/apps/create) |
| 404 | `APP_NOT_FOUND` | Приложения с указанным `id` нет |
| 502 | `BITRIX_PARTIAL_REBIND` | Битрикс24 отклонил перепривязку места встраивания при переименовании. Новое название не записано — повторите запрос |
| 502 | `PLACEMENT_UNBIND_FAILED` | Аккаунт не подтвердил снятие мест встраивания, убранных из `placements`. Остальные поля запроса и перепривязка названия не применяются, коды перечислены в `error.placements`. Поле `placements` при этом уже перезаписано и отражает фактическое состояние аккаунта — перечитайте приложение. Приходит только после включения проверки — см. врезку ниже |
| 503 | `NETWORK_DEVKEY_REQUIRED` | Аккаунт переведён на транспорт ключа разработчика, а у автора приложения такого ключа нет. Повтор не поможет — попросите автора переподключить аккаунт. Приходит только после включения проверки — см. врезку ниже |

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

**Проверка снятия мест встраивания на стороне аккаунта сейчас раскатывается по аккаунтам, поэтому вариантов два:**

- **Пока возможность не включена на аккаунте** — `PATCH` с уменьшенным набором `placements` отвечает `200`, даже если снять лишние места на аккаунте не удалось. Неснятый код при этом ОСТАЁТСЯ в `placements` приложения, а причина приходит строкой `Failed to unbind <код>` в `warnings`. Это единственный признак расхождения списка с аккаунтом, поэтому на сегодняшнем проде `warnings` надо разбирать. Кодов `PLACEMENT_UNBIND_FAILED` и `NETWORK_DEVKEY_REQUIRED` у этого эндпоинта не бывает.
- **После включения** — неподтверждённое снятие отвечает `502 PLACEMENT_UNBIND_FAILED`, и остальная часть запроса не применяется: ни перепривязка названия, ни прочие поля. Повторите запрос — перечисленные в `error.placements` места на аккаунте остались. Ответ `502` здесь не означает «ничего не изменилось»: список `placements` уже перезаписан снятым набором, поэтому перечитайте приложение через [данные приложения](/docs/apps/get), а не полагайтесь на список, который был у вас до вызова. Ответа `200` с неснятым местом на этом пути не бывает — про снятие в `warnings` успешного ответа остаются пояснения о подтверждении. Остальные строки набора включение не меняет — отказы привязки и прочие поводы из таблицы `warnings` выше приходят и на этом пути.

## Известные особенности

- **Переименование приложения в каталоге меняет и подписи на портале.** Новое `title` уходит в карточку каталога (поле `catalogTitle` пишется вместе с `title`) и в места встраивания — пункт левого меню и вкладки CRM. Поэтому переименование обращается к Битрикс24 и может вернуть `400 NO_USER_TOKEN` или `502 BITRIX_PARTIAL_REBIND`. При отказе название не записывается, повтор запроса чинит состояние. Портал кэширует левое меню — новое имя видно после перезагрузки страницы с очисткой кэша. У приложения вне каталога переименование меняет только `title`.
- **Смена `scopes` переносит платформенные скоупы `vibe:*` в ключи приложения.** Обновление сравнивает старый и новый набор и применяет разницу по `vibe:*` ко всем активным ключам приложения — добавленный `vibe:ai` появляется у ключей, снятый `vibe:infra` у них снимается. Скоупы портала Битрикс24 (`crm`, `user` и прочие) в ключи не переносятся: их набор фиксируется при выпуске ключа и меняется только перевыпуском.
- **Ключ с зафиксированным набором прав платформенные скоупы через перенос не получает.** Такой набор у парного ключа приложения, созданного [партнёрским](/docs/partner-connect) ключом, проектным ключом [Cowork](/docs/cowork), личным ключом из формы кабинета или ключом с `exactScopes: true` — [Создать приложение](/docs/apps/create). Снятие скоупов доходит до него как до остальных, а добавление — нет: `vibe:infra`, дописанный в `scopes` приложения, у такого ключа не появится, и [`POST /v1/infra/servers`](/docs/infra/servers/create) продолжит отвечать `403 INFRA_SCOPE_REQUIRED`. Нужное право объявляется в `scopes` при создании приложения.
- **Расхождение между скоупами приложения и его ключа чинится двумя запросами.** Бывает, что в `scopes` приложения стоит `vibe:infra`, которого у ключа нет, — ключ отвечает `403` на создание сервера. Снимите `vibe:infra` из `scopes` первым запросом и верните вторым: перенос применяет именно разницу, поэтому вторая правка добавляет скоуп в ключ. На ключ с зафиксированным набором прав это не действует — см. абзац выше. Итоговый набор ключа показывает [`GET /v1/me`](/docs/keys-auth/me) в поле `data.scopes`, вызванный этим ключом.
- **Смена `placements` у опубликованного приложения запускает синхронизацию мест встраивания на портале.** Привязка и отвязка проходят прямо на портале Битрикс24, и часть кодов может не привязаться — тогда ответ несёт `warnings` со списком таких кодов. На облачном портале без токена пользователя синхронизация невозможна, запрос возвращает `400 NO_USER_TOKEN`. У приложения в статусе `PRIVATE` `placements` пишутся в базу без обращения к порталу.
- **Правка `appUrl` доезжает до карточки приложения в каталоге Битрикс24 сама.** Карточка ставится в очередь на обновление этим же запросом, отдельного вызова не нужно. Открывается она по полному адресу приложения вместе с подпутём, параметрами запроса и якорем, когда адрес указывает на тот же поддомен Black Hole, что и сервер карточки. В остальных случаях карточка открывает корень сервера — в том числе при другом поддомене, своём домене, другой схеме, пустом или неразбираемом адресе, имени пользователя перед хостом и адресе длиннее 512 символов, куда засчитываются и параметры запроса. Отдельно от карточки действует ограничение шлюза: на первом заходе за сессию посетитель приземляется в корень поддомена независимо от адреса карточки — [Деплой приложения](/docs/infra/deploy/deploy).
- **Кириллица в `title` из Windows PowerShell.** Отправленная без явной сериализации в UTF-8, она сохраняется знаками вопроса (`?`): байты теряются на стороне клиента, до отправки запроса. Готовый вызов с `UTF8.GetBytes` — [Windows / PowerShell и UTF-8](/docs/apps#windows-powershell-и-utf-8).

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

- [Приложения](/docs/apps)
- [Создать приложение](/docs/apps/create)
- [Данные приложения](/docs/apps/get)
- [Удалить приложение](/docs/apps/delete)
- [Опубликовать](/docs/apps/publish)
