## Создать расписание

`POST /v1/work-schedules`

Создаёт своё расписание работы в библиотеке портала.

Созданное расписание назначается серверам через [смену режима работы](/docs/infra/lifecycle/run-mode).

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

| Поле | Тип | Обяз. | Описание |
|------|-----|:-----:|----------|
| `name` | string | да | Название, от 1 до 80 символов. Пробелы по краям отбрасываются |
| `timezone` | string | да | Часовой пояс IANA, в котором читаются окна, например `Europe/Moscow` |
| `windows` | array | да | Окна `{ isoDay, start, end }`, не больше двух в день. Правила окон — в [индексе раздела](/docs/infra/work-schedules) |
| `windows[].isoDay` | number | да | День недели: 1 — понедельник, 7 — воскресенье |
| `windows[].start` | string | да | Начало окна, местное время `ЧЧ:ММ` с шагом 30 минут |
| `windows[].end` | string | да | Конец окна, местное время `ЧЧ:ММ` с шагом 30 минут. Полночь — `24:00` |

## Примеры

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

```bash
curl -X POST https://vibecode.bitrix24.tech/v1/work-schedules \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Смены склада",
    "timezone": "Europe/Moscow",
    "windows": [
      { "isoDay": 1, "start": "09:00", "end": "18:00" },
      { "isoDay": 2, "start": "09:00", "end": "13:00" },
      { "isoDay": 2, "start": "14:00", "end": "24:00" }
    ]
  }'
```

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

```bash
curl -X POST https://vibecode.bitrix24.tech/v1/work-schedules \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Смены склада",
    "timezone": "Europe/Moscow",
    "windows": [
      { "isoDay": 1, "start": "09:00", "end": "18:00" },
      { "isoDay": 2, "start": "09:00", "end": "13:00" },
      { "isoDay": 2, "start": "14:00", "end": "24:00" }
    ]
  }'
```

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

```javascript
const res = await fetch('https://vibecode.bitrix24.tech/v1/work-schedules', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Смены склада',
    timezone: 'Europe/Moscow',
    windows: [
      { isoDay: 1, start: '09:00', end: '18:00' },
      { isoDay: 2, start: '09:00', end: '13:00' },
      { isoDay: 2, start: '14:00', end: '24:00' },
    ],
  }),
})
const { data } = await res.json()
console.log(`Создано расписание ${data.id}`)
```

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

```javascript
const res = await fetch('https://vibecode.bitrix24.tech/v1/work-schedules', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Смены склада',
    timezone: 'Europe/Moscow',
    windows: [
      { isoDay: 1, start: '09:00', end: '18:00' },
      { isoDay: 2, start: '09:00', end: '13:00' },
      { isoDay: 2, start: '14:00', end: '24:00' },
    ],
  }),
})
const { data } = await res.json()
```

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

Ответ приходит со статусом `201 Created`.

| Поле | Тип | Описание |
|------|-----|----------|
| `success` | boolean | Всегда `true` при успехе |
| `data.id` | string | ID созданного расписания |
| `data.kind` | string | Всегда `CUSTOM` |
| `data.name` | string | Название |
| `data.presetKey` | null | У своего расписания всегда `null` |
| `data.timezone` | string | Часовой пояс IANA |
| `data.windows` | array | Окна `{ isoDay, start, end }` в порядке дней и времени |
| `data.version` | number | Номер версии, у нового расписания `1` |
| `data.canEdit` | boolean | `true`: автор вправе править своё расписание |
| `data.assignedCount` | number | `0`: новое расписание ещё никому не назначено |

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

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

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

400 — время окна не в формате `ЧЧ:ММ`:

```json
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "windows.0.end: must be local time HH:MM (24:00 for midnight)"
  }
}
```

## Ошибки

| HTTP | Код | Описание |
|------|-----|----------|
| 400 | `VALIDATION_ERROR` | Тело не подходит под схему — неизвестное поле, пустое название, неизвестный часовой пояс, время не в формате `ЧЧ:ММ` — либо окна нарушают правила недели. В `message` — путь к полю и причина |
| 400 | `WORK_SCHEDULE_EMPTY` | Передан пустой `windows`: сервер на таком расписании не работал бы никогда |
| 400 | `RUN_MODE_UNAVAILABLE` | Режимы работы ещё не включены для портала |
| 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` |
| 401 | `INVALID_API_KEY` | Ключ не опознан: такой строки на платформе нет |
| 403 | `WORK_SCHEDULE_LIMIT` | У портала уже 50 своих расписаний. Удалите ненужное или назначьте готовое |
| 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` | Ключ не привязан к порталу Битрикс24 |
| 429 | `RATE_LIMITED` | Превышен лимит 20 запросов в минуту на ключ. Точное значение — в заголовке `x-ratelimit-limit` (потолок делится на реплики) |

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

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

- **Автор — владелец ключа.** Автором расписания записывается владелец ключа, а не пользователь сессии OAuth-приложения. Править и удалять расписание потом смогут он и администратор портала.
- **Готовые расписания в лимит не входят.** Лимит в 50 расписаний считает только свои, готовые расписания платформы его не занимают.

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

- [Список расписаний](./list.md)
- [Обновить расписание](./update.md)
- [Сменить режим работы сервера](/docs/infra/lifecycle/run-mode)
