PropFlow · ADR-0117 · PR #4449 · owner: Gera

Collections AI pilot — rent reminders that don’t annoy anyone

Prepared 2026-07-23 · from the founders call + four research passes (market, AppFolio, platform, legal) · Full spec: docs/adr/0117-collections-ai-pilot.md (PR #4449, held for Fede’s approval)

Decided on the 07-23 call: while Yale is stuck in IT review, we build a basic delinquency agent and practice at Camellia. Every serious competitor ships this and sells it hard — EliseAI claims 40–52% delinquency reduction, Entrata bought Colleen AI, RealPage ships Lumina reminders, AppFolio has RealmX flows. The read-side of our platform is already built (renewals proved it). What’s left is the outreach loop, the guardrails, and the measurement.

The one-sentence product Clara politely reminds online-portal payers at Camellia when rent is unpaid past the Colorado 7-day grace, links them to the portal, answers balance questions in their preferred language, records promises-to-pay, and escalates anything with legal teeth to a human. Sean’s tone spec is the north star: “Hey, it’s Clara — we noticed we haven’t received your payment yet, here’s a link, let us know if there’s any issues.”

Phase 0 — tenant language preference (ships first)

Fede’s call: this rolls out before any collections touch. Per-tenant languagePreference (en/es, extensible) sourced from application data, conversation inference, and PM-set overrides (Fede collected Spanish/English unit-by-unit on-site 07-21 — seed from that). Every outbound path checks it and translates before send; the mass-send composer shows the translated copy for PM review because raw MT is sometimes bad.

This isn’t just UX. English-only dunning at a heavily Spanish-speaking property is a national-origin disparate-impact risk (fair housing), and it’s the same gap that produced the English water-shutoff texts to Spanish-speaking units this week. It also benefits renewals, maintenance, and mass-send for free.

Phase 1 — who we contact (and who we never contact)

Population: Camellia residents who pay via the AppFolio online portal. Only them. Payment state is real-time, so no false “you’re late” pings while a money order sits in the office for a week. Fede’s estimate was ~40% of the building — measured 2026-07-24: 50.5% (46 of 91 current households pay majority-online); see the ledger audit below. Refresh monthly.

Camellia ledger audit — measured 2026-07-24

Every number below is 🟢 measured from the live AppFolio Data API (property 7), pulled 2026-07-24. Window: 2025-07-01 → 2026-07-24 (13 months). Sources: receivables_activity (1,618 payment txns), charge_detail (3,964 rows → 2,112 tenant rent-family charges), delinquency (79 rows). Raw pulls + analysis scripts archived in the session scratchpad; re-runnable read-only.

1 · Who actually pays online (the “~40%” check)

Payment-method mix across all 1,618 transactions in the window:

PaymentTypeTxns$ volumeClass
Money Order523$560,664Offline
eCheck469$584,470Portal
CC426$405,154Portal
Check190$299,145Offline
Flexible Rent9$11,545Third-party (Flex)
Uncategorized1$928

Per-household rollup, current-status occupancies with ≥1 payment in the window (n=91). The cohort definition matters, so here is every reasonable cut:

DefinitionShare of current households
Majority of txns online (eCheck/CC) — pilot cohort definition46/91 = 50.5%
Most recent payment was online47/91 = 51.6%
100% of txns online (strictest)30/91 = 33.0%
≥1 txn online ever50/91 = 54.9%
Zero online txns (the money-order/check population)41/91 = 45.1%
AppFolio PortalActivated=Yes59/91 = 64.8%
OptedOutOfPortal=Yes0/91
CertifiedFundsOnly=Yes (hard-excluded)2/91 = 2.2%
$ volume paid online (current households)$696,520 / $1,307,671 = 53.3%

Verdict: Fede’s ~40% estimate was low — it’s 50.5% by the cohort definition (46 households), 53.3% of dollars. The brief’s “~40–45 tenant” cohort-size assumption holds almost exactly: the pilot cohort is 46 households (44 after the 2 certified-funds exclusions). 13 more households have an activated portal but still pay offline — the conversion opportunity below.

2 · How late Camellia actually pays (rent-family charges, 13 mo)

2,112 tenant charges on rent-family GLs (Rent Income, Parking Space Rental, Pet Rent), days from charge posting (≈ the 1st) to earliest applied receipt:

Paid…ChargesShare
Day 0–7 (inside CO grace)1,17055.4%
Day 8–1437217.6%
Day 15–211436.8%
Day 22–301044.9%
Day 31+25312.0%
Still open / partial703.3%

The same distribution split by pilot-cohort membership — this is the number pair that actually sizes the pilot:

Pilot cohort (online-majority, Current)Non-cohort (offline / past)
Rent charges · households809 · 461,303 · 111
Paid in grace (day 0–7)79.9%40.2%
Day 8–147.5%23.9%
Day 15–212.7%9.3%
Day 22–303.1%6.1%
Day 31+5.8%15.8%
Still open / partial1.0%4.8%
Past day 8 (trigger rate)20.1%59.8%
$ collected by day 8 / 15 / 2280.1% / 87.0% / 90.4%42.1% / 67.4% / 77.0%
Days-to-receipt p50 / p90 / p951 / 17 / 339 / 42 / 60
Households ≥6 charges: never late · 6+× late20 · 11 (of 43)10 · 50 (of 80)

3 · Expected reminder volume (backtest of the day-8 trigger on the pilot cohort)

Distinct cohort households whose rent-family charge was still unpaid at day 8, per month — i.e. who would have received a day-8 reminder had the pilot been live:

MonthCohort triggeredCohort rent-$ lateNon-cohort triggered
2025-078$9,77334
2025-087$8,73449
2025-097$9,16553
2025-108$9,64437
2025-117$9,26543
2025-128$8,12537
2026-017$8,04043
2026-0211$12,58039
2026-0310$12,02540
2026-0415$15,56044
2026-0511$11,46036
2026-0610$12,34539
2026-0712$12,46035

4 · Delinquency snapshot (as of 2026-07-24)

5 · 10-day demands actually served (mailbox census, 2025-07-24 → 2026-07-24)

Source: read-only Microsoft Graph sweep of the camelliaapts@jp-co.com mailbox — the demand traffic with the eviction firm Tschetter Sulzer Muccio PC (TSM). AppFolio's Data API exposes no notice/eviction surface at all (33 candidate report endpoints probed, all rejected), so email is the only system of record. Tenant names withheld here (units only); the full machine-readable census lives in the session scratchpad.

6 · Data-quality findings that change the build

Cadence — the “not annoying” contract

Max 3 touches per resident per month — well under the Reg F 7-in-7 cap we self-impose. Stop instantly on: applied payment, promise-to-pay (one polite check-in if the date passes unpaid), opt-out, dispute (→ human), PM pause. Suppression re-checks the ledger at send time, not enqueue time. Quiet hours 8am–9pm resident-local enforced in the dispatcher. Tone adapts to history — first-time late gets the softest copy, chronic late gets neutral-firm, never harassment-adjacent — and the whole tone bank goes through promptfoo evals before launch.

Channels: SMS + email only. No outbound voice in the pilot — the FCC treats AI voice as “artificial voice” (highest consent bar), and the Camellia TFN has a T-Mobile block anyway. Disclosure-forward: first contact in any thread identifies Clara as Camellia’s automated assistant with an easy human handoff. EliseAI does the opposite (human name, disclose only if asked) and a National Housing Law Project litigator publicly called that “unfair and deceptive” — we make transparency the feature.

Human-in-the-loop boundaries

Clara may (autonomous)Clara may never
Send cadence reminders · answer balance/lease questions in any thread · record promises-to-pay · surface the portal pay link · escalate Mention or threaten eviction, legal action, or credit reporting · state a late fee that isn’t posted + lease-valid + cap-compliant · offer/accept payment-plan terms (pilot: plans are drafted suggestions to the PM from a pre-approved menu; a human sends and enters them in AppFolio) · waive anything · contact guarantors · serve, send, or sign a 10-day demand (drafting one for human review is planned — see the demand section, hard-gated behind /review)

Escalate to PM on: dispute, hardship mention, opt-out, promise broken twice, day-22 reached, any eviction/legal question, any conversation the agent can’t hold in the tenant’s language.

The 10-day demand — as-is workflow, the law, and Clara’s role

Added 2026-07-24 from two parallel deep-dives: a read-only Graph sweep of the Camellia mailbox (the real demand traffic with TSM), and primary-source legal research (C.R.S. §§ 13-40-104/106/108, 38-12-105; JDF 99A rev. 2025-09-04; HB23-1120 / HB24-1098 / HB25-1240). Not legal advice; counsel sign-off required before any of Clara’s demand-adjacent behavior ships.

How the team does it today (reconstructed from the mailbox)

  1. Decide: the PM team tracks delinquents in “deliq update” threads; Kenya owns the relationship with the eviction firm (Tschetter Sulzer Muccio PC, client ID 54784).
  2. Prepare by hand: the on-site team fills the TSM-provided “Denver Demand for Compliance or Possession” (current rev 01.01ABDen 08/22/25 — a 9-page packet: fillable demand + return-of-service + Government Assistance Affidavit + the mandatory Denver Tenant Rights & Resources pages). It IS a fillable AcroForm — but today it’s filled with pen and scanned.
  3. Serve — the property itself serves, not the firm: a staff member personally delivers (or posts after two failed attempts on separate days) and completes the return-of-service block.
  4. Wait 10 full days; if uncured, scan the served demands and email them to TSM’s intake (Zendesk ticket, 3–4 business-day SLA).
  5. TSM legal-reviews and files the eviction (Summons & Complaint, Denver County) — or bounces the demand as defective, which restarts everything including re-service.

Reality check from the census (audit §5): ~6 batches/year, 2–6 demands each, ~16 households. The single biggest failure: date math — one whole batch of 4 was voided for a 9-day pay-or-vacate window, weeks lost. And 4 of the 46 pilot-cohort online payers were served a demand this year (units 118, 410, 122, 620; two escalated to real eviction filings) — demand territory is not disjoint from Clara’s cohort, so the boundary rules below will actually fire.

What the law requires (verified against current statute + the official form)

Clara’s role — proposed, counsel-gated, and 100% behind the /review queue

Hard gate — nothing here is autonomous This is the most delicate surface in the pilot. Every demand-adjacent action routes through the PM review queue (/review — the typed proposed-mutation inbox Gera built; tenant-confirmation and vendor-outreach are the existing types) as a new review type, and executes only on explicit PM approval. Initial rollout: Clara proposes, a human approves and acts, every time — no exceptions, no auto-send even for the pre-demand warning. Loosening any of this requires counsel sign-off + Fede/Sean explicitly un-gating it.
  1. Demand drafting (“Clara fills the PDF for the team”): Clara populates the current Denver demand AcroForm from ledger + tenant data — occupants, unit, base-rent-due with missed months, pay-or-vacate date, community fields — and emits a print-ready PDF into a /review item alongside the evidence (ledger snapshot, language preference, affidavit checklist). The killer feature is the date math: a computed, guaranteed-compliant PVD (≥10 full days from day-after-service, with the service-date entered by the human server), eliminating the failure mode that voided the whole April batch. PM approves → prints → signs → serves. Clara never signs, never serves, never emails a demand to a tenant.
  2. Pre-demand warning (“should Clara warn them?” — yes, narrowly): lawful as a disclosed first-party agent IF factual, rent-only, non-certain (“a formal 10-day demand may be the next step”), and only when JP actually intends to proceed. Design: fires only at the day-22 escalation stage, drafted by Clara but held in /review for PM approval before send during initial rollout; suppressed entirely for any tenant with a disclosed SSI/SSDI/Colorado-Works status, subsidy tenancy, active dispute, or existing served demand. The word “eviction” stays out of Clara’s vocabulary — “formal demand” is the ceiling.
  3. Cure-clock + packet tracking: once a human records service (date/method/attempts), Clara tracks the 10-full-day clock, reminds the team the day it expires, pre-fills the return-of-service data for the server to sign, and assembles the scan-to-TSM packet checklist (signed demand + return of service + tenant-rights pages + affidavit). Kills the second failure mode: premature or sloppy submissions.
  4. Suppression feedback loop: a served demand immediately hard-stops all cadence messaging for that tenant (it’s an active legal process — reminder copy could contradict the demand); cure/payment restores normal state.

Not doing, ever (this pilot): electronic “service” of anything; auto-sending warnings without review-queue approval; stating amounts that include late fees; contacting anyone post-filing; drafting anything for the court stage (JDF 101/102 is TSM’s job).

Open items for counsel: rent-only vs. Denver’s “other amounts” block; first-party status of Clara’s messaging (the pivotal classification); HB25-1240 effective date + covered-dwelling scope. Open item for Fede: confirm who signs/serves on-site today (the served scans show a signer whose name doesn’t match our team roster — verify before wiring the signature workflow).

What the platform already has vs. what you’re building

Already built (reuse, don’t rebuild)

Net-new build

  1. Adapter reads: wire the AppFolio delinquency report — AppfolioDelinquencyRow (integrations/appfolio/types.ts:351) is fully typed (PaymentPlan, InCollections, NSF, LateCount, LastPayment…) but nothing calls it — plus payment history (receivables_activity/charge-receipt join). Through getPMSClient only; add to the domain interface so Yardi/RealPage can implement later.
  2. CollectionsCase per tenant-month: ELIGIBLE → REMINDED_1..3 → PAID | PROMISE | ESCALATED | SUPPRESSED, full audit trail (message, timestamp, channel, ledger snapshot behind every stated balance). Keep ≥ 4 years. Plus a PromiseToPay record (amount, date, kept/broken).
  3. Temporal cadence workflow — same doctrine as renewals (ADR-0108); remember the 05-26 SQS-bypass incident. Send-time suppression re-read.
  4. Tool upgrades: real lastPayment* (currently hardcoded null, handle-get-tenant-balance.ts:37-41) and bucket-aware daysDelinquent (currently assumes due-on-the-1st).
  5. Language preference field + translation layer + mass-send review UX (Phase 0).
  6. PM surface: collections cases on a simple list + per-unit opt-out picker; a per-tenant AR view can come later.

AppFolio mechanics that shape the design

Legal — verdicts and hard constraints

Research 2026-07-23; counsel sign-off required before go-live. Not legal advice.

RegimeVerdictWhat it means for the build
FDCPA / CO CFDCPANot bindingWe’re a first-party landlord collecting current-resident rent. Two trap doors: never present as a third-party collector (always “Clara at Camellia Apartments”), and never chase debt acquired already-in-default. Counsel must confirm the JP-Co/owner entity structure keeps this first-party.
CFPB Reg FAdopt anyway7-in-7 caps don’t bind first parties — we self-impose them (our ceiling is 3/month) plus a cooldown after any live payment conversation.
CO late fees
§38-12-105
Hard lawFee = greater of $50 or 5% · ≥7-day grace · must be in the lease · one fee per late payment · no fee-on-fee · payments apply to rent first · notice within 180 days · no eviction for unpaid late fees. $50/violation + CCPA deceptive-practice exposure. Clara never states a fee that violates any of this.
CO eviction
§13-40-104
Hard lawNonpayment needs a written 10-day pay-or-quit demand; cure kills the notice. Clara never implies eviction is imminent — the word doesn’t exist in her collections vocabulary this pilot.
TCPA / FCCHard lawNumber-on-the-lease = consent for transactional debt contact (email consent ≠ SMS consent — ask before texting email-only residents). Quiet hours 8am–9pm local. Opt-out by any reasonable phrasing, honored ≤10 business days, cross-channel — the agent needs an explicit opt-out tool, not just STOP webhooks. AI voice = “artificial voice” (why voice is out). Register collections as its own transactional 10DLC campaign. Keep consent/opt-out records ≥4 years.
CO AI ActNot in forceSB24-205 repealed; SB26-189 disclosure duties start Jan 1 2027. We disclose anyway — UDAP hedge and brand position.
Fair housingHard lawIdentical cadence/tone/escalation for all similarly-situated residents; monthly audit of outcome distributions; don’t penalize benefit-cycle payment timing; language access (Phase 0).
Payment plansCarefulAccepting partial rent can waive eviction rights on a notice → counsel-approved reservation-of-rights template; plans only from the pre-approved menu; written confirmation of every plan.

Market notes worth stealing (and avoiding)

Measurement — proving we reduce delinquency

Lock the baseline before the first send: 12 months of charge_detail history. The portal cohort is 46 households (44 after certified-funds exclusions) with only ~9.3 day-8 triggers/month (audit §3), so month-one truth is direction + case narratives, not p-values — report absolute numbers. Baseline must be the trailing-6-month per-tenant window, because cohort lateness has been worsening since Feb 2026 (7–8 → 10–15 triggers/month) and a 13-month average would flatter the pilot’s starting point.

Suggested build order

  1. Phase 0 language preference + translation review in mass-send.
  2. Adapter reads (delinquency report + payment history) → cohort query with all exclusions. Portal-payer share is now measured (50.5%, 46 households — see audit); productionize that query (majority-eCheck/CC over trailing 13 mo, minus CertifiedFundsOnly/Flex) and refresh it monthly. Do NOT read delinquency.LateCount — it’s zero for everyone (audit §5); compute lateness from charge_detail.
  3. CollectionsCase/PromiseToPay + Temporal cadence with send-time suppression; tone bank + promptfoo evals; opt-out tool.
  4. PM surface (case list + unit opt-out) + 10DLC campaign registration + carrier smoke test.
  5. Baseline lock → counsel review of tone bank → live on the cohort. Test Property (ID 45) or log-mode only until launch day — no real comms in test runs.
  6. Demand assist (parallel track, counsel-gated): new /review item types (demand draft, pre-demand warning, cure-clock expiry) on Gera’s review-queue primitive → AcroForm fill of the current Denver demand + compliant-PVD computation → cure-clock/return-of-service tracking → TSM packet checklist. Ships nothing tenant-facing until counsel signs off on the warning copy and the rent-only amounts question. See the demand section.
Deferred — each un-gates only with counsel + Fede/Sean sign-off Guarantor contact · self-service payment plans · outbound voice · anything post-resident · any demand-adjacent action leaving the /review gate. (10-day-demand drafting is no longer deferred — it’s now a planned, counsel-gated, review-queue-only workstream: see the demand section.)

Sources: founders call 2026-07-23 (raw transcript) · EliseAI/competitor research pass · AppFolio KB pass (help-articles + Data API) · repo capability inspection (paths cited inline) · first-party collections legal research (CO/TCPA/FDCPA/Reg F) · Camellia ledger audit 2026-07-24 (live AppFolio Data API: receivables_activity / charge_detail / delinquency, property 7, 2025-07-01→2026-07-24). Full citations live in ADR-0117 and the research reports behind it. Vendor metrics are marketing claims, not benchmarks.

PropFlow Docs