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

# Quiet hours

> Why a text message waits: the recipient-local sending window, how the recipient's clock is worked out, what a held message looks like, and how to declare a message the window does not apply to

A text message to a US number may only be sent during daytime hours **in the recipient's own local time**. That is a legal restriction rather than a preference, and it is enforced here rather than left to each flow author to remember: a message whose recipient's clock is outside the window is **held** and sent when the window opens.

This applies to [SMS](/concepts/sms) and to nothing else. Email carries no such restriction and has no gate — see [quiet hours do not apply to email](/concepts/transactional-email#quiet-hours-do-not-apply-to-email).

## The window that is enforced

**08:00 until 21:00, every day of the week, in the recipient's local time.** That is the federal window, and it is what the platform applies to every `marketing` message before it goes out.

Two properties are worth knowing before you meet them:

**The check happens when the message is about to leave, not when the task starts.** Outbound work is [paced](/concepts/dispatch-pacing), so a message can be queued at 20:55 and reach the front of the queue at 21:10. Checking at the start of the task would have blessed that send half an hour before it happened; checking where the queue delay ends is the only place the answer is still true.

**A held message does not hold the queue behind it.** It steps out of line into a held state with a computed release time, and the next message is sent immediately — including a `transactional` one, and including one addressed to a recipient three time zones away for whom it is the middle of the afternoon. One recipient's clock never becomes everybody's.

## Working out where the recipient is

A window in the recipient's local time needs a time zone, and a text message does not carry one. So the send task declares **which parts of your record say where the recipient is**, and the platform asks them in order, using the first one that answers:

```json theme={null}
{
  "action_id": "twilio__sms__send",
  "quiet_hours": {
    "lead_timezone": "{{ input.record.timezone }}",
    "zip_code": "{{ input.record.postal_code }}",
    "state": "{{ input.record.state }}"
  },
  "parameters": { "to": "{{ input.record.phone_e164 }}", "sender": "+15551234567", "body": "…" }
}
```

| Order | Source          | What it must resolve to                                                                                                   |
| ----- | --------------- | ------------------------------------------------------------------------------------------------------------------------- |
| 1     | `lead_timezone` | An IANA time-zone name, such as `America/Chicago`. Used as-is when it names a zone the platform knows.                    |
| 2     | `zip_code`      | A US ZIP code, `#####` or `#####-####`. Consulted when no usable time zone was supplied.                                  |
| 3     | `state`         | A two-letter US state abbreviation, such as `TX`. Consulted last.                                                         |
| 4     | —               | Nothing resolved: the recipient's location is **unknown**, and the [conservative window](#when-nothing-resolves) applies. |

Each one is an expression evaluated against the flow's context, exactly like a task parameter. Supply as many or as few as your records actually carry — each is optional, and an unanswerable one simply falls through to the next.

<Warning>
  **The recipient's phone number is deliberately not one of these sources, and it never will be.** Numbers are portable and people move: an area code says where a number was *issued*, not where its owner is. Guessing wrong means texting somebody in the middle of their night, which is the exact outcome this whole mechanism exists to prevent — so the platform declines to guess. There is no parameter through which a number could be offered, and adding one would be a visible change rather than a quiet one.
</Warning>

Only the **answer** travels onward. The ZIP and the state stay on the record; what is carried alongside the queued message is a time-zone name and nothing else.

### When a state spans two time zones

Fourteen US states span more than one zone — Florida, Texas, Michigan, Indiana, Kentucky, Alaska and eight others. A recipient resolved by **state alone** in one of those cannot be placed in a single zone, so they are treated as unknown and take the conservative window below. It is always the later answer, never the earlier one.

Both of the other two sources are unaffected: a record carrying a time zone, or a ZIP code, resolves such a recipient precisely. If your leads are in split states and you want the full window, carry one of those.

## When nothing resolves

An unknown location does not mean "send anyway" and it does not mean "fail". It means **send only during hours that are legal in every US time zone** — the overlap of 08:00–21:00 across Hawaii at one end and the east coast at the other:

| Season                   | The window, in Eastern time | In UTC        |
| ------------------------ | --------------------------- | ------------- |
| Summer (daylight saving) | **14:00 – 21:00**           | 18:00 – 01:00 |
| Winter (standard time)   | **13:00 – 21:00**           | 18:00 – 02:00 |

<Warning>
  **That is roughly seven hours a day, and it is much narrower than any single zone's window.** If your records carry no time zone, no ZIP and no state — or if the task declares no `quiet_hours` sources at all — then *every* marketing message you send takes this band, and most of what you queue in the morning will be held until the afternoon.

  Nothing is lost and nothing errors; the messages go out later the same day. But an author who expected a 13-hour window and got a 7-hour one will read it as the platform being broken, so it is worth checking one record before you send a hundred thousand.
</Warning>

The band is bounded at the opening end by Hawaii's 08:00 — which is 18:00 UTC all year, since Hawaii does not observe daylight saving — and at the closing end by 21:00 on the east coast. It is computed from real time-zone rules on the day, not from a stored offset, so it is correct across both daylight-saving transitions rather than an hour wrong for a fortnight twice a year.

## Marketing and transactional

Each send task declares what kind of message it sends, and that is what decides whether the window applies:

| `traffic_class`               | Quiet hours                                                          | What it is for                                                                                                                |
| ----------------------------- | -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `marketing` (**the default**) | **Applied.** The message is held until the recipient's window opens. | Anything the recipient did not specifically ask to receive at that moment.                                                    |
| `transactional`               | **Bypassed.** The message is sent immediately, at any hour.          | Messages the recipient asked for and is waiting on: one-time passcodes, fraud alerts, appointment and delivery notifications. |

`marketing` is the default deliberately: it is the protected value, so it has to be the one a task gets by saying nothing about the field. The other ordering fails invisibly — nothing errors, nothing looks wrong, and the first signal is a complaint.

<Note>
  **Declaring `transactional` requires an administrator.** A non-admin save is refused with a `422` naming the step and the field. The declaration is recorded on the flow, so who switched off a legal protection and on which step is answerable afterwards.

  The vocabulary is exactly those two values. There is no account-level switch and no per-run override — a single toggle that could turn the protection off everywhere is precisely what this design rejects.
</Note>

## A held message

A message held for quiet hours is a **first-class, visible state**, not a silent pause.

**On the run.** `GET /flows/executions/{execution_id}` carries a `quiet_hours_hold` object while the message is held:

```json theme={null}
{
  "id": "exec_84e3a014280848f4",
  "status": "running",
  "quiet_hours_hold": {
    "zone": "America/Denver",
    "hold_until": "2026-09-05T14:00:00Z"
  }
}
```

It is deliberately **not** a new execution status, and the reason is that the two facts are independent: a run can be parked on a human reply *and* have its next message held for legal hours at the same time. So `status` says whether the run is parked, and `quiet_hours_hold` says whether a message is waiting on a clock. The presence of the object is the whole signal — `null` (the overwhelmingly common case) means no legal-hours hold is in force, which is **not** the same as "not parked".

Two details when you read it:

* `zone` is the time zone the window was evaluated in. **`null` means the recipient's location was unknown** and the conservative window above is in force. It never means UTC.
* The object is populated by the **detail** route only. The executions list leaves it out, the same way it leaves out per-step detail.

**On the stream.** Watching the [execution stream](/concepts/execution-streaming) shows the same thing as it happens:

| Event                            | When                                                            |
| -------------------------------- | --------------------------------------------------------------- |
| `execution.held_quiet_hours`     | The message was held. Carries the zone and the release instant. |
| `execution.quiet_hours_released` | The hold ended and the message returned to the queue.           |

**Neither is terminal**, so a hold never closes an open stream — a detail view can sit on a run held overnight and pick the story back up in the morning.

**A held message keeps its place in line.** When the window opens it returns to the queue in the position it left, ahead of everything queued behind it while it waited. Nothing is re-sent and nothing is dropped.

<Note>
  **A release can lag the window opening by a few minutes.** Holds are released as part of the ordinary dispatch cycle rather than by a clock ticking alongside it, so on an account with other work in flight a release is picked up promptly, and on an otherwise idle account it can wait up to about five minutes. This is the same behaviour a scheduled [pause resume](/concepts/dispatch-pacing#pause-is-not-cancel) has, for the same reason.
</Note>

**No phone number appears anywhere in any of this** — not in the hold object, not in either stream event, not in the operator logs behind them. A zone name, a release time and the run's own identifiers are the whole of it.

## Stricter state rules

Several US states impose windows narrower than the federal one, and the platform maintains a dated table of them.

<Warning>
  **The table below is published as reference. It is not what the send gate enforces today.**

  What is applied to an outbound message is the **federal 08:00–21:00** window described above, in the recipient's resolved local time. The stricter state windows are not yet applied at the point a message is sent, because the state is deliberately not carried alongside the queued message — only the resolved time zone is, and a time zone cannot be turned back into a state.

  The federal window is always legal, so this is a gate that is *narrower than the table*, never a gate that is missing. But if your own obligations are stricter than federal — and in these states they are — you must express that yourself, with the [`windowed` execution model](/concepts/execution-models#windowed) on the sending step, until the gate applies the table itself.
</Warning>

The table is current **as of 2026-09-03**. These rules change, so the date is published with it rather than left implicit — a table with no as-of date is one nobody can tell is stale. A state that is **absent from the table uses the federal window** rather than falling into a gap.

| State | Window (recipient local)                      | Days      |
| ----- | --------------------------------------------- | --------- |
| AL    | 08:00 – 20:00                                 | Mon–Sat   |
| CT    | 09:00 – 20:00                                 | every day |
| FL    | 08:00 – 20:00                                 | every day |
| IL    | 09:00 – 21:00                                 | every day |
| KY    | 10:00 – 21:00                                 | every day |
| LA    | 08:00 – 20:00                                 | Mon–Sat   |
| MA    | 08:00 – 20:00                                 | every day |
| MD    | 08:00 – 20:00                                 | every day |
| MI    | 09:00 – 21:00                                 | every day |
| MN    | 09:00 – 21:00                                 | every day |
| MS    | 08:00 – 20:00                                 | Mon–Sat   |
| NM    | 09:00 – 21:00                                 | every day |
| NV    | 09:00 – 20:00                                 | every day |
| OK    | 08:00 – 20:00                                 | every day |
| PA    | 09:00 – 21:00 Mon–Sat; 13:30 – 21:00 Sunday   | every day |
| RI    | 09:00 – 18:00 Mon–Fri; 10:00 – 17:00 Saturday | Mon–Sat   |
| SD    | 09:00 – 21:00                                 | Mon–Sat   |
| TX    | 09:00 – 21:00 Mon–Sat; 12:00 – 21:00 Sunday   | every day |
| UT    | 08:00 – 21:00                                 | Mon–Sat   |
| WA    | 08:00 – 20:00                                 | every day |
| WY    | 08:00 – 20:00                                 | every day |

<Note>
  **Holiday restrictions are not covered.** Six states in the table above — AL, LA, MS, PA, RI and UT — additionally restrict calling on certain public holidays. Those restrictions are **not** enforced by the platform and are not represented in the table. If they apply to you, handle them in your own scheduling.

  Nebraska is deliberately absent. The available sources contradict each other about what its rule is and whom it applies to, and a compliance table is the wrong place to record a guess — so Nebraska takes the federal window until a citable answer exists.
</Note>

This is a starting point for your own compliance review and not a substitute for one. The table is maintained on a best-effort basis from public sources, most of them secondary, and it is dated for exactly that reason.

## Next steps

<CardGroup cols={2}>
  <Card title="SMS" icon="comment-sms" href="/concepts/sms">
    The two send steps, both sender forms, and what a send reports.
  </Card>

  <Card title="Dispatch pacing" icon="gauge-high" href="/concepts/dispatch-pacing">
    Why a message waits for reasons other than the clock, and what a pause holds.
  </Card>

  <Card title="Execution models" icon="clock" href="/concepts/execution-models#windowed">
    Confine a task to your own recurring local-time window, per record.
  </Card>

  <Card title="Execution streaming" icon="signal-stream" href="/concepts/execution-streaming">
    Watch a run hold and release live, without polling.
  </Card>
</CardGroup>
