> ## Documentation Index
> Fetch the complete documentation index at: https://docs.open.cx/llms.txt
> Use this file to discover all available pages before exploring further.

# Office hours and holidays

> Configure weekly availability, dated closures and recurring holidays in one place, then use the same schedules for teams and workflow routing.

Office Hours stores weekly availability and calendar exceptions for your organization. Use named schedules for individual teams, countries or workflow branches, and the default schedule for organization-wide availability.

## Configure in the dashboard

Open **Settings → Office Hours**. You need permission to read these settings; editing requires **Office Hours: Write**.

1. Edit the default schedule or add/edit a custom schedule.
2. Select its timezone and weekly shifts. No weekly shifts means open 24/7, except during closures and holidays.
3. Under **Holidays and exceptions**, choose **Add holiday or exception**.
4. Enter a name, type, start and end. Dates and times use the schedule's timezone, not your browser's timezone. The end is exclusive: Christmas Day starts at December 25 midnight and ends at December 26 midnight.
5. Enable **Repeat every year** for a fixed annual date. Leave it off for a one-off holiday or a holiday whose date changes each year.
6. Save the schedule. Repeat for each calendar exception.

Exception types:

| Type | Effect |
| - | - |
| Holiday (closed) | Closes the schedule and identifies the closure as a holiday for workflow routing. |
| Closed | Closes the schedule for the specified period. |
| Extra opening hours | Opens the schedule outside its normal weekly shifts. |

When exceptions overlap, **Holiday → Closed → Extra opening hours → weekly shifts** determines availability. Extra opening hours do not reopen a holiday. To shorten a working day, add a closure covering the hours you want to remove. Existing weekly shifts resume outside the exception period.

A yearly exception starts repeating from its configured year and must span less than a year. Periods can cross December into January. An occurrence with an invalid date, such as February 29 in a non-leap year, is skipped. Moving holidays must be entered with their actual dates each year; there is no automatic national-holiday feed. Each schedule supports up to 200 exceptions.

Configured start and end times skipped by a daylight-saving clock change are rejected. If a later yearly occurrence falls in a skipped hour, that boundary moves to the first valid local time after the gap. When clocks repeat a local time, the earlier occurrence is used. Check recurring exceptions that fall near clock changes when updating your calendar.

Campaign weekly send windows still follow the recipient's timezone when it is available. Holidays and other dated exceptions always follow the schedule's timezone.

Updating a named calendar refreshes its upcoming SLA transitions and active deadlines. Closed time does not consume the remaining SLA budget. If a calendar has no future opening, affected timers remain frozen until you reopen the calendar. Existing snoozes and paused resolution timers remain paused.

## Use schedules in workflows and IVRs

Use **Get Custom Working Hours** with the named schedule, or **Get Default Working Hours** for the organization default. Both use the current schedule configuration and return:

* `isNowWithinHours` (custom) or `isNowWithinDefaultWorkingHours` (default): whether the schedule is open, including its exceptions.
* `isHoliday`: whether a holiday exception is active.
* `exceptionName`: the active exception's name, or an empty string.
* `secondsUntilNextOpen`: seconds until the next opening; zero when already open. If no next opening can be calculated, this is a **3,600-second recheck interval**, not a promised opening.
* `nextOpeningKnown`: false when the schedule is closed with no known opening.

For a workflow that must wait for office hours, branch on the open status first. When closed, wait the returned seconds, then run the Office Hours check again. Only proceed when `isNowWithinHours` (custom schedule) or `isNowWithinDefaultWorkingHours` (default schedule) is true. A Wait step alone does not guarantee the schedule is open, including when a closure changes while the run is waiting.

Sequences that respect Office Hours remain held when a valid calendar has no opening. They recheck hourly and release the held sends once the calendar permits them, including after you edit the schedule.

For separate IVR branches, check `isHoliday` first, then `isNowWithinHours`; use the remaining branch for ordinary closures. Keep dates and time calculations in Office Hours rather than copying them into workflow code. A named schedule must be explicitly selected by the workflow; creating it alone does not change routing.

If two branches use different hours, create two named schedules and check the appropriate one in each branch. Existing workflows with embedded calendars continue using those calendars until updated to use the Office Hours actions.

## API and MCP

Reading requires `office-hours:read`; creating or updating requires `office-hours:write`. The existing create and update operations accept an optional `exceptions` array:

```json theme={"dark"}
{
  "name": "France Support",
  "iana_timezone": "Europe/Paris",
  "shifts": [
    { "day_of_week": "monday_to_friday", "start_time": "09:00:00", "end_time": "17:00:00" }
  ],
  "exceptions": [
    {
      "name": "Christmas Day",
      "kind": "holiday",
      "starts_at": "2026-12-25T00:00:00",
      "ends_at": "2026-12-26T00:00:00",
      "repeat_yearly": true
    }
  ]
}
```

This is a create request. Custom-schedule updates also require each existing shift's `id`. Default-schedule requests omit `name`, and default shifts omit `id`.

On update, **omitting `exceptions` preserves them**, supplying an array replaces them, and supplying `[]` clears them. Include every exception you want to retain when replacing the array. Existing clients that update only weekly shifts will not erase holidays. Local timestamps must include seconds and must not include `Z` or a timezone offset.

MCP exposes the same field on `create_office_hours`, `update_office_hours` and `update_default_office_hours`. Read back the schedule after saving to confirm its dates and timezone.

<CardGroup>
  <Card title="Get Default" icon="clock" href="./get-default">Read the organization-wide fallback schedule.</Card>
  <Card title="Update Default" icon="pen-to-square" href="./update-default">Save default shifts and exceptions.</Card>
  <Card title="List Schedules" icon="list" href="./list">List named schedules.</Card>
  <Card title="Get Schedule" icon="magnifying-glass" href="./get">Read a named schedule.</Card>
  <Card title="Create Schedule" icon="plus" href="./create">Create shifts and exceptions together.</Card>
  <Card title="Update Schedule" icon="pen" href="./update">Replace shifts or exceptions.</Card>
  <Card title="Delete Schedule" icon="trash" href="./delete">Delete a named schedule.</Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.