# Opt-in flow: community alerts on +1 844 219 8901

Maintained in messaging-service/docs beside OPTIN-FLOW-DEVELOPER.md. This is the description of record for how consent is collected for government community alerting on +1 844 219 8901 (Aric Alerts, Product 1). It is kept true by the compliance-master rule in Projects/CLAUDE.md: any change to the opt-in paths, the message texts, the STOP and HELP handling, the quiet-hours policy, or the consent-request window updates this file in the same session. Code of record: Products.CommunityAlerts.Core (KeywordOptIn, WebSignup, ImportSubscribers, ConsentRequest, ProcessHeldMessages) in services-platform, and HandleInboundSmsUseCase plus the quiet-hours response exemption in messaging-service.

Number: +1 844 219 8901, toll-free, two-way SMS, shared by government tenants; inbound routing is by number + keyword (each keyword is unique per sending number, enforced at registration). Developer traffic stays on +1 833 240 8240. Every outbound community message leads with the sending entity's name ("Town of Pilot: ..."), and the consent ledger is written before any local subscription row — an aborted ledger write leaves nothing behind.

There are three ways a resident opts in. No path ever sends an alert to a number that has not either texted the keyword itself, replied YES from the phone, or (for imported numbers) been asked first by the consent request below.

## 1. Keyword opt-in (the resident texts first)

The resident texts the topic's keyword (for example PILOT) to +1 844 219 8901. The signed keyword callback writes the opt-in to the consent ledger first (source: keyword), creates the subscription, and replies with the 13.2 confirmation carrying the entity name and the frequency/rates disclosure:

```
Town of Pilot: You are subscribed to General Alerts alerts. Msg&data rates may apply. Reply STOP to cancel, HELP for help.
```

A duplicate opt-in is idempotent. Because the confirmation is a direct response to the resident's own text, it sends even inside quiet hours under the response rule (section 5).

## 2. Web sign-up (double opt-in)

The resident enters their number in the tenant's sign-up widget, which includes an express-consent attestation on the form. The sign-up writes the consent ledger first (source: web form, with the TCPA attestation recorded), stores the subscription PENDING — a pending subscription is in no send segment — and texts the confirmation request:

```
Town of Pilot: Reply YES to confirm General Alerts alerts sign-up. Msg&data rates may apply. Reply STOP to cancel.
```

The subscription is confirmed only when the phone itself replies YES (or texts the topic keyword), which proves the number belongs to the person; the 13.2 confirmation above is then sent. The sign-up endpoint is rate-limited per IP, an unknown or unsold tenant answers an indistinguishable 404, and a duplicate sign-up answers identically without re-texting the phone.

## 3. CSV import (consent collected elsewhere, confirmed on first send)

An administrator may import numbers whose consent was collected elsewhere (e.g., a paper sign-up sheet). The import requires an explicit consent attestation, which is refused if absent and recorded in the audit log; files are capped at 10,000 rows. Each row's ledger entry is written first (source: CSV import, the attestation in the note). Imported numbers are stored UNCONFIRMED and are never texted at import, and a number that has opted out is never re-imported over its STOP.

The first alert targeting an unconfirmed imported number does not deliver the alert. Instead the number receives the consent request, verbatim:

```
Town of Pilot wants to send you a text. Reply YES to receive it and future alerts. Msg&data rates may apply. Reply STOP to opt out.
```

The alert itself is held. A YES confirms the subscription (the ledger records the texted YES) and releases the held message; with no YES, the held message is dropped after the window (default 24 hours, tenant-configurable 1–168 hours) and a later YES confirms future sends only. At most one consent request is sent per number per window. If the first send falls inside quiet hours, the consent request is queued for quiet-hours end and the window starts when it actually sends.

## 4. Opt-out and help, handled on every message

| Resident texts | What happens |
|---|---|
| STOP, UNSUBSCRIBE, CANCEL, END, QUIT | The number is suppressed immediately; the opt-out is recorded in the consent ledger — on the shared number it is mirrored to every tenant the phone has a consent history with, because a carrier STOP suppresses the whole number. |
| START | Sending is re-enabled and recorded (mirrored the same way). |
| HELP | Reply with the entity's templated help text; the default: "Town of Pilot: alerts and notifications by Aric Software (aricsoftware.com). Msg&data rates may apply. Reply STOP to cancel, HELP for help." |
| Anything else | Logged and audited; the tenant's inbound policy applies (government tenants are provisioned with a once-per-24-hours auto-reply naming the entity, stating that the number does not read replies, giving a contact phone, and repeating STOP and HELP). |

STOPs are honored between compose and delivery: recipients are re-resolved at dispatch, so a number that opts out after a send is composed (or scheduled, or approved) is not texted.

## 5. Quiet hours and the response rule

Community sends are held during quiet hours, 8 PM to 8 AM in the tenant's local time, with no emergency override for community tenants. Scheduled sends that would land inside quiet hours are refused at compose time, never silently delayed.

The one exception is the response rule: a single-recipient message sent within 15 minutes of the recipient's own action — their own inbound text (keyword, YES, HELP) or their own web sign-up — goes out inside quiet hours as a direct response. The action is spent by one send and the exemption is audited. A night-time YES to a consent request releases the one held message it covers; the 13.2 confirmation and any older held messages queue for quiet-hours end.

## 6. Record keeping

Every opt-in, confirmation, opt-out, help reply, consent request, import attestation, and send is written to an append-only audit log; consent history is a ledger (never overwritten) and is exportable, along with subscribers, subscriptions, and held messages, in the tenant's data export. Delivery reports are aggregated from the provider's own log.
