---
updatedAt: 2026-06-07T10:23:20.000Z
---

Fetch the complete documentation index at: https://apidocs.hibob.com/llms.txt. Use this file to discover all available pages before exploring further.

# Search calendar events

Read company-wide holidays and closures for a date range. Use with Search employee calendars to resolve which calendar applies to each employee before fetching events.

# OpenAPI definition

```json
{
  "openapi": "3.1.1",
  "info": {
    "title": "Time Off API",
    "contact": {
      "name": "Hi Bob, Inc."
    },
    "description": "Public API for the Calendar Events API.",
    "license": {
      "name": "Proprietary",
      "url": "https://apidocs.hibob.com/docs/api-terms-of-use"
    },
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.hibob.com/v1",
      "description": "Production"
    },
    {
      "url": "https://api.sandbox.hibob.com/v1",
      "description": "Sandbox"
    }
  ],
  "x-readme": {
    "metrics-enabled": false
  },
  "tags": [
    {
      "name": "Calendar events",
      "description": "Operations for managing Calendar events"
    }
  ],
  "security": [
    {
      "basic": []
    },
    {
      "bearer": []
    }
  ],
  "paths": {
    "/timeoff/calendars/events/search": {
      "post": {
        "operationId": "post_timeoff-calendars-events-search",
        "tags": [
          "Calendar events"
        ],
        "summary": "Search Calendar Events",
        "description": "Calendar events are company-wide holidays and closures (and similar events)\nthat affect work schedules and time off. Use this API to read those events\nand keep Bob's external calendars in sync.\n\nEach event is tied to a `calendarId` and `siteId`. To see which calendars and\nsites exist in your company (and their IDs), call the\n[Get a specific company list by name](https://apidocs.hibob.com/reference/get_company-named-lists-listname)\nendpoint with `listName = calendar` or `site`.\n\n**Events for a specific employee**\n\nTo get the events that apply to a specific employee, you need to find out the\ncalendar linked to the employee. The employee uses their site's default holiday\ncalendar unless a calendar is set on the employment table.\n\nRead the following fields with the\n[Search employee by ID](https://apidocs.hibob.com/reference/post_people-identifier)\nendpoint (`POST /v1/people/{identifier}`): `payroll.employment.calendarId` and `work.siteId`.\n\nThen fetch the employee's assigned calendar events:\n- If `payroll.employment.calendarId` is `null` — filter by `/calendarEvent/siteId` using `work.siteId`.\n- If `payroll.employment.calendarId` is set — filter by `/calendarEvent/calendarId` using that value.\n\n**Start date range span:** The mandatory `from` / `to` pair on `/calendarEvent/startDate`\nmust describe at most **366 calendar days inclusive** (both endpoints count). If the span\nis longer, the API returns **400 Bad Request** with key\n`exception.calendar.publicApi.dateRangeTooLong`. For multi-year exports, run several\nsearches (for example one per calendar year or successive 366-day windows) and merge\nresults client-side.\n\nWhen a filter uses a `fieldId` that is not supported for search (for example\n`/calendarEvent/visibility`), the API returns **400** with key\n`exception.calendar.publicApi.unsupportedFilterField` and the rejected path(s) in `args`.\n\n**OAuth scopes (app-user):** `timeoff.calendars:write`.\n\n**IAM permission:** `Settings / Calendars / Manage` (company-scoped).",
        "requestBody": {
          "required": true,
          "description": "Request body for calendar event search. `filters` is required and must\nalways include a date range on `/calendarEvent/startDate` as a `from`/`to`\npair (other filters may be added on top). `fields` is optional — omit it\nto return every field; `limit` and `cursor` are optional and fall back to\nserver-defined paging (see examples for typical payloads).",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SearchCalendarEventsInput"
              },
              "examples": {
                "dateRangeAndSelectedFields": {
                  "summary": "Search with date range and selected fields",
                  "description": "Request a subset of fields and constrain events to January 2024 using paired `from` / `to` filters on `/calendarEvent/startDate`.",
                  "value": {
                    "fields": [
                      "/calendarEvent/id",
                      "/calendarEvent/name",
                      "/calendarEvent/startDate",
                      "/calendarEvent/endDate",
                      "/calendarEvent/eventType",
                      "/calendarEvent/siteId"
                    ],
                    "filters": [
                      {
                        "fieldId": "/calendarEvent/startDate",
                        "operator": "from",
                        "values": [
                          "2024-01-01"
                        ]
                      },
                      {
                        "fieldId": "/calendarEvent/startDate",
                        "operator": "to",
                        "values": [
                          "2024-01-31"
                        ]
                      }
                    ],
                    "limit": 50
                  }
                },
                "filterBySite": {
                  "summary": "Site-scoped events within a date range",
                  "description": "Combine the mandatory date range on `/calendarEvent/startDate` with `/calendarEvent/siteId` to list events for a site. Always pass IDs as strings.",
                  "value": {
                    "fields": [
                      "/calendarEvent/id",
                      "/calendarEvent/name",
                      "/calendarEvent/startDate",
                      "/calendarEvent/eventSource",
                      "/calendarEvent/siteId",
                      "/calendarEvent/isWorkingDay"
                    ],
                    "filters": [
                      {
                        "fieldId": "/calendarEvent/startDate",
                        "operator": "from",
                        "values": [
                          "2024-01-01"
                        ]
                      },
                      {
                        "fieldId": "/calendarEvent/startDate",
                        "operator": "to",
                        "values": [
                          "2024-12-31"
                        ]
                      },
                      {
                        "fieldId": "/calendarEvent/siteId",
                        "operator": "equals",
                        "values": [
                          "12345"
                        ]
                      }
                    ],
                    "limit": 100
                  }
                },
                "minimalDateRangeOnly": {
                  "summary": "Mandatory date range only (default field projection)",
                  "description": "Smallest valid request — the date range on `/calendarEvent/startDate` is mandatory; `fields` is omitted to return every field, and `limit` caps the page size.",
                  "value": {
                    "filters": [
                      {
                        "fieldId": "/calendarEvent/startDate",
                        "operator": "from",
                        "values": [
                          "2024-01-01"
                        ]
                      },
                      {
                        "fieldId": "/calendarEvent/startDate",
                        "operator": "to",
                        "values": [
                          "2024-12-31"
                        ]
                      }
                    ],
                    "limit": 50
                  }
                },
                "nextPageWithCursor": {
                  "summary": "Next page using cursor",
                  "description": "Pass `next_cursor` from a previous response's `response_metadata` to continue pagination. The cursor value is opaque; this string is illustrative. The mandatory `from` / `to` date range on `/calendarEvent/startDate` must still be present.",
                  "value": {
                    "fields": [
                      "/calendarEvent/id",
                      "/calendarEvent/name",
                      "/calendarEvent/startDate"
                    ],
                    "filters": [
                      {
                        "fieldId": "/calendarEvent/startDate",
                        "operator": "from",
                        "values": [
                          "2024-01-01"
                        ]
                      },
                      {
                        "fieldId": "/calendarEvent/startDate",
                        "operator": "to",
                        "values": [
                          "2024-12-31"
                        ]
                      }
                    ],
                    "limit": 50,
                    "cursor": "eyJjIjoiZXhhbXBsZS1jdXJzb3IifQ=="
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchCalendarEventsOutput"
                }
              }
            }
          },
          "400": {
            "description": "Bad request — the request was malformed or missing required parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized — authentication credentials are missing or invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden — the authenticated user does not have permission to perform this operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests — rate limit exceeded, retry after the indicated delay",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error — an unexpected error occurred on the server",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "basic": {
        "type": "http",
        "scheme": "basic"
      },
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "OAuth 2.0",
        "description": "OAuth 2.0 access token issued by HiBob's Authorization Code flow. Approved Marketplace and technology partners install their app from the HiBob Developer Portal, complete the Authorization Code flow against their app's install URL, and exchange the authorization code (with `client_id` + `client_secret`) for an `access_token` (and `refresh_token`). Paste the resulting `access_token` here to call this endpoint from Try It!. <a href=\"https://apidocs.hibob.com/reference/oauth-20\" target=\"_blank\">Learn more about OAuth 2.0 in HiBob</a>"
      }
    },
    "schemas": {
      "ApiErrorResponse": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable machine-readable error code"
          },
          "message": {
            "type": "string",
            "description": "Human-readable error message"
          },
          "details": {
            "type": "object",
            "additionalProperties": true,
            "description": "Structured error context keyed by field or domain identifier"
          },
          "request_id": {
            "type": "string",
            "description": "Request identifier for support and tracing"
          }
        }
      },
      "CalendarEvent": {
        "type": "object",
        "properties": {
          "/calendarEvent/id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Unique identifier of the calendar event. Currently read-only —\nwill be used to reference a specific event when update endpoints become available."
          },
          "/calendarEvent/name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Display name of the calendar event."
          },
          "/calendarEvent/startDate": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 10,
            "maxLength": 10,
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "The start date of the event as an ISO 8601 calendar date string\n(`YYYY-MM-DD`), aligned to the timezone of the event's site\n(`/calendarEvent/siteId`). No time-of-day or timezone offset is included."
          },
          "/calendarEvent/endDate": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 10,
            "maxLength": 10,
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "The end date of the event as an ISO 8601 calendar date string\n(`YYYY-MM-DD`), aligned to the timezone of the event's site\n(`/calendarEvent/siteId`). No time-of-day or timezone offset is included."
          },
          "/calendarEvent/datePortion": {
            "type": [
              "string",
              "null"
            ],
            "description": "Indicates which portion of the day the event covers.\nPossible values: all_day, morning, afternoon."
          },
          "/calendarEvent/eventSource": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/CalendarEventSource"
              },
              {
                "type": "null"
              }
            ],
            "description": "The source that created this event. See `CalendarEventSource` for the\nfull list of supported values (`public_library`, `manual`)."
          },
          "/calendarEvent/eventType": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/CalendarEventType"
              },
              {
                "type": "null"
              }
            ],
            "description": "The event type. See `CalendarEventType` for the full list of supported\nvalues (`public_holiday`, `company_closure`)."
          },
          "/calendarEvent/isWorkingDay": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether this event falls on a working day."
          },
          "/calendarEvent/siteId": {
            "type": [
              "string",
              "null"
            ],
            "description": "The ID of the site associated with this event."
          },
          "/calendarEvent/calendarId": {
            "type": [
              "string",
              "null"
            ],
            "description": "The ID of the calendar this event belongs to."
          },
          "/calendarEvent/coverImage": {
            "type": [
              "string",
              "null"
            ],
            "description": "URL of the cover image for the event, if available."
          },
          "/calendarEvent/visibility": {
            "type": [
              "string",
              "null"
            ],
            "description": "Visibility level of the event (e.g. public, private)."
          }
        }
      },
      "CalendarEventFieldId": {
        "description": "Field IDs that can be requested in `fields` on the search request and that\ncan appear as keys on each result item. Use these IDs to project a subset\nof the response and to discover the available calendar event fields.",
        "type": "string",
        "enum": [
          "/calendarEvent/id",
          "/calendarEvent/name",
          "/calendarEvent/startDate",
          "/calendarEvent/endDate",
          "/calendarEvent/datePortion",
          "/calendarEvent/eventSource",
          "/calendarEvent/eventType",
          "/calendarEvent/isWorkingDay",
          "/calendarEvent/siteId",
          "/calendarEvent/calendarId",
          "/calendarEvent/coverImage",
          "/calendarEvent/visibility"
        ]
      },
      "CalendarEventFilterFieldId": {
        "description": "The filter field ID.",
        "type": "string",
        "enum": [
          "/calendarEvent/startDate",
          "/calendarEvent/calendarId",
          "/calendarEvent/eventType",
          "/calendarEvent/siteId"
        ]
      },
      "CalendarEventSource": {
        "description": "Closed list of supported event sources returned in `/calendarEvent/eventSource`.",
        "type": "string",
        "enum": [
          "public_library",
          "manual"
        ]
      },
      "CalendarEventType": {
        "description": "Closed list of supported event types returned in `/calendarEvent/eventType`\n(and accepted as filter values for that field).",
        "type": "string",
        "enum": [
          "public_holiday",
          "company_closure"
        ]
      },
      "ResponseMetadata": {
        "type": "object",
        "properties": {
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Opaque cursor that identifies the start of the next page of results.\nPass this value back as `cursor` on the next request to continue paging.\n`null` (or absent) when there are no more results."
          }
        }
      },
      "SearchCalendarEventsInput": {
        "description": "Request body for calendar event search. `filters` is required and must\nalways include a date range on `/calendarEvent/startDate` as a `from`/`to`\npair (other filters may be added on top). `fields` is optional — omit it\nto return every field; `limit` and `cursor` are optional and fall back to\nserver-defined paging (see examples for typical payloads).",
        "type": "object",
        "properties": {
          "fields": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/CalendarEventFieldId"
            },
            "description": "List of field IDs to include in each result item (see `CalendarEventFieldId`\nfor the available field IDs — they match the keys on each item in the response).\nWhen omitted, all available fields are returned."
          },
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchFilter"
            },
            "minItems": 2,
            "description": "Filters to apply to the search results.\n\nYou MUST always provide a date range as exactly two filters on\n`/calendarEvent/startDate` — one with operator `from` and one with\noperator `to`. Both are mandatory; requests without this pair are\nrejected with `400 Bad Request`.\n\nThe inclusive number of days from the `from` date through the `to` date must be\nbetween **1** and **366**; otherwise you receive **400** with\n`exception.calendar.publicApi.invalidDateRange` (empty or inverted range) or\n`exception.calendar.publicApi.dateRangeTooLong` (more than 366 days).\n\nOn top of the mandatory date range you may add more optional filters.\n\nAny other `fieldId` under `filters` (for example `/calendarEvent/visibility`)\nis rejected with **400** and `exception.calendar.publicApi.unsupportedFilterField`.\n\nExample minimal payload:\n[{\"fieldId\":\"/calendarEvent/startDate\",\"operator\":\"from\",\"values\":[\"2024-01-01\"]},\n{\"fieldId\":\"/calendarEvent/startDate\",\"operator\":\"to\",\"values\":[\"2024-01-31\"]}]"
          },
          "limit": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 500,
            "default": 50,
            "description": "Maximum number of results per page (allowed range 1–500). When omitted, the server applies its own default (often 50)."
          },
          "cursor": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 8192,
            "description": "Opaque cursor from a previous response's `response_metadata.next_cursor`. Omit on the first request;\nwhen present it must be a non-empty opaque token (empty string is not valid)."
          }
        },
        "required": [
          "filters"
        ],
        "default": {
          "fields": [
            "/calendarEvent/id",
            "/calendarEvent/name",
            "/calendarEvent/startDate",
            "/calendarEvent/endDate",
            "/calendarEvent/eventType",
            "/calendarEvent/siteId"
          ],
          "filters": [
            {
              "fieldId": "/calendarEvent/startDate",
              "operator": "from",
              "values": [
                "2024-01-01"
              ]
            },
            {
              "fieldId": "/calendarEvent/startDate",
              "operator": "to",
              "values": [
                "2024-01-31"
              ]
            }
          ],
          "limit": 50
        }
      },
      "SearchCalendarEventsOutput": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CalendarEvent"
            },
            "description": "Page of matching calendar events. Each item is keyed by field ID\n(e.g. `/calendarEvent/id`, `/calendarEvent/name`); only the fields\nrequested in `fields` are populated. Empty when there are no matches."
          },
          "response_metadata": {
            "$ref": "#/components/schemas/ResponseMetadata",
            "description": "Pagination metadata for this page (e.g. cursor for the next page).\nUse the `next_cursor` value to fetch subsequent pages."
          }
        },
        "required": [
          "items",
          "response_metadata"
        ]
      },
      "SearchFilter": {
        "type": "object",
        "properties": {
          "fieldId": {
            "$ref": "#/components/schemas/CalendarEventFilterFieldId",
            "description": "Field ID to filter by."
          },
          "operator": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "description": "Comparison operator for this filter. The allowed values depend on the\n`fieldId`:\n\n- `/calendarEvent/startDate`: **only** `from` or `to` (paired to form a\n  mandatory inclusive date range — see search operation docs).\n- `/calendarEvent/calendarId`, `/calendarEvent/siteId`,\n  `/calendarEvent/employeeId`, `/calendarEvent/eventType`: either\n  `equals` (row matches when its value appears in `values`) or\n  `notEqual` (row matches when its value does **not** appear in\n  `values`). Both operators accept one or multiple values and are\n  treated symmetrically as in / not-in.\n\nAny other operator (for example `eq`, `in`, `not_equals`, `neq`,\n`not_in`, `gt`, `lt`) is rejected with **400 Bad Request** and key\n`exception.calendar.publicApi.unsupportedOperator`."
          },
          "values": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Filter values, always sent as JSON strings.\n\n- For date filters (`/calendarEvent/startDate` with operator `from` or `to`):\n  provide exactly one ISO 8601 calendar date string `YYYY-MM-DD`\n  (e.g. `\"2024-01-31\"`) — no time-of-day, no timezone offset. The paired mandatory\n  `from`/`to` range on `startDate` must cover at most **366** inclusive days.\n- For `/calendarEvent/siteId`: provide one or more site IDs as strings. Use the\n  company sites list endpoint to discover the valid IDs for the company.\n- For `/calendarEvent/calendarId`: provide one or more holiday calendar IDs as\n  strings. Use the holiday calendars list endpoint to discover the valid IDs\n  for the company.\n- For `/calendarEvent/employeeId`: provide one or more Bob employee IDs as\n  strings. IDs must be sent as strings even when they look numeric, so that\n  large IDs are not truncated by JSON number precision in clients.\n- For enum-style filters (`/calendarEvent/eventType`): provide one or more\n  string values from the supported list (see `CalendarEventType`)."
          }
        },
        "required": [
          "fieldId",
          "operator",
          "values"
        ]
      }
    }
  }
}
```