## Обновить расписание

`PATCH /v1/work-schedules/:id`

Меняет название, часовой пояс или окна своего расписания. Библиотека общая на портал, поэтому новые окна сразу действуют у всех серверов, назначенных на расписание, а правка несёт номер версии, чтобы не затереть чужую.

## Параметры

| Параметр | В | Тип | Обяз. | Описание |
|----------|---|-----|:-----:|----------|
| `id` | path | string | да | ID своего расписания. Источник — `data[].id` из [списка расписаний](./list.md) |

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

| Поле | Тип | Обяз. | Описание |
|------|-----|:-----:|----------|
| `version` | number | да | Версия, которую вы прочитали. Источник — `version` в [списке](./list.md) или в [получении расписания](./get.md) |
| `name` | string | нет | Новое название, от 1 до 80 символов |
| `timezone` | string | нет | Новый часовой пояс IANA |
| `windows` | array | нет | Новые окна `{ isoDay, start, end }` — заменяют прежние целиком. Правила окон — в [индексе раздела](/docs/infra/work-schedules) |

## Примеры

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

```bash
curl -X PATCH https://vibecode.bitrix24.tech/v1/work-schedules/WORK_SCHEDULE_ID \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "version": 2,
    "windows": [
      { "isoDay": 1, "start": "08:00", "end": "17:00" },
      { "isoDay": 2, "start": "08:00", "end": "17:00" }
    ]
  }'
```

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

```bash
curl -X PATCH https://vibecode.bitrix24.tech/v1/work-schedules/WORK_SCHEDULE_ID \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "version": 2,
    "windows": [
      { "isoDay": 1, "start": "08:00", "end": "17:00" },
      { "isoDay": 2, "start": "08:00", "end": "17:00" }
    ]
  }'
```

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

```javascript
const res = await fetch(
  `https://vibecode.bitrix24.tech/v1/work-schedules/${workScheduleId}`,
  {
    method: 'PATCH',
    headers: {
      'X-Api-Key': 'YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      version: 2,
      windows: [
        { isoDay: 1, start: '08:00', end: '17:00' },
        { isoDay: 2, start: '08:00', end: '17:00' },
      ],
    }),
  }
)
const body = await res.json()
console.log(`Версия ${body.data.version}, затронуто серверов: ${body.affectedServers}`)
```

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

```javascript
const res = await fetch(
  `https://vibecode.bitrix24.tech/v1/work-schedules/${workScheduleId}`,
  {
    method: 'PATCH',
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      version: 2,
      windows: [
        { isoDay: 1, start: '08:00', end: '17:00' },
        { isoDay: 2, start: '08:00', end: '17:00' },
      ],
    }),
  }
)
const body = await res.json()
```

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

| Поле | Тип | Описание |
|------|-----|----------|
| `success` | boolean | Всегда `true` при успехе |
| `data` | object | Расписание после правки — та же форма, что в [получении расписания](./get.md) |
| `data.version` | number | Новая версия: каждая успешная правка увеличивает её на единицу |
| `affectedServers` | number | Сколько серверов портала работает по расписанию после правки, включая серверы других сотрудников |

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

```json
{
  "success": true,
  "data": {
    "id": "cmfp4r0q2000a1ocg7h2k9x3d",
    "kind": "CUSTOM",
    "name": "Смены склада",
    "presetKey": null,
    "timezone": "Europe/Moscow",
    "windows": [
      { "isoDay": 1, "start": "08:00", "end": "17:00" },
      { "isoDay": 2, "start": "08:00", "end": "17:00" }
    ],
    "version": 3,
    "canEdit": true,
    "assignedCount": 1
  },
  "affectedServers": 1
}
```

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

409 — расписание успели изменить после вашего чтения:

```json
{
  "success": false,
  "error": {
    "code": "WORK_SCHEDULE_STALE",
    "message": "The work schedule was changed by someone else — reload it and repeat the edit"
  }
}
```

## Ошибки

| HTTP | Код | Описание |
|------|-----|----------|
| 400 | `VALIDATION_ERROR` | Тело не подходит под схему — нет `version`, неизвестное поле, неизвестный часовой пояс — либо окна нарушают правила недели. В `message` — путь к полю и причина |
| 400 | `WORK_SCHEDULE_EMPTY` | Передан пустой `windows`: серверы на таком расписании не работали бы никогда |
| 400 | `RUN_MODE_UNAVAILABLE` | Режимы работы ещё не включены для портала |
| 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` |
| 401 | `INVALID_API_KEY` | Ключ не опознан: такой строки на платформе нет |
| 403 | `WORK_SCHEDULE_PRESET_READONLY` | Расписание готовое — оно не правится. Для другой недели [создайте своё](./create.md) |
| 403 | `WORK_SCHEDULE_EDIT_FORBIDDEN` | Править расписание может только его автор или администратор портала |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | Ключ в режиме «только чтение» — правка ему закрыта |
| 403 | `INFRA_SCOPE_REQUIRED` | У ключа нет скоупа `vibe:infra` |
| 403 | `INFRA_FORBIDDEN_FOR_COWORK_KEY` | Вызов сделан ключом Cowork/Code — библиотека расписаний такому ключу закрыта. Что делать — [Проектный ключ для деплоя](/docs/cowork/deploy-key) |
| 404 | `NOT_FOUND` | Расписания с таким `id` нет в портале ключа, либо ключ не привязан к порталу Битрикс24 |
| 409 | `WORK_SCHEDULE_STALE` | Версия в запросе устарела: расписание изменили после вашего чтения. Прочитайте его заново и повторите правку с новой `version` |
| 429 | `RATE_LIMITED` | Превышен лимит 30 запросов в минуту на ключ. Точное значение — в заголовке `x-ratelimit-limit` (потолок делится на реплики) |

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

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

- **Правка окон или пояса перестраивает пробуждения всех назначенных серверов.** Замена окон, пересчёт пробуждений у каждого сервера на расписании и новая версия записываются одной операцией: при отказе не меняется ничего. Правка одного названия пробуждений не касается.
- **Счёт серверов меняется вместе с окнами.** Сервер на расписании работает в его окна, поэтому более длинная неделя увеличивает счёт за каждый назначенный сервер, включая серверы других сотрудников — их число приходит в `affectedServers`.

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

- [Получить расписание](./get.md)
- [Создать расписание](./create.md)
- [Удалить расписание](./delete.md)
