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

# Public-sector civic services: an end-to-end walkthrough

> Compose a resident communications posture end to end in Devotel Orbit: split civic reminders, benefits renewals, court-date notices, and emergency alerts into tenant-owned consent classes, run the routine lane on scheduled sends with resident-local quiet hours, take two-way multilingual service intake on WhatsApp with auto-localized templates, keep the emergency lane on the shipped voice-plus-SMS-plus-push cascade with its own stop valve, answer the hotline on an IVR with a callback queue, deliver formal notices by email, and close the loop with the reach evidence your public accountability requires.

# Public-sector civic services: an end-to-end walkthrough

This walkthrough takes a city, county, or agency from the first classification decision to a live civic reminder and emergency alert posture. It composes pieces that already ship: [scheduled sends](https://docs.orbit.devotel.io/guides/message-scheduling.md), [send-window optimization](https://docs.orbit.devotel.io/guides/message-scheduling-send-window-optimization.md), [two-way WhatsApp](https://docs.orbit.devotel.io/guides/whatsapp/getting-started.md) with [auto-localized templates](https://docs.orbit.devotel.io/guides/template-auto-localization.md), the [campus emergency cascade](https://docs.orbit.devotel.io/guides/emergency-mass-notification-campus-walkthrough.md), [IVR flows](https://docs.orbit.devotel.io/guides/build-ivr-flow.md) with [voice queues](https://docs.orbit.devotel.io/guides/voice-queues.md) and the [callback console](https://docs.orbit.devotel.io/guides/voice-callback-console.md), and the [email lifecycle](https://docs.orbit.devotel.io/guides/email-lifecycle-guide.md). The examples below use one fictional city, Alder Point, population 86,000, with a resident contact base in which roughly a third prefers Spanish.

Every control on this page is tenant-owned. Your office decides which service classes exist, which are routine and which are urgent, which windows apply, and which languages you support. Orbit provides the channels and the controls; the posture decisions are yours.

## 1. Classify every service message before you send it

Write the classes down first, because the class decides the controls:

1. **Emergency alerts.** Evacuation orders, boil-water notices, shelter-in-place, and severe weather with a threat to life. This class is exempt from your quiet hours by your configuration, and it should be the only class that is. It sends only through the emergency lane in section 4.
2. **Service reminders and benefits renewals.** Collection-day changes, benefits and license renewals, permit status, and clinic appointment reminders. This class respects quiet hours by your configuration and sits outside marketing frequency caps.
3. **Court-date and legal notices.** Court-date reminders, jury duty, and hearing notices. This class respects quiet hours by your configuration, and where the law requires a document, the email lane in section 6 carries it.
4. **Civic outreach and programs.** Program enrollment appeals, surveys, and event announcements. This class respects quiet hours, [frequency caps](https://docs.orbit.devotel.io/guides/frequency-caps.md), and every promotional gate in [send gates](https://docs.orbit.devotel.io/compliance/send-gates.md).

Declare the classes and their consent basis in [consent management](https://docs.orbit.devotel.io/compliance/consent-management.md) and [send gates](https://docs.orbit.devotel.io/compliance/send-gates.md), and set the per-class windows in [quiet-hours configuration](https://docs.orbit.devotel.io/guides/quiet-hours-configuration.md). Two decisions deserve explicit sign-off before the first send:

* **What counts as urgent.** Write the rule down ("evacuation orders, boil-water notices, and shelter-in-place are urgent; renewal reminders are routine") so the quiet-hours exemption is never decided at send time.
* **Where each class sends from.** Routine classes and the emergency class should use different senders, and section 4 explains why: a resident who opts out of a drill must not land on the emergency suppression list.

Then build the resident record the classes act on: `phone` in E.164, `preferred_language`, address, and one field per service enrollment. Create them as [custom fields](https://docs.orbit.devotel.io/guides/custom-fields.md) if your import does not carry them, and build one segment per service and per district so a renewal blast addresses its enrolled residents rather than the whole city ([CDP segments](https://docs.orbit.devotel.io/guides/cdp-segments.md) for attribute-driven groups, [static contact lists](https://docs.orbit.devotel.io/guides/contact-lists-static-targeting.md) for rosters you maintain by hand).

## 2. The routine lane: scheduled reminders in resident-local quiet hours

The routine lane is everything that is not an emergency: benefits renewals, court dates, collection days, permit updates. Send it on a schedule, and let each resident's local quiet hours decide when it lands.

Every channel send endpoint accepts `scheduled_at` ([message scheduling](https://docs.orbit.devotel.io/guides/message-scheduling.md)). Pair it with `send_at_type: "optimize_with_send_window"` and the platform treats your time as the earliest acceptable send time, then moves any fire time that lands outside your configured window in the recipient's local timezone forward to the next window open ([send-window optimization](https://docs.orbit.devotel.io/guides/message-scheduling-send-window-optimization.md)):

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/messages/sms \
  -H "X-API-Key: $ORBIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "+15550142",
    "to": "+14155550173",
    "body": "Alder Point: Your water bill is due May 4. Pay online or at City Hall. Reply HELP for assistance, STOP to opt out of billing reminders.",
    "scheduled_at": "2026-05-01T16:00:00Z",
    "send_at_type": "optimize_with_send_window",
    "recipient_timezone": "America/Los_Angeles",
    "metadata": { "class": "service-reminders", "campaign": "alder-point-water-may" }
  }'
```

A renewal ladder that works for most offices:

| Notice | First send | Follow-ups | Window |
| - | - | - | - |
| Benefits renewal | 30 days before the deadline | 7 days and 1 day before | Your quiet-hours window, resident-local |
| Court-date reminder | 7 days before the date | 1 day before | Your quiet-hours window, resident-local |
| Collection-day change | The evening before | None | Your quiet-hours window, resident-local |
| Civic outreach | Per campaign | Capped by frequency caps | Your quiet-hours window, plus every promotional gate |

Pass `recipient_timezone` whenever you know it; for residents whose timezone you cannot resolve, the window posture you chose in [quiet-hours configuration](https://docs.orbit.devotel.io/guides/quiet-hours-configuration.md) decides what happens, per class. That is your call, and it is worth writing down next to the class definitions from section 1.

Two lane rules keep the routine lane honest:

* **Routine copy never travels on the emergency sender.** A renewal reminder that arrives from the number your evacuation orders use trains residents to ignore that number.
* **Opt-outs are class-scoped.** A resident who opts out of civic outreach still receives the service and legal classes, because the consent classes from section 1 govern suppression, not a single global list per resident.

## 3. Multilingual intake on WhatsApp

A reminders program that only speaks one language leaves a third of Alder Point reading nothing. Run two-way service intake on WhatsApp after connecting your number per [WhatsApp getting started](https://docs.orbit.devotel.io/guides/whatsapp/getting-started.md):

* **Auto-localized templates.** The first message of a resident session goes out on an approved template; [template auto-localization](https://docs.orbit.devotel.io/guides/template-auto-localization.md) generates and keeps the per-language versions in step, and [per-language recipes](https://docs.orbit.devotel.io/guides/per-language-recipes.md) carries the worked shapes for bodies, variables, and keyword handling in each language. Address the template with the resident's `preferred_language` so a renewal notice opens in Spanish for a Spanish-preferring resident without a second send.
* **Two-way intake.** Once the resident replies, the conversation continues free-form: a renewal question, an address change, a missed-collection report. Wire acknowledgements with keyword auto-reply rules the same way the [campus walkthrough](https://docs.orbit.devotel.io/guides/emergency-mass-notification-campus-walkthrough.md) wires its reporting keywords, and tag the thread so the right desk watches it in your [Inbox](https://docs.orbit.devotel.io/guides/inbox-setup.md).
* **Language switch on reply.** If a resident answers in a language different from their stored preference, the thread follows the resident; update `preferred_language` from the exchange so the next scheduled send opens in the right language.

Read the tally next to the delivery record: replies by keyword and language tell the service desk where intake volume is building before the counter line does.

## 4. The emergency lane: kept distinct, on the shipped cascade

Emergency alerts reuse the cascade the [campus emergency notification walkthrough](https://docs.orbit.devotel.io/guides/emergency-mass-notification-campus-walkthrough.md) ships: push at T+0 to registered devices, voice at T+0 per recipient as the primary reach, and SMS armed as the fallback hop on a terminal voice failure. The payload shape is the same waterfall, with civic copy:

```bash theme={null}
curl -X POST "https://api.orbit.devotel.io/api/v1/notify" \
  -H "X-API-Key: $ORBIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "waterfall",
    "fallback_window_seconds": 600,
    "from": "+15550199",
    "metadata": { "class": "emergency", "campaign": "alder-point-boil-water-riverbend" },
    "bindings": [
      {
        "channel": "voice",
        "address": "+14155550173",
        "body": "Alder Point emergency management: A boil water notice is in effect for the Riverbend district. Boil tap water for one minute before use until further notice. Updates at the city alerts page.",
        "max_price": 0.25
      },
      {
        "channel": "sms",
        "address": "+14155550173",
        "body": "Alder Point: Boil water notice in Riverbend district until further notice. Details: alderpoint.gov/alerts",
        "max_price": 0.02
      }
    ],
    "max_total_price": 0.27
  }'
```

Define a curated push category once (`POST /api/v1/push/categories`, identifier `CIVIC_EMERGENCY`, high-alert sound, one action that opens your alerts page) and name it on every emergency push, so the device side treats an alert differently from a renewal reminder.

The separation from routine traffic is the posture, and it is three decisions:

1. **Different sender, different account where you can.** A STOP reply writes to the suppression list of the account that sent. If drills and outreach share the emergency sender, one bad drill can opt residents out of the next real alert. Keep the emergency roster intact by construction.
2. **Quiet hours exempt the emergency class only.** A 2 AM restoration-of-water update must not wait until 8 AM; a renewal reminder must. Both postures are your configuration in [quiet-hours configuration](https://docs.orbit.devotel.io/guides/quiet-hours-configuration.md).
3. **The federal voice window still stands.** The 8 AM to 9 PM recipient-local dialing window is non-relaxable, for any message class, and an emergency does not change it. The SMS and push legs carry the urgent reach outside those hours; count the residents with no resolvable timezone before the first event, not during it.

Drills follow the campus walkthrough's discipline: schedule them against a volunteer list, never against the production resident roster, and label the drill in `metadata` so the delivery log can separate it afterwards.

When something goes wrong with a send itself, the [emergency stop runbook](https://docs.orbit.devotel.io/guides/compliance-emergency-stop.md) is the org-wide stop valve: know before an incident what it blocks, what it deliberately does not block, and who in your office is authorized to arm and disarm it.

## 5. Voice hotline IVR with a callback queue

Not every resident wants an app, and during an event the least digital residents pick up the phone first. Build the hotline with [build an IVR flow](https://docs.orbit.devotel.io/guides/build-ivr-flow.md):

* **Status lane.** Match the calling number to an address, play the current notice for that district (boil water, outage, road closure), and offer one keystroke to report something the system has not seen. The lane should read from the same data your alerts page shows, so the IVR never tells a caller something the web contradicts.
* **Services lane.** Benefits hours, clinic appointments, and permit status by menu, with [slot-filling intake](https://docs.orbit.devotel.io/guides/ivr-slot-filling-intake.md) for account or case numbers where a lookup needs one.

Route callers who need a person through [voice queues](https://docs.orbit.devotel.io/guides/voice-queues.md), and offer the callback instead of the hold: after your wait threshold or on overflow, the [callback console](https://docs.orbit.devotel.io/guides/voice-callback-console.md) returns the call in order when an agent frees up. For senior residents and long events, a callback beats a forty-minute hold, and your queue statistics stay honest about actual wait. During an event, update the IVR prompts the moment facts change; the hotline is your overflow valve.

## 6. Formal notices by email

Email carries the notices that are documents, not messages:

* **Court and hearing notices.** The notice itself plus the packet as an attachment ([email attachments](https://docs.orbit.devotel.io/guides/email-attachments.md)); keep these in the legal class so a resident's outreach unsubscribe never stops a court-date notice.
* **Benefits and program determinations.** Written confirmations residents may need to present or appeal, sent with the same lifecycle controls.

The [email lifecycle guide](https://docs.orbit.devotel.io/guides/email-lifecycle-guide.md) walks the class split, the suppression behavior per class, and the delivery record to keep as your evidence of notice. One suppression list covers the whole resident base across every channel; a resident who opts out on SMS is not emailed around the decision, except where a legal class requires the document.

## 7. Reach evidence for public accountability

A civic program answers to residents, council, and public-records requests. Keep three reads current:

* **Delivery log.** Filter the [delivery log](https://docs.orbit.devotel.io/guides/delivery-log.md) by the `metadata` class and campaign values and by the event window. Per-hop receipts (`GET /api/v1/notify/:notifyId`) show which leg reached each resident and at what price; [track a cascade](https://docs.orbit.devotel.io/guides/track-a-cascade.md) reads every column. Export the residents every hop missed and load them as a `missed-<event>` list for a different leg: a staff phone tree or a door-knock list for residents who are push-blind and voice-blind both.
* **Audit and export controls.** The [audit log export](https://docs.orbit.devotel.io/guides/audit-log-export.md) records who changed the class posture, quiet hours, and senders, and when; the [interactions export auth model](https://docs.orbit.devotel.io/guides/interactions-export-auth-model.md) decides which roles may pull resident-level interaction exports, so the evidence package leaves the workspace through a door you chose.
* **Standing report.** After each event and each quarter, deliver reached counts per channel against segment size, missed counts, opt-out deltas, and per-class spend as a [scheduled report](https://docs.orbit.devotel.io/guides/scheduled-reports.md), with [insights alerts](https://docs.orbit.devotel.io/guides/insights-alerts-console-operator-guide.md) on delivery-failure rate and inbound keyword volume during events. The accountability review then exists before anyone requests it.

### Rollout checklist

1. Classes written down with their consent basis, quiet-hours posture, and the urgent exemption signed off.
2. Resident record carries `preferred_language`, timezone where known, and service enrollments; one segment per service and district.
3. Routine renewal ladder tested against a staff list with the production `scheduled_at` and send-window settings.
4. WhatsApp connected; auto-localized templates approved in every supported language; intake keywords and staffed desks named.
5. Emergency sender and account separate from routine; `CIVIC_EMERGENCY` push category created; device coverage counted.
6. Waterfall payload tested against a volunteer list with the production `max_price` values; drill list separate from the resident roster.
7. Hotline IVR rehearsed, including the callback-on-overflow path.
8. Legal email class split from outreach; attachment delivery verified.
9. Delivery-log filter, audit export, export role scoping, and the standing scheduled report configured.
10. Emergency stop authority and its block scope written into the incident plan.

### Troubleshooting

* **`TCPA_FEDERAL_DIALING_WINDOW_BLOCKED` on the emergency voice hop.** A schedule fact, not a configuration error: the federal window does not relax for emergencies. The SMS and push legs carry those residents; confirm your emergency-class SMS posture is open overnight.
* **Opt-out replies after a drill.** A STOP reply writes to the suppression list of the account that sent. If a drill shares the emergency sender, residents can opt out of the wrong class; the separate emergency account from section 4 keeps the alert roster intact.
* **A scheduled reminder arrived later than the time you sent.** With `send_at_type: "optimize_with_send_window"`, a fire time outside the resident's window moves to the next window open; that is the posture working. Use the default fixed scheduling only for sends where the exact instant matters more than the window.
* **Localized WhatsApp template rejected.** Per-language bodies have their own approval rules; the [per-language recipes](https://docs.orbit.devotel.io/guides/per-language-recipes.md) worked shapes carry the variables and phrasing that pass.
* **Residents with no resolvable timezone.** The voice hop refuses them under the federal guard; the SMS hop catches them when your class posture allows it. The section 2 counts surface how many residents that is before the first event.

## See also

* [Industries overview: Public sector](https://docs.orbit.devotel.io/guides/industries-overview.md) — the vertical's buyer problem, compliance posture, and channel matrix.
* [Public-sector civic notifications buyer explainer](https://docs.orbit.devotel.io/blog/public-sector-civic-notifications-buyer-explainer) — the resident communications workflow for the buying decision.
* [Devotel Orbit for public sector](https://orbit.devotel.io/en/public-sector) — the product page for this vertical.
* [Emergency mass notification for campuses](https://docs.orbit.devotel.io/guides/emergency-mass-notification-campus-walkthrough.md) — the cascade and drill discipline section 4 reuses.
* [Template auto-localization](https://docs.orbit.devotel.io/guides/template-auto-localization.md) and [per-language recipes](https://docs.orbit.devotel.io/guides/per-language-recipes.md) — the multilingual intake layer.
* [Message scheduling](https://docs.orbit.devotel.io/guides/message-scheduling.md) and [send-window optimization](https://docs.orbit.devotel.io/guides/message-scheduling-send-window-optimization.md) — the routine lane's scheduling surfaces.
* [Quiet-hours configuration](https://docs.orbit.devotel.io/guides/quiet-hours-configuration.md), [send gates](https://docs.orbit.devotel.io/compliance/send-gates.md), and [consent management](https://docs.orbit.devotel.io/compliance/consent-management.md) — the tenant-owned class controls.
* [Emergency stop runbook](https://docs.orbit.devotel.io/guides/compliance-emergency-stop.md) — the org-wide stop valve.
* [Build an IVR flow](https://docs.orbit.devotel.io/guides/build-ivr-flow.md), [voice queues](https://docs.orbit.devotel.io/guides/voice-queues.md), and [voice callback console](https://docs.orbit.devotel.io/guides/voice-callback-console.md) — the hotline lane.
* [Email lifecycle guide](https://docs.orbit.devotel.io/guides/email-lifecycle-guide.md) — formal notices and the evidence record.


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