Business Hours
Business hours decide whether you’re open, closed, or on a holiday, and they route calls accordingly. SIP.IO models them as a reusable, timezone-aware schedule (the equivalent of Amazon Connect’s “hours of operation”) that you can evaluate inside a flow or attach directly to a number, queue, or ring group.
The schedule object
Section titled “The schedule object”A time_schedule is a named, reusable object. Many routers can share one schedule.
{ "id": "sch_01j0jvpe0wzc6g05bktfew0xyx", "account_id": "acc_01jf18ah3jeb5w6dfp27sgjsbt", "name": "Support hours", "timezone": "America/New_York" }| Field | Purpose |
|---|---|
timezone | IANA timezone (DST-aware). null inherits account.timezone; override per schedule for multi-zone operations. |
Hours are expressed as rules (time_schedule_rule), stored as rows. There are three kinds:
[ { "schedule_id": "sch_01j0jvpe0wzc6g05bktfew0xyx", "kind": "weekly", "dow": 1, "start_time": "09:00", "end_time": "17:00" }, { "schedule_id": "sch_01j0jvpe0wzc6g05bktfew0xyx", "kind": "weekly", "dow": 5, "start_time": "09:00", "end_time": "13:00" }, { "schedule_id": "sch_01j0jvpe0wzc6g05bktfew0xyx", "kind": "date", "start_date": "2026-07-04", "is_closed": 1 }, { "schedule_id": "sch_01j0jvpe0wzc6g05bktfew0xyx", "kind": "date_range", "start_date": "2026-12-24", "end_date": "2026-12-26", "is_closed": 1 }]| Field | Purpose |
|---|---|
kind | weekly (recurring), date (a single day), or date_range (a span). |
dow | Day of week for weekly: 0 = Sunday … 6 = Saturday. |
start_time / end_time | "HH:MM" open interval (for the relevant day). |
start_date / end_date | "YYYY-MM-DD" for date / date_range. |
is_closed | 1 marks a closed/holiday override. |
Evaluation rules
Section titled “Evaluation rules”The engine evaluates against “now” in the schedule’s timezone, with these precedence rules:
- Date and date-range rules override weekly rules. A holiday on a Monday beats the normal Monday hours.
is_closedforces closed for that date/range, regardless of weekly hours (this is how holidays work).- Overnight intervals are supported. If
start_time > end_time(e.g.22:00–06:00), the interval wraps past midnight. Intervals are half-open[start, end). - No matching open interval → closed.
The three outcomes
Section titled “The three outcomes”Evaluating a schedule yields one of three outcomes:
| Outcome | When |
|---|---|
in_hours | An open interval matches now. |
out_of_hours | Closed by the weekly schedule (outside open hours). |
holiday | Closed by a date/date-range is_closed override. |
Two ways to use a schedule
Section titled “Two ways to use a schedule”1. In a flow: the timeCondition node
Section titled “1. In a flow: the timeCondition node”Drop a timeCondition node into a call flow and branch on the outcome:
{ "id": "hours", "type": "timeCondition", "data": { "kind": "timeCondition", "scheduleId": "sch_01j0jvpe0wzc6g05bktfew0xyx" } }Draw edges for in_hours, out_of_hours, and optionally holiday. If you don’t draw a holiday edge, the holiday outcome falls back to out_of_hours, so the common case (treat holidays like after-hours) needs just two edges, while splitting them out is one extra edge. This node resolves inside the stateful edge object with no edge round-trip.
2. Attached to an object: “hours on the queue”
Section titled “2. Attached to an object: “hours on the queue””You can attach a schedule directly to a DID, extension, queue, or ring group. When that object is closed or on a holiday, its route target is overridden before the call is enqueued or rung:
{ "id": "q_01j160r23gw5zkpfjme3fwzs5k", "name": "Support", "schedule_id": "sch_01j0jvpe0wzc6g05bktfew0xyx", "closed_dest_kind": "voicemail", "closed_dest_id": "vm_01jg8asp59ps9rtt7azhrhvcre", "holiday_dest_kind": "flow", "holiday_dest_id": "flow_01jzqbs3hn9rb3sp06ypecjn0t"}- In hours → the normal route (enqueue / ring / dest).
- Closed →
closed_dest_*. - Holiday →
holiday_dest_*, falling back toclosed_dest_*if not set. - No schedule, or no override dest → the normal route (fail open).
This is the “hours on the queue” model from Amazon Connect: one schedule gates every route into the queue, shared by all the DIDs and extensions that point at it.
Which approach should I use?
Section titled “Which approach should I use?”| Use… | When |
|---|---|
timeCondition in a flow | You want a single visual place that controls hours, possibly with different branches for sales vs support, or extra logic around the decision. |
| Schedule attached to a queue/number | You want hours enforced consistently on a destination no matter how callers reach it: the simplest, most robust option for “this queue is closed.” |
They compose: a flow can check hours up front and the queue it enqueues to can have its own schedule as a backstop.
For a step-by-step, see Configure business hours.