
## Resource bookings

`GET /v1/calendar-resources/bookings`

Returns the occupied intervals of calendar resources for a period — when each resource is occupied and by which booking.

## Parameters

| Parameter | Type | Required | Default | Description |
|----------|-----|:-----:|-----------|---------|
| `resourceIds` (query) | string | Yes | — | Comma-separated calendar resource IDs: `?resourceIds=57,59`. List: [`GET /v1/calendar-resources`](./list.md) |
| `from` (query) | string | No | — | Period start — a date such as `2026-10-01`, or an ISO 8601 date with time. Without `from` and `to`, the period runs from 30 days before the current date to 90 days after it. If only `to` is passed, the period has no start limit |
| `to` (query) | string | No | — | Period end in the same format. If only `from` is passed, the period has no end limit |

The generic `filter` parameter is not applied by this endpoint. By default, the API preserves the previous HTTP 200 response and data, adds `Warning: 299 - "filter is not supported on this endpoint and was ignored"`, and records unsupported-filter use in the server log.

## Examples

### curl — personal key

```bash
curl "https://vibecode.bitrix24.com/v1/calendar-resources/bookings?resourceIds=59&from=2025-01-21&to=2025-01-22" \
  -H "X-Api-Key: YOUR_API_KEY"
```

### curl — OAuth application

```bash
curl "https://vibecode.bitrix24.com/v1/calendar-resources/bookings?resourceIds=59&from=2025-01-21&to=2025-01-22" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN"
```

### JavaScript — personal key

```javascript
const params = new URLSearchParams({ resourceIds: '59', from: '2025-01-21', to: '2025-01-22' })
const res = await fetch(`https://vibecode.bitrix24.com/v1/calendar-resources/bookings?${params}`, {
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
  },
})

const { success, data } = await res.json()
for (const slot of data) console.log(slot.resourceId, slot.from, slot.to)
```

### JavaScript — OAuth application

```javascript
const params = new URLSearchParams({ resourceIds: '59', from: '2025-01-21', to: '2025-01-22' })
const res = await fetch(`https://vibecode.bitrix24.com/v1/calendar-resources/bookings?${params}`, {
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
  },
})

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

## Response fields

`from` and `to` are returned for every interval; the other fields may be absent.

| Field | Type | Description |
|------|-----|---------|
| `success` | boolean | Always `true` on success |
| `data` | array | Occupied resource intervals |
| `data[].id` | number | ID of the calendar event that occupies the resource |
| `data[].name` | string | Event name |
| `data[].resourceId` | number | Resource ID from `resourceIds` |
| `data[].bookingId` | number \| null | Resource booking ID |
| `data[].from` | string | Interval start: ISO 8601 date and time with an offset. For an all-day interval — a date without time |
| `data[].to` | string | Interval end in the same format. For an all-day interval — the last day, inclusive |
| `data[].timezoneFrom` | string | Start time zone, for example `UTC`. Not returned for an all-day interval |
| `data[].timezoneTo` | string | End time zone. Not returned for an all-day interval |
| `data[].skipTime` | boolean | `true` — an all-day interval |
| `data[].accessibility` | string | Availability status in the event, for example `busy` |
| `data[].importance` | string | Event importance, for example `normal` |
| `data[].eventType` | string | Event type. For a resource booking — `#resourcebooking#` |
| `meta.total` | number | Number of intervals in the response |

## Response example

```json
{
  "success": true,
  "data": [
    {
      "from": "2025-01-21T09:30:00+00:00",
      "to": "2025-01-21T10:30:00+00:00",
      "id": 7667,
      "name": "Booking: client meeting",
      "resourceId": 59,
      "bookingId": 159,
      "accessibility": "busy",
      "importance": "normal",
      "eventType": "#resourcebooking#",
      "timezoneFrom": "UTC",
      "timezoneTo": "UTC",
      "skipTime": false
    },
    {
      "from": "2025-01-21T11:00:00+00:00",
      "to": "2025-01-21T12:00:00+00:00",
      "id": 7707,
      "name": "Booking: product presentation",
      "resourceId": 59,
      "bookingId": 167,
      "accessibility": "busy",
      "importance": "normal",
      "eventType": "#resourcebooking#",
      "timezoneFrom": "UTC",
      "timezoneTo": "UTC",
      "skipTime": false
    }
  ],
  "meta": {
    "total": 2
  }
}
```

An all-day interval has dates without time and no `timezoneFrom` or `timezoneTo`:

```json
{
  "from": "2024-04-14",
  "to": "2024-04-16",
  "id": 7389,
  "name": "Booking: lead",
  "resourceId": 59,
  "bookingId": 155,
  "accessibility": "busy",
  "importance": "normal",
  "eventType": "#resourcebooking#",
  "skipTime": true
}
```

## Error response example

400 — `resourceIds` is missing:

```json
{
  "success": false,
  "error": {
    "code": "MISSING_REQUIRED_FIELDS",
    "message": "resourceIds must be a comma-separated list of positive safe integers"
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|---------|
| 200 | `Warning: 299` | The filter is ignored by default; previous data is preserved and the warning is sent in the `Warning` header. |
| 400 (strict mode only) | `UNSUPPORTED_FILTER` | The server mode is disabled by default; until it is enabled, the endpoint preserves HTTP 200 and the previous data. |
| 400 | `MISSING_REQUIRED_FIELDS` | `resourceIds` is missing or contains anything other than comma-separated positive integers |
| 400 | `INVALID_PARAMS` | `from` or `to` is not an ISO 8601 date |
| 403 | `SCOPE_DENIED` | The API key does not have the `calendar` scope |
| 403 | `BITRIX_ACCESS_DENIED` | Bitrix24 denied the key owner access to bookings |
| 401 | `TOKEN_MISSING` | The API key has no configured tokens |
| 401 | `MISSING_API_KEY` | The `X-Api-Key` header is missing |
| 429 | `RATE_LIMITED` | Request limit exceeded |
| 502 | `BITRIX_UNAVAILABLE` | Bitrix24 is unavailable, returned bookings in an invalid shape, or returned an interval without a date and time zone |
| 503 | `BITRIX_TIMEOUT` | Bitrix24 did not respond in time |

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

## Known specifics

**A non-existent resource does not cause an error.** An ID that is not in the resource list returns an empty `data` with `200` — the same as a resource with no bookings. Check IDs against [`GET /v1/calendar-resources`](./list.md); otherwise a typo in an ID reads as "the resource is free".

**All intervals in one response.** There is no pagination: the method returns all intervals for the period. To shorten the response, narrow the period with `from` and `to`.

## See also

- [List calendar resources](./list.md)
- [Calendar resources](/docs/entities/calendar-resources)
- [Calendar events](/docs/entities/calendar-events)
- [Attendee availability](/docs/calendar/accessibility)
