
## Список ресурсов бронирования

`GET /v1/booking-resources`

Возвращает ресурсы бронирования, доступные ключу. Это единственный способ узнать значения для обязательного поля `resourceIds` при [создании бронирования](/docs/entities/bookings/create) — начните отсюда, если бронирование создаётся впервые.

Метод возвращает весь каталог целиком и параметров постраничного вывода не принимает: `meta.total` всегда равен длине `data`, а `meta.hasMore` всегда `false`.

## Параметры

| Параметр | Тип | Обяз. | По умолч. | Описание |
|----------|-----|:-----:|-----------|---------|
| `typeId` (query) | number | нет | — | Оставить только ресурсы одного типа. Целое положительное число в каноничной записи |
| `searchQuery` (query) | string | нет | — | Поиск Битрикс24 по подстроке. Непустая строка не длиннее 200 символов |

Параметры можно комбинировать. Любой другой параметр, повторный параметр, массивная или объектная форма записи (`typeId[]`, `filter[typeId]`) отклоняются с `400 INVALID_PARAMS` до обращения к Битрикс24.

Сортировка наружу не выведена намеренно: обход всегда идёт по возрастанию `id`, и управляемый снаружи порядок нарушил бы гарантию полноты ответа.

## Примеры

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

```bash
curl "https://vibecode.bitrix24.tech/v1/booking-resources?typeId=1" \
  -H "X-Api-Key: YOUR_API_KEY"
```

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

```bash
curl "https://vibecode.bitrix24.tech/v1/booking-resources?typeId=1" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN"
```

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

```javascript
const res = await fetch('https://vibecode.bitrix24.tech/v1/booking-resources?typeId=1', {
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
  },
})

const { data, meta } = await res.json()
console.log(`Доступно ресурсов: ${meta.total}`)
```

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

```javascript
const res = await fetch('https://vibecode.bitrix24.tech/v1/booking-resources?typeId=1', {
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
  },
})

const { data, meta } = await res.json()
console.log(`Доступно ресурсов: ${meta.total}`)
```

Связка «список ресурсов → бронирование» одним сценарием:

```javascript
const res = await fetch('https://vibecode.bitrix24.tech/v1/booking-resources?searchQuery=переговорная', {
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
  },
})

const { data } = await res.json()
console.log(`Доступно ресурсов: ${data.length}`)

const room = data.find(r => r.isMain === 'Y') ?? data[0]

await fetch('https://vibecode.bitrix24.tech/v1/bookings', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    resourceIds: [room.id],
    datePeriod: {
      from: { timestamp: 1723446900, timezone: 'Europe/Moscow' },
      to: { timestamp: 1723447800, timezone: 'Europe/Moscow' },
    },
  }),
})
```

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

| Поле | Тип | Описание |
|------|-----|---------|
| `success` | boolean | Всегда `true` при успехе |
| `data[].id` | number | Идентификатор ресурса. Именно это значение идёт в `resourceIds` бронирования |
| `data[].name` | string | Название ресурса |
| `data[].typeId` | number | Идентификатор типа ресурса. Он же принимается фильтром `typeId` |
| `data[].isMain` | string | Признак основного ресурса в записи Битрикс24: `"Y"` или `"N"` |
| `meta.total` | number | Количество возвращённых записей. Всегда равно длине `data` |
| `meta.hasMore` | boolean | Всегда `false` — успешный ответ содержит весь каталог в пределах потолка |

Поле `description` не отдаётся намеренно: это свободный текст портала, в нём встречаются персональные данные и внутренние заметки, а для выбора ресурса оно не нужно. Параметры уведомлений и шаблонов в ответ тоже не попадают.

Ответ помечен заголовком `Cache-Control: private, no-store` — содержимое привязано к порталу и к личности ключа.

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

```json
{
  "success": true,
  "data": [
    {
      "id": 1,
      "name": "Переговорная на 6 человек",
      "typeId": 1,
      "isMain": "Y"
    },
    {
      "id": 3,
      "name": "Переговорная с проектором",
      "typeId": 1,
      "isMain": "N"
    }
  ],
  "meta": {
    "total": 2,
    "hasMore": false
  }
}
```

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

400 — передан неизвестный параметр:

```json
{
  "success": false,
  "error": {
    "code": "INVALID_PARAMS",
    "message": "Only typeId and searchQuery are supported query parameters."
  }
}
```

## Ошибки

| HTTP | Код | Описание |
|------|-----|---------|
| 400 | `INVALID_PARAMS` | Неизвестный, повторный, массивный или некорректный параметр запроса. Тот же код приходит, когда фильтры отклонил сам Битрикс24 |
| 401 | `MISSING_API_KEY` | Заголовок `X-Api-Key` не передан |
| 401 | `TOKEN_MISSING` | У ключа нет настроенных токенов Битрикс24 |
| 403 | `SCOPE_DENIED` | У ключа нет скоупа `booking` |
| 403 | `BITRIX_ACCESS_DENIED` | Битрикс24 отказал в доступе |
| 403 | `B24_TARIFF_RESTRICTION` | Тариф портала не включает ресурсы бронирования |
| 422 | `BITRIX_METHOD_NOT_FOUND` | Модуль бронирования на портале недоступен |
| 422 | `BITRIX_ERROR` | Битрикс24 отклонил запрос |
| 429 | `RATE_LIMITED` | Превышено 20 запросов в минуту на портал к этому эндпоинту, либо лимит запросов к Битрикс24. Точное значение — в заголовке `x-ratelimit-limit` (потолок делится на реплики). Смотрите `Retry-After` |
| 429 | `OPERATION_TIME_LIMIT` | Превышен лимит времени операций Битрикс24 |
| 429 | `QUEUE_OVERFLOW` | Очередь портала к Битрикс24 переполнена, запрос отклонён сразу. Смотрите `Retry-After` |
| 429 | `QUEUE_TIMEOUT` | Запрос простоял в очереди к Битрикс24 дольше таймаута. Смотрите `Retry-After` |
| 502 | `BITRIX_RESPONSE_INVALID` | Битрикс24 вернул ответ неожиданной формы |
| 502 | `BITRIX_PAGINATION_INCOMPLETE` | Обход каталога не сошёлся, полнота ответа не гарантируется |
| 502 | `BITRIX_RESULT_TOO_LARGE` | На портале больше 500 ресурсов. Сузьте выборку через `typeId` или `searchQuery` |
| 502 | `BITRIX_UNAVAILABLE` | Битрикс24 временно недоступен |
| 503 | `BITRIX_TIMEOUT` | Битрикс24 не ответил вовремя |

Ни один отказ не содержит частично собранных данных: ответ либо полный, либо это ошибка.

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

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

**Усечённый каталог не отдаётся.** Портал, каталог которого не помещается в потолок, получает отказ, а не первые записи: неполный список без признака неполноты читался бы как весь каталог. Сузьте выборку фильтрами.

**Полнота гарантируется для каталога, не менявшегося во время запроса.** Битрикс24 не предоставляет снимок коллекции, поэтому создание или удаление ресурса параллельно с обходом может сдвинуть страницу. Ответ в этом случае остаётся корректным по форме, но может не содержать только что созданный ресурс или содержать только что удалённый.

**Видимость решает Битрикс24.** Метод возвращает то, что портал показывает личности, стоящей за ключом. Ключ сотрудника со скоупом `booking` метод вызвать может. Совпадёт ли его список со списком администратора, решает портал, а не платформа.

**Ключ только для чтения подходит.** Метод читающий, поэтому режим «только чтение» его не отбивает.

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

- [Бронирования](/docs/entities/bookings)
- [Создать бронирование](/docs/entities/bookings/create)
- [Список бронирований](/docs/entities/bookings/list)
- [Ошибки](/docs/errors)
- [Лимиты и оптимизация](/docs/optimization)
