
## Update an application

`PATCH /v1/apps/:id`

Changes application properties. Send only the fields you want to change.

## Parameters

| Parameter | Type | Required | Description |
|----------|-----|:-----:|---------|
| `id` (path) | string | yes | Application identifier from [create](/docs/apps/create) or [list](/docs/apps/list) |

## Request fields (body)

| Field | Type | Description |
|------|-----|---------|
| `title` | string | Name, from 1 to 255 characters. For an application in the catalog the limit is 100 characters |
| `description` | string \| null | Description, up to 2000 characters |
| `appUrl` | string | Application address, only `http://` or `https://`. An empty string is stored as `null` |
| `scopes` | array | Set of application scopes, at least one. A change to the platform `vibe:*` scopes is propagated into the application's active keys — see "Known specifics" |
| `redirectUris` | array | Redirect addresses for OAuth |
| `placements` | array | Placements. List of codes — [Available placements](/docs/apps/placements/available). To bind or remove a single placement without republishing the app — [Placements](/docs/apps/placements) |

`handlerUrl` cannot be changed — the field in the body results in `400 HANDLER_URL_READONLY`.

## Examples

### curl — personal key

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

### curl — OAuth application

```bash
curl -X PATCH https://vibecode.bitrix24.com/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.com/dashboard" }'
```

### JavaScript — personal key

```javascript
const res = await fetch('https://vibecode.bitrix24.com/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.com/dashboard',
  }),
})

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

### JavaScript — OAuth application

```javascript
const res = await fetch('https://vibecode.bitrix24.com/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.com/dashboard',
  }),
})

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

## Response fields

| Field | Type | Description |
|------|-----|---------|
| `data` | object | Application after the update. The field set matches the [create](/docs/apps/create) response, without `rawKey` |
| `data.updatedAt` | string | Update date, ISO 8601 |
| `warnings` | array | Appears on partial embedding-place sync: codes that could not be bound |

## Response example

```json
{
  "success": true,
  "data": {
    "id": "33c4d5e6-f7a8-49b0-1234-5c6d7e8f9012",
    "title": "Sales dashboard",
    "description": "Updated",
    "scopes": ["crm", "user", "placement"],
    "handlerUrl": "https://vibecode.bitrix24.com/v1/bitrix-handler",
    "appUrl": "https://app-abc12345.vibecode.bitrix24.com/dashboard",
    "redirectUris": [
      "https://vibecode.bitrix24.com/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": []
  }
}
```

## Error response example

404 — application not found:

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

## Errors

| HTTP | Code | Description |
|------|-----|---------|
| 400 | `HANDLER_URL_READONLY` | `handlerUrl` passed in the body — the field is set by the platform and cannot be changed |
| 400 | `NO_USER_TOKEN` | Changing `placements` or renaming a published application without a user token on a cloud account |
| 400 | `TITLE_TOO_LONG_FOR_CATALOG` | The new name is longer than 100 characters for an application that is in the catalog |
| 403 | `UNAUTHORIZED` | The key does not belong to the author or owner of the application |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | The request changes `scopes` while coming from a key in read-only mode. Such a key can still change the other fields. More — [Access mode](/docs/keys-auth/access-mode) |
| 404 | `APP_NOT_FOUND` | No application with the specified `id` |
| 502 | `BITRIX_PARTIAL_REBIND` | Bitrix24 rejected the re-binding of an embedding place during the rename. The new name is not written — repeat the request |

Full list of common API errors — [Errors](/docs/errors).

## Known specifics

- **Renaming an application in the catalog also changes the labels on the account.** The new `title` goes into the catalog card (the `catalogTitle` field is written together with `title`) and into the embedding places — the left-menu item and the CRM tabs. The rename therefore calls Bitrix24 and can return `400 NO_USER_TOKEN` or `502 BITRIX_PARTIAL_REBIND`. On a rejection the name is not written, and repeating the request repairs the state. The account caches the left menu — the new name shows up after a hard page reload. For an application outside the catalog the rename changes `title` only.
- **Changing `scopes` propagates the platform `vibe:*` scopes into the application's keys.** The update compares the old and the new set and applies the `vibe:*` difference to every active key of the application — an added `vibe:ai` appears on the keys, a removed `vibe:infra` is taken away from them. Bitrix24 account scopes (`crm`, `user` and the rest) are not propagated: their set is fixed when the key is issued and changes only by reissuing it.
- **A mismatch between the application scopes and its key is repaired with two requests.** An application created before propagation existed can carry `vibe:infra` in `scopes` while its key does not — the key answers `403` to server creation. Remove `vibe:infra` from `scopes` with the first request and put it back with the second: propagation applies exactly the difference, so the second edit adds the scope to the key. The key's effective set is shown by [`GET /v1/me`](/docs/keys-auth/me) in `data.scopes` when called with that key.
- **Changing `placements` of a published application triggers embedding-place sync on the account.** Binding and unbinding happen directly on the Bitrix24 account, and some codes may fail to bind — then the response carries `warnings` with a list of such codes. On a cloud account without a user token the sync is impossible, and the request returns `400 NO_USER_TOKEN`. For an application in `PRIVATE` status, `placements` are written to the database without contacting the account.

## See also

- [Applications](/docs/apps)
- [Create an application](/docs/apps/create)
- [Application data](/docs/apps/get)
- [Delete an application](/docs/apps/delete)
- [Publish](/docs/apps/publish)
