Live tracker

Yale 25 Station — Onboarding Tracker

Internal engineering tracker for the CONAM → PropFlow onboarding. Client-side items live on the onboarding doc’s checklist. Statuses here save for everyone; the full migration & cutover plan from Aug 25 is kept underneath as reference.

Started 2026-08-25 · restructured 2026-08-27 · prod-audited 2026-08-31 · Yardi pivot 2026-09-16 · owner: Fede · engineering: agents/006 · client doc: Onboarding (its checklist tracks the CONAM-side items)

Where this stands — 16 Sep (ConAm is leaving RealPage for Yardi CRM IQ; researched, see the Yardi section below)

Where this stands — 31 Aug (audited against production)

Phase 0 · Client packet0 / 0
Phase 1 · Sandbox0 / 0
Phase 2 · Config model0 / 0
Phase 3 · Quiet mode0 / 0
Phase 4 · Turn on leasing0 / 0
Phase 0

Client packet

client-side items live on the onboarding doc · nothing changes in prod

The four CONAM-side items (RealPage user, lead-source answers, calendar consent, Yardi report) are tracked on the onboarding doc's own checklist — not here. This page is the internal engineering tracker.

StatusItemOwnerEvidence
Onboarding doc for CONAM IT (web + PDF)v5, 28 Aug (Fede full review): access items vs one go-live step, open questions answered inline, mailbox read+send added back (analytics / future use), gated link — email gate is the view tracking, no password by ruling.Fededoc
Packet sent to CONAM with a named IT contact requestedEmailed to Dara Johnson and team 28 Aug on the Yale 25 roll-out thread, with the gated onboarding link and a request for a direct IT contact (in-person offered).Fedesent 28 Aug
Which RealPage system Yale is onILM Lead Manager — confirmed by Fede, 28 Aug (matches the Zillow tracking-number test and the on-site notes).FedeILM, confirmed 28 Aug
Phase 1

Sandbox practice round

this week · yale-sandbox only · Camellia untouched

Rehearse the whole Yale operating model on the isTest sandbox (org_sandbox) with harnesses, before any of it touches the real property. Every item proves on the sandbox first.

StatusItemOwnerEvidence
Sandbox phone line: local Twilio number bought, wired, mappedVoice → the prod Clara Triage agent, SMS → the prod webhook, attached to the verified A2P campaign, mapped to yale-sandbox in the phone→property map.Eng+1 719-601-1047 wired, mapped and deployed 27 Aug
Sandbox inbox liveDONE overnight 27→28 Aug: machine receive rides an SES rule on inbound.propflowai.co (yale25-sandbox@inbound…, additive rule, root MX untouched); SendGrid sends the property-branded replies. Real Gmail → sandbox → branded reply in 31s, honest about missing pricing. Cleanup owed: remove the bounced root probe (yale25-sandbox@propflowai.co) from SendGrid suppression before that address ever receives. Public yale25@ needs Fede’s Google alias (morning gate).Engproven live, e2e
Sandbox isolation gaps closedShipped overnight; sweep windows show 0 Camellia and 0 real-Yale activity.Engmerged overnight
ILM simulator (from the research spec)Shipped overnight — guest cards, auto-responder, opt-in flow, per-source switches with the 24–48h lag, dedupe, assignment.Engmerged overnight
Lead-by-email harnessShipped overnight (two-channel harness with a shared skeleton), plus a live proof: a real Gmail lead became a conversation and got a property-branded reply.Engmerged overnight + live e2e
Lead parser: Apartments247 + Zillow-direct first-classRescoped 27 Aug: RealPage is what we’re replacing, not a lead source — Apartments247 (the website host’s emails) and Zillow-direct are first-class parsers; RealPage-sender detection stays only as a drain-window safety net. (Recognized today: 8 aggregator domains + AppFolio; apartments247.com missing.)Eng
Outcomes-only notifications for the PMShipped overnight and ARMED on the sandbox (pmNotificationMode=outcomes_only): tour outcomes + coworker asks. CORRECTION 2026-08-31 (Fede): “application sent” is NOT an outcome — it is Clara’s routine work, and the PM email for it was a bug. Removed globally (PR #6733); no PM email fires when Clara sends an application link.Engmerged + armed on sandbox
Voice + SMS end-to-end on the sandbox lineFirst pass 27 Aug on real cloned Yale data: booked, rescheduled and cancelled a tour by text. Findings: (1) the mid-thought “Also —” reply — root-caused and fixed (a dropped pre-tool draft met a forward that reached nobody; the honest template now wins); (2) the escalated thread going silent is Fede’s Aug-20 rule working as designed — whether tour booking should still proceed is Decision 11; (3) Saturday accepted because the scraped office hours say Sat 9–4 while the site header says weekdays — confirm with the PM.Engack fix in PR · D11 pending · Sat hours to confirm
Camellia regression gateFull leasing suite green + a drift test proving no Camellia setting or behavior changed. Runs on every PR in this program.Eng
Phase 2

Configuration model — operating modes

design first · then build behind flags

Turn the Camellia-shaped assumptions the audits found into per-property settings, so the third property is a config change, not a fork.

StatusItemOwnerEvidence
operatingMode / connectionMode on the Property recordShipped overnight with the inbox→conversation lane (dual-gate armed per D9).Engmerged overnight
Per-property sending identity for the no-mailbox caseShipped overnight: sending identity + inbound addresses live on the Property record (envelope-recipient routing); sandbox configured.Engmerged overnight
Phone→property map as data, not codeBuilt overnight, PR green except one stuck CI check (re-run queued); merges this morning.EngPR open, green pending re-run
Gate AppFolio tools by pmsSourceClosed by verification, 27 Aug overnight fleet: AppFolio tools are already PMS-gated (PMS_MISMATCH) — the audit line was stale; no build needed.Engverified already gated — no work
One timezone fallbackIn the same open PR as the phone map; merges this morning.EngPR open
SMS consent mode per propertySingle opt-in (STOP on every message) vs ILM-style double opt-in. Check /tcpa before changing any send behavior. Decision D7.Eng
Multi-role escalation routingLeasing questions → leasing assistant first, PM fallback; first time the system routes by role. Decision D8.Eng
Settings UI for the script-only fields — and one “who gets Clara’s questions” fieldescalationOwnerEmail, smsShadowMode, leasingActivityChannel have no operator write path today; and three different fields (propertyEmail, renewalContactEmail, escalationOwnerEmail) decide who hears a forward — collapse to one per role (D8).Eng
Phase 3

Yale quiet mode

real property · connected · nothing sent

Connect the real mailbox and calendar, watch real guest cards through the ILM user, and let the PM review what Clara would have said for one to two weeks.

StatusItemOwnerEvidence
Prod test data cleaned95 test rows deleted 27 Aug with a backup first; the test calendar connection removed and the office phone restored on the Yale record.Engdone 27 Aug
Yale config verifiedDone 27 Aug: test calendar disconnected, office phone back to (303) 395-9448, shadow modes on. Still to set: escalationOwnerEmail AND propertyEmail (the “forward to the manager” email picks its recipient from propertyEmail / renewalContactEmail, not escalationOwnerEmail — real Yale has none of the three), applicationLink = on-site.com, timezone check.Eng3 of 7 settings verified
PM calendar connected + prod Yale address liveCalendar: after IT consent, the PM connects from /settings in under a minute. Email: yale25@propflowai.co (root domain, final ruling 27 Aug) as a per-property sending identity — no Microsoft seat; Camellia’s Graph mailbox becomes one mode behind the email-channel adapter.Fede
ILM user in hand — observe guest cardsWhich creation paths produce leads, what the confirmation email looks like, whether “Lead Management” is on, the live adsource list.Fede
Rent roll ingested + pricing scraper armed115/115 leases; on-site.com pricing scrape confirmed running; placeholder roll retired.Eng
Shadow review sign-offPM reviews every draft for 1–2 weeks; zero misroutes; tour context complete on calendar events.Fede
Phase 4

Turn on leasing

source repoint · rollback rehearsed

Clara owns new leads end to end: phone, Zillow email, texts, tours and their changes; applications tracked in ILM; lease-signed as a bonus.

StatusItemOwnerEvidence
Migrate open guest cards + history into PropFlowVia the ILM user; in-flight conversations stay with the team until they resolve (Decision D4: drain).Eng
Repoint Zillow (phone + email) and the website formPer Decision D1. Expect 24–48h propagation; Zillow retries failed deliveries, so a brief mistake is recoverable.CONAM
Rollback rehearsed oncePoint one source back and confirm it lands in ILM again within the propagation window.Eng
First week live: response time, tours, escalations, weekend coverageMetrics on the Yale dashboard; every conversation reviewed daily for the first week.Fede
Application → lease status loopRead applicant/lease status through the ILM user so Clara stops chasing people who already applied. Bonus: lease-signed.Eng

Yale end-to-end test grid — real mode

Ruled 31 Aug (Fede): synthetic tests run on all channels in REAL mode (quiet mode off for the test window; nothing external points at Yale email yet, the phone line already answers live). Every permutation below gets an explicit PASS/FAIL with evidence before Fede does his own hands-on pass. Robot/test rows are kept until the whole grid is done, then one sweep deletes them plus everything the grid created. Statuses update here as each test runs.

#ChannelTestProvesStatusEvidence
E1EmailOutside lead email arrives at yale25@propflowai.coReceive route delivers; an inquiry + prospect are createdPASS31 Aug 20:15Z: synthetic Gmail lead ("Sam Whitfield", 2BR, November) → prospect + email conversation in 13s, bedrooms/move-in parsed correctly, topic labeled "leasing", reply drafted-not-sent (quiet mode held). First attempt bounced until the mail server's accept list got the Yale address (fixed). Draft CONTENT under review → see E4.
E2EmailClara replies for realSend path works; from "Yale 25 Station Leasing <yale25@propflowai.co>"; lands in the sender's inbox (not spam)PASS31 Aug 20:58Z: real reply delivered to the lead's Gmail in 24s — From "Yale 25 Station Leasing <yale25@propflowai.co>", Reply-To correctly the machine inbox (the reply-routing fix, proven live; one earlier send raced the deploy and carried the old header). Honest tour wording ("request in… team will confirm").
E3EmailLead replies againThreading: the reply joins the same conversation, Clara keeps contextFAIL31 Aug: a threaded reply (proper In-Reply-To headers, sent to the Reply-To address) opened a NEW conversation instead of joining the thread — one lead now has 4 separate conversations. Identity/context survive at the person level (Clara knew the Saturday tour, declined Sunday correctly, offered Tuesday), but the thread fragments for the PM. Filed on the board.
E4EmailLead asks the rentPlaceholder-data gate holds on the email path: honest deferral, no fake numberPASS (after fix)31 Aug, traced to code: the tour pipeline pre-loads "available units" into Clara's context from the RAW units table — a third path the data gate never sees. Clara quoted placeholder rents ($1,830/$2,055) instead of the same-day scraped real ones ($1,865/$1,795) — one unit 14% high. The 50%-off special she mentioned IS real (scraped from Yale's site today). Fix merged + deployed same evening; retest 21:17Z quoted the REAL prices exactly ("Unit 217 — $1795/mo, Unit 201 — $1865/mo"). Caught and fixed inside one test window — no renter ever saw a wrong number.
E5EmailQuestion Clara can't answerEscalation forward reaches the (newly set) escalation addressPASS31 Aug: PASS — Clara said "I'll check with the team" on the pet/1BR question and a real coworker-ask email ("Are there any 1-bedroom units currently available at Yale 25 Station?") landed in Fede's inbox from Clara, delivered (SendGrid-verified). A second ask from the Spanish robocall arrived too. (An earlier "no forward seen" read was a wrong-mailbox check on our side, corrected.)
E6EmailPublic address yale25@propflowai.co (send + reply)Mail to the public address reaches Clara; her reply comes from it; a reply to her reply is answeredPASS2 Sep 9:25pm MT: Google recipient-address-map rule (yale25@ → machine inbox) live; inbound matched Yale in 5s, reply delivered from "Yale 25 Station Leasing <yale25@propflowai.co>" with Reply-To on the same clean address; the prospect's follow-up reply was answered in 15s. Google Group approach rejected (mandatory unsubscribe footer poisoned sender detection).
S1SMSInbound text to the Yale numberConversation created; real reply sent from the Yale numberPASS31 Aug 21:0xZ, real text from a clean unmapped test number: correct 2BR answer texted back, conversation created at Yale. Caveat: no prospect card was minted for the SMS-only lead (carded).
S2SMSBook a tour by textTour created; honest wording (proposed vs confirmed); confirmation text arrivesPASSTour booked by text ("Jordan Meyer", Wed 3pm): tour row created as proposed, wording honest ("team will confirm shortly"), no false confirm.
S3SMSReply STOPOpt-out honored; no further sendsPASSSTOP → immediate unsubscribe confirmation; a follow-up message got silence. Opt-out recorded and honored.
S4SMSAsk the rent by textPlaceholder-data gate holds on the SMS pathPASS"How much exactly?" → "unit 201 at 922 sqft for $1,865/mo, unit 217 at 946 sqft for $1,795/mo" — the REAL scraped prices, quoted AFTER the gate fix deployed mid-test. Text path clean post-fix.
S5SMSRobot's queued follow-up textsQueued cadence inventoried BEFORE un-mute; fires deliberately or is cancelled — never by surprisePASS31 Aug prod read: the robot's 4-touch cadence self-cancelled 4s after the call ended (call-ended reply bridge, by design); zero touches sent or scheduled; full scan of Yale's rows found NO other pending outbound. Un-mute fires nothing.
V1VoiceInbound callAnswered as Yale 25 Station (right property, right greeting)PASSRobot: "Hi, is this Yale 25 Station?" → "Yes, it is." Right property, no Camellia bleed.
V2VoiceBook a tour on the callTour created; "confirmed" said only when actually confirmedPASS"Riley Cooper" booked a 2BR tour; Clara said the team will confirm shortly — DB row is "proposed", wording matched reality (the Aug-26 honesty fix, proven live).
V3VoiceHang up, call right backReturning caller recognized — live re-proof of the fixed identity bugPASSSame caller rang back 2.5 min later: "Hi, Riley" + exact tour details. The fixed identity bug re-proven live.
V4VoiceReschedule the tour by phoneExisting tour moved, not duplicated; no "no prospect found"PASSSame tour id moved Mon 4pm → Tue 2pm, no duplicate, still honestly "proposed".
V5VoiceSpanish callFull conversation in Spanish, no language flipsPASSFull conversation in natural Spanish, no flips or resets.
V6VoiceAsk the rent on the phonePlaceholder-data gate holds on voice (its original home)PASSQuoted $1,795 and $1,865 — the REAL same-day scraped rents, not the placeholder numbers. Voice path gates correctly; the bug is email-preload-only.
V7VoiceCall after hoursMessage taken instead of dialing a closed officePASS3 Sep 7:06pm MT (re-test after the fix, EL conversation conv_1801m1mz7g2df6nbqspyc6zwnek5, prod voice conversation conv_voice_a3d948e1-95b5-493c-a9e7-b17aea44e0ed, property 1773625952029): PASS. Same opening as the failing call — prospect "Morgan Lee": "Can you transfer me to someone in the office right now?" — plus two escalating follow-ups ("I'd really rather just speak to a person, can you put me through?" and "It's important, I'd like to talk to someone tonight"). Clara answered all three with the closed-office line and never dialed: transfer_to_number did not fire, capture_unknown_caller_note did, and she never said "connecting you". Her words on the third ask: "I completely understand, and I'm sorry I can't make that happen tonight — the office is closed and there's no one available to pick up right now. I'll make sure your message gets to the team so they can reach out first thing during business hours." The greeting was clean too: "Hi Riley, it's Clara at Yale 25 Station — I'm on it. I've got your question with the team, and you'll get a text as soon as they've answered."

Earlier attempt, 3 Sep 5:25pm MT (conv_7401m1msem4xed8ae2e8c7fxnq7b / conv_voice_b4bda8d6-5eac-4d06-bb9a-327629d1c723) — FAILED: Clara said "I hear you... Let me connect you with someone on the team" and dialed +1 303 395 9448, which nobody answered. The 30 Aug closed-office rule was already live and correct; it lost on position and form — it sat at character 35,842 of an 89,128-character prompt and asked the model to run a two-flag check on the turn a caller demanded a transfer. The fix moves the verdict to the server: the office-closed question is now answered before the call starts and injected as an unconditional standing order at the top of the prompt, and as nothing at all during business hours. The same call also exposed the garbled greeting ("I've got your question about Clara told the caller…"), caused by the spoken topic falling back to an internal narrative field and then being truncated mid-quote; the greeting now only ever says a short, clean version of the caller's own question, or no topic at all.
X1CrossCall, then text from the same numberSame person recognized across channels — one conversation historyPASSProven live (accidentally but genuinely): a text sent from the voice-test caller's number merged into that caller's existing conversation and got a coherent reply — same number, same person, one history across channels.
X2CrossTour booked on voice → confirmation textChannel hand-off: the booking triggers the SMS confirmationFIX DEPLOYED — live proof = Fede's call31 Aug FAIL → root cause found and FIXED 1 Sep (merged + deployed): the code treated "no calendar connected" the same as "calendar write failed" and silently downgraded every auto-confirmed voice booking back to proposed — so the confirmation text (which only sends for confirmed tours) never fired. The 1 Sep live retest came back unchanged BUT hit the wrong path: the test number already owned a tour, so the call became a reschedule — and a rescheduled tour goes back to "proposed" on purpose (Aug 22 incident: auto-reconfirming a moved tour armed reminders for a slot nobody approved). Fresh-booking behavior is proven by the fix's merged tests; the live proof is Fede's own hands-on call from a fresh number — book a tour, expect "confirmed" spoken and a text received.
X3CrossVoice conversation gets a topic labelSettles the stale "no labels" audit claim with a live rowPASSAll five of today's robocall conversations carry topic labels in prod ("leasing"; the greeting-only call correctly "none"). The Aug-25 "no labels" audit claim was stale.
C1CalendarConnect test calendar; book a tourEvent appears with prospect details; tour auto-confirms against a clean slotPENDINGneeds a Microsoft account — Fede gate
C2CalendarBook into a busy slotConflict detected; alternatives offered instead of double-bookingPENDING

Bugs found by the grid (beyond the pass/fail criteria): (1) Cross-property caller-identity bleed — the test robot's phone number is known as a maintenance vendor at the Willows test property, and Yale's Clara opened one call with "is this the Willows Maintenance? It's Clara at Yale 20 Station…" referencing a fake ticket, before recovering. Wrong property, wrong self-name, phantom ticket — a real caller whose number exists at another property could hit this. No bad data was written. (2) Garbled openers on two callback calls — Clara read internal instructions aloud ("Clara told the caller the team will confirm…") instead of speaking naturally. Both filed as Trello cards; neither blocks the grid.

Prerequisites — status 31 Aug PM: yale25 email PROVISIONED (machine inbox yale25@inbound.propflowai.co registered on the property AND added to the mail server's accept list — the first test mail bounced 550 because the AWS receive rule enumerates addresses, not the whole subdomain; new additive rule "yale-inbound" mirrors the sandbox rule; sender identity "Yale 25 Station Leasing" <yale25@propflowai.co>; inquiry pipeline armed Yale-only) · escalation/property email SET (fede@propflowai.co, test-window value) · queued-sends inventory DONE (nothing queued — see S5) · reply-routing PR in flight (replies to the pretty address would bounce until it lands; blocks E2/E3) · test calendar (C1/C2) still needs a Microsoft account — Fede gate · Google alias for direct mail to yale25@propflowai.co — Fede gate. Quiet mode flips OFF only when the reply-routing PR is merged. After the grid: Fede's hands-on pass, his call on whether real mode stays, then one cleanup sweep (robot rows inventoried: person, claim, inquiry, tour, conversation + 18 messages — IDs on file).

Decisions

Open conflict — Decision 1. Fede re-picked all sources at once on 27 Aug, but the access doc for CONAM still says one source at a time (safer with the 24–48 h propagation lag per source). Yale has only two sources, so the practical gap is one review window. Say the word and the doc gets re-worded.

Decision 1 · Cutover style

In plain terms

The listing sites are doors; today every door leads to RealPage's desk. We can re-hang one door at a time to lead to Clara, and hang any door back the same day. One door, all doors, or none yet?

Decision 2 · Sending identity

In plain terms

Whose name is on the envelope? An address that reads as the property's leasing office, on our mail system so replies come back to Clara. Renters already get Yale's mail from a system address today.

Industry evidence (2026-08-25):
  • the incumbent vendor sends from its own vendor domain across every PMS it integrates ("We do not use the email address you specify" on the CRM user; ILSs redirected to its portal-generated address; zero client-DNS steps in 12+ onboarding docs).
  • Only the PMS platforms use client-domain delegation (conam.com's own SPF authorizes Yardi's mail servers) — the AI layers on top don't.
  • ILS relays trained renters on platform-domain senders (zms-1234@reply.zillow.com).
  • No industry buys client-lookalike domains — that shape is the phishing signature detectors target (Proofpoint/Abnormal). ESP fallbacks without client DNS are always platform-owned addresses.
  • Legal: CA bot law + Colorado AI Act (delayed to 2027-01-01) require in-conversation AI disclosure, not any sender-domain property. Action: Clara discloses AI in-conversation; flag for counsel.

Implementation ruled 27 Aug (Fede, overnight session: “i like this” · “dont tie yourself to whatever camellia has” · “i want the best possible cleaner long term solution”): SendGrid for sending (per-property identities on the root domain — final address ruling 27 Aug: yale25@propflowai.co, display “Yale 25 Station Leasing”; the leasing. subdomain plan is dead) + the existing AWS SES receive path (already wired end to end: SES → S3 → forwarder → queue → ingest; today it files leads without acting — the overnight build turns that into inquiries). No Microsoft 365 seat (that purchase gate is dropped); no new vendor to operate, and root-domain receive rides the existing route so no DNS/SendGrid/Cloudflare writes were needed. A later SendGrid-receive migration is documented, not built (a root MX move would also move rent-roll/report intake). Camellia’s Graph mailbox keeps working as one per-property mode behind a new email-channel adapter. Note: the overnight session’s verification corrected the literal “SendGrid both directions” — SendGrid does not receive anything today — and flagged the wording deviation to Fede.

Decision 3 · ILM/RealPage access ask

In plain terms

Clara needs a login to see who applied and who's renewing. The biggest vendor in the space gets it by asking plainly — the client creates a user account for the AI. Ask the same way.

Decision 4 · In-flight ILM leads at cutover

In plain terms

On day one some people are mid-conversation in the old system. Either the PM finishes those few while Clara takes everyone new — or we copy them by hand and risk a renter hearing from two places at once.

Sources: Aug 24 on-site raw transcript + team call · Jul 22 rollout meeting · Jun 17 discovery call · Jul 1 RealPage call · codebase audit · verified vendor/ILS documentation + DNS records · Twilio account state (Aug 25). Unconfirmed figures are labeled in place.

Decision 5 · Where Zillow and website leads are delivered

In plain terms

Whose front door do the leads knock on? CONAM’s own mailbox (we already know how to answer that door) or a door we own (we’d have to build it).

Decision 6 · What the property manager hears from Clara

In plain terms

How much of Clara’s work should land in the manager’s inbox: just the results, everything, or a daily summary?

Decision 7 · Texting consent at an enterprise property

In plain terms

ILM makes every lead say “yes” before anyone can text them. Do we keep that extra step, drop it, or make it a switch per property?

Decision 8 · Who answers Clara’s questions at Yale

In plain terms

When Clara needs a human — “is unit 204 pet-friendly?” — who gets the text first?

Decision 9 · How “operating mode” is modeled

In plain terms

Do we give each property one switch that says how it works (corporate-managed, centralized, on-site), or keep stacking little switches?

Decision 10 · Which organization Yale 25 Station lives in — DECIDED 27 Aug: stays in JPCO

Considered moving Yale into its own CONAM organization (ADR-0019 defines an org as the operating company whose staff log in). Fede reversed it the same hour on learning the side effect: JP&Co leadership would lose the single view across Camellia + Yale, because no cross-organization owner/portfolio view exists yet. Ruling: Yale stays in JPCO; CONAM staff are isolated by per-property scoping. Revisit only if an owner-across-orgs view ships. (Third time this has been decided the same way: Aug 24 Fede, Aug 25 Gera, Aug 27 Fede.)

Decision 11 · Should Clara still book a tour while a question is waiting on a human? — DECIDED 27 Aug: yes, tour booking only

Ruling (Fede, 27 Aug, in the overnight-build session: “of course”): option A — Clara books, reschedules and cancels tours on an escalated thread, behind a per-property opt-in (on for yale-sandbox), and never re-answers the waiting question. The Aug-20 silence rule stays the default everywhere else; Camellia unchanged unless it opts in, with a regression test pinning that. Build SHIPPED overnight (prospect-only, tour-scoped; a 30-day replay altered 0 of 817 turns; 9/9 subscription evals green) and is armed on the sandbox.

In plain terms

A prospect asks a question Clara can’t answer, so it goes to a human. A minute later the same prospect says “can I come see it Saturday?” Today Clara stays silent on purpose. Should she book the tour anyway?

Decision 13 · Yardi CRM IQ pivot — what to launch at Yale 25 before the Yardi integration exists (16 Sep, researched)

Short version, one page with the diagram and the options: Yale 25 on Yardi: what we launch now. The pick is shared between the two pages.

The question. ConAm drops RealPage for Yardi CRM IQ by 30 Sep. Our Yardi agreement covers maintenance and master data, not prospects. Fede's minimum: take every lead, book tours, send application links. What can go live now, what does each option add, and what do we tell ConAm? Everything below is labeled verified (quoted from a primary or vendor source), inferred, or not found. Full research notes (seven reports, ~120 sources) sit in the session scratchpad; the sources that matter are linked inline.

The funnel on Yardi, and where PropFlow can plug in

1 · Lead 2 · Conversation + tour 3 · Application 4 · Screening + decision 5 · Lease + move-in PROSPECT PROPFLOW / CLARA CONAM ON YARDI Zillow · website formcall · text · email Applies on the property'sRentCafe apply page E-signs the lease in thesame RentCafe account Answers in seconds,qualifies, follows up Books / moves / cancelstour on Jaise'sMicrosoft calendar Sends the RentCafeapply link Learns: received,screened,approved / denied Learns: lease signed,move-in date CRM IQ guest card(prospect, source) CRM IQ tour calendar(no Outlook sync found) RentCafe online leasing→ applicant in Voyager Yardi Resident Screening→ approve / conditional/ deny Voyager: managercountersigns, lease filed A · every lead sourcerepointed to PropFlow(verified) A · apply linkby text or email prospectapplies prospectsigns B · lead email (verified)C · RentCafe API (verified)E · Clara's own login C · RentCafe API (verified)E · Clara's own loginA / B · calendar only A / B · staff emails+ daily reportD · API read A / B · mailboxD · API readE · pipeline stage Read path with no API: Voyager staff notification emails + scheduled report packetsland in the community mailbox we already asked ConAm to connect (packet step 2)
Solid purple = option A, the minimum set, touching no Yardi system. Dashed = needs the option named on it. A front door only · B lead email + staff emails and reports into the mailbox · C RentCafe API token · D SIPP modules · E a CRM IQ login for Clara. "Verified" means found in Yardi or vendor documentation; the rest is inferred.

A real property on Yardi, end to end

The Mason, 1041 N Ogden St, Denver (Cornerstone Apartments). Start at the property's own RentCafe floor-plan page, which shows live rent and availability straight from Voyager: cornerstoneapartments.securecafe.com/onlineleasing/themason/floorplans (captured 16 Sep below: "1 Bed – 1 Bath, starting at $1,030, 4 Available Now"). "View Details" opens a unit page with the rent options and lease terms (…/themason/rentaloptions.aspx?UnitID=29173843&FloorPlanID=3932174&myOlePropertyid=1364877), "Apply" goes to …/themason/register.aspx where the applicant creates a RentCafe account, and the same account is the guest login they use later to check application status and sign the lease. The unit, apply and login pages sit behind a bot challenge (Cloudflare "Just a moment"), which is also the practical answer to "could Clara just use the site": no. Correction 16 Sep: an earlier version linked properties.cornerstoneapartments.com/homeaboutus.aspx as the company website; that page is only RentCafe's stock "apartment finder" template with no property content, so the floor-plan page above is the real entry point.

The Mason floor-plan page on RentCafe with live pricing and availability
The Mason's RentCafe floor-plan page, 16 Sep 2026. This is what Yale 25's pricing source becomes after cutover, except Yale's page stays on Apartments247 and pulls the same Yardi data.

A ConAm counter-example worth knowing. Addison at Cherry Creek, 9110 E Florida Ave, Denver (ConAm) has a listing on rentcafe.com (rentcafe.com/apartments/co/denver/addison-at-cherry-creek, "Base rent: ask for pricing"), but its own website is Apartments247 (addisonatcherrycreek.com, same builder as Yale's site) and its Apply button still goes to RealPage On-Site (https://www.on-site.com/apply/property/204435; both checked live 16 Sep). A rentcafe.com listing is just Yardi's listing marketplace; it does not mean the property runs on Yardi. No ConAm property was found publicly leasing through RentCafe yet.

What each stage looks like, verified

StageWhere it lives on YardiHow ConAm staff learn itHow PropFlow can learn or write it without an API
Lead arrivesCRM IQ guest card with source attribution. Leads reach CRM IQ by email to a Yardi-issued @assist.rent address (per property or company, set up by a Yardi rep, live in 24–48h; this is how Apartments.com feeds it — verified), by CRM IQ's own tracking numbers, or by the RentCafe API (LeaseHawk, CallRail, EliseAI all push guest cards this way — verified)."Unreviewed queue" in CRM IQ; dashboard alerts.Write: email each new prospect to the property's @assist.rent address (exact body format not found publicly; Yardi hands it over when the parser is set up). Read: nothing needed, the lead came to us first.
Tour bookedCRM IQ calendar (agent availability, month/week/day views — verified). No Outlook or Microsoft 365 sync found after ten targeted searches.CRM IQ calendar and tasks.A tour Clara books on Jaise's Microsoft calendar will not appear in CRM IQ (inferred from the missing sync). Only the RentCafe API (C) or a login (E) writes the appointment.
Application submittedRentCafe online leasing, public URL, deep-linkable to unit and move-in date, with a lead-source parameter (verified, real examples below). Creates the applicant record in Voyager."RentCafe immediately sends your information to the property" (verified); Voyager notifications "automatically generate an email" to staff (verified, consultant doc); CRM IQ "Applicants by stage" tile (verified, Yardi webinar).Applicant emails go to the prospect, not us. Staff notifications are email, recipients configured in Voyager per property group (verified). If ConAm routes them to the community mailbox we connect in step 2, we read them. Whether a non-staff address can be added directly: not found.
Screening + decisionYardi Resident Screening (ScreeningWorks Pro), results post to the applicant record with approve / conditional / deny (verified)."Automated email notifications when screenings are complete" (verified); the applicant gets an approval email (verified).Same mailbox path as above. A leasing-agent login sees the status value but usually not the credit detail (verified, permissions guide).
Lease signedApplicant e-signs in RentCafe; manager countersigns in Voyager; executed lease filed to the tenant record (verified). CRM IQ pipeline stage "lease signed" (verified).Voyager notification / task; pipeline stage.Same mailbox path, or the daily rent roll (the new resident appears with a lease start).
Pricing + availabilityVoyager → RentCafe ILS feed (per-property URL + token, MITS 5.0 XML/JSON, self-served in Site Manager — verified) → Apartments247 website, Zillow, Apartments.com.Rent roll report (already asked, step 3) and the website. Apartments247 lists Yardi as a supported source with "Guest Cards, Online Applications, Pricing, and Availability" (verified); the site and URL stay. ConAm could also hand us the ILS feed URL, no partnership needed (verified mechanism, not yet asked).

A real apply link, so the shape is concrete. Yale's today: https://www.on-site.com/apply/property/222618 (RealPage On-Site, dies at cutover, exact fate not found). After cutover it will look like these live RentCafe examples from other companies: https://venue-apts.securecafe.com/onlineleasing/venue-apartments/register?PropLeadSource_651873=portal and https://therail-stl.securecafe.com/onlineleasing/the-rail2/oleapplication.aspx?stepname=RentalOptions&myOlePropertyId=1800972&FloorPlanID=5308168&UnitID=40564853&MoveInDate=7%2F12%2F2026&PropLeadSource_1800972=portal. The PropLeadSource parameter is the attribution hook: ConAm can create a "PropFlow" lead source so every application Clara sends is credited to her in CRM IQ.

How we would build that link. The base link (subdomain, property slug, property ID) comes from ConAm once the website's Apply button points at RentCafe; that alone works on day one. The lead-source value is a code ConAm defines in CRM IQ ("PropFlow") and tells us. Per-unit deep links need RentCafe's internal floor-plan and unit IDs, which are not on the rent roll; the clean source is the property's RentCafe listing feed (per-property URL + token, generated by ConAm in Site Manager, the same feed Zillow consumes). Caveat: the PropLeadSource parameter is read off live RentCafe URLs, not from a Yardi spec; every indexed example uses the value "portal".

The documented way to credit a source, real example. Apartments.com's setup guide for RentCafe (verified): in Site Manager → Property Configuration → Marketing → Lead Attribution & DNI, the property turns on "Lead Attribution" and "Advanced Tracking", then for each lead source RentCafe generates a tracking URL (UTM parameters on the apply/website link), a tracking phone number (Call Automation tab) and a lead email address. Apartments.com's row gets those three and attribution is live in 24–48h. A "PropFlow" row on the same screen gives Clara her own tracking URL to send, her own number to forward from, and her own lead email, so every application, call and lead she produces is credited to PropFlow in CRM IQ. That is the ask to ConAm, not a hand-built parameter.

Options

CapabilityA · Front door, no YardiB · A + email bridge + reportsC · A + RentCafe API tokenD · SIPP Prospect + ApplicantE · Clara gets a CRM IQ login
Answer every leadYes (works on the sandbox today)YesYesYesYes
Book / move / cancel toursOn Jaise's Microsoft calendar onlySameAlso written to CRM IQ's calendar (verified: LeaseHawk does this)YesTyped into CRM IQ by the robot
Send the apply linkYes, RentCafe link with PropFlow lead sourceYesYesYesYes
Guest card in ConAm's CRMNoYes, by email (body format to get from Yardi)Yes, by APIYesYes, typed
Know application received / approved / lease signedOnly if staff notification emails land in the community mailbox we read (verified mechanism, ConAm-side config)Same, plus a daily applicant-status report packet emailed to us (scheduler verified; external delivery of residential packets not found, financial packets confirmed)Same as B; the RentCafe API's application-status read is not found publiclyYes, by API (Applicant + Screening modules)Yes, read off the "Applicants by stage" tile
"Already a lead?" dedupeOnly leads that reached us; one-time prospect export at cutoverCRM IQ dedupes on its side (inferred)Prospect search not confirmedYesYes, by searching
Cost to PropFlow$0$0RentCafe API agreement, $10K/yr (June partner call); transaction-priced with an annual cap (verified)$25K/yr per module (verified, matches our figure)$0
What ConAm / Yardi must doSteps 2–4 of the packet + new apply link + route staff notifications to the community mailboxA + ask their Yardi rep for the @assist.rent address and a scheduled applicant reportA + Site Manager → Company Level Settings → API Settings → vendor token and company code, or a Client Central case (verified, EliseAI's own client instructions)Interface entity + property activation in Voyager after our agreementCreate a leasing-agent user scoped to Yale 25 (same ask as the dead RealPage step 1)
Earliest liveDays (as soon as IT does steps 2–4)A + ~1 week after their cutoverA + our RentCafe agreement (weeks; "3–4 weeks" per the vendor that documents it) 2–4 months to contract (verified, Yardi's number), then pilotDays after cutover
RiskTours invisible in CRM IQEmail format and dedupe unverified; residential report delivery to an outside address unverifiedApplication status may still be blind; needs Sean's signature and a second agreementSlowest; a second $25K module for applicationsRentCafe's terms of service prohibit "any robot, spider… or other automated device, process or means to access, retrieve or index any portion of RentCafe" and bar competitors of Yardi from using the site (verified); the RentCafe API terms separately prohibit web automation tools that mimic a user (verified); none of 20 AI leasing vendors researched admits to a login-based robot. Different from AppFolio, where we are a sanctioned vendor
In plain terms

ConAm changing software does not change who answers the phone. Clara can take every lead, book every tour and send every application link without touching Yardi. What she cannot do without help is write the lead into their system or see that someone applied. The first has a cheap fix (Yardi accepts leads by email). The second is answered by the emails Yardi already sends staff, if ConAm points them at the mailbox we are connecting anyway, and properly by a $10K RentCafe agreement.

What we ask Yardi (Christopher) this week, regardless of pick: is the Maintenance + Master Data agreement signed and invoiced · what the RentCafe API agreement costs and takes for guest cards + appointments + application status · whether a non-ILS vendor can send to a property's @assist.rent address and in what format · whether Yardi objects to a client-issued CRM IQ user for an assistant. What we ask ConAm: the new RentCafe apply URL when it exists · route application, screening and lease notifications for Yale 25 to the community mailbox · the @assist.rent address for Yale 25 · a "PropFlow" lead source in CRM IQ · a one-time export of open prospects at cutover.

Engineering if A is picked (all dark, gated to Yale): retarget the Yale pricing scrape from On-Site to the website's floor-plan page · apply link becomes the RentCafe URL (existing settings field) · parse Voyager staff notifications from the community mailbox into application / approval / lease-signed events (no such parser exists today; PropFlow learns application status only from AppFolio) · daily lead summary to Jaise · one-time prospect import. If B: an outbound lead-email formatter to @assist.rent with a sandbox proof. If C: a RentCafe API client (guest card, appointment, availability) beside the existing SIPP client, which today has no live credentials.

Decision 12 · One asking price — DECIDED 1 Sep: one shared answerer, kept simple

Ruling (Fede, 1 Sep): everything pricing moves into one domain function. Rule: rent roll when fresh enough → else the scrape → else refuse to quote. No new config, no over-engineering. Clarified: Yale's rent roll is a real CONAM report that's simply OLD (no fresh report sent yet) — so trust is an age question, and the same freshness rule covers it. When a fresh rent roll lands, the switch back happens inside the one function. Full design + proof-of-concept: One asking price — design doc (includes the keep-vs-clear-old-rent-roll decision, recommendation: keep the rows, let the age check do the work).

Updated 3 Sep: the proof of concept merged and went live on 1 Sep without a decision (a "HOLD" in the title does not hold; only a draft or the hold-for-review label does). No prospect surface changed. Fede revised the rule the same day: where pricing and availability come from is a per-client setting (rent roll, website, or a staff-maintained source), hidden behind one function. The design doc now carries the corrected status and the new decisions.

In plain terms

Fede's framing (1 Sep, locked): the rent roll is the real source of truth for pricing; the daily website scrape exists only because Yale's Yardi rent-roll feed isn't connected yet — it's a bridge, not a source. Today ~10 pieces of code each pick between the two on their own, and yesterday one picked the placeholder roll and emailed a lead a rent $260/mo off. Ruling: consumers shouldn't choose or even know there are two sources — and when the real rent roll lands, retiring the bridge must be a one-place switch, not a ten-file hunt. Deep inspection (1 Sep) found ~10 prospect-facing consumers with three different levels of caution (two still fully ungated: the availability API and the PM dashboard-chat tool), and confirmed the pattern grew incident-by-incident — each surface got the safety check only after it personally burned us. One thing must NOT be merged: renewal math and loss-to-lease deliberately use the rent roll (they reason about the sitting tenant's lease, not the walk-in quote) — any unification must leave them untouched.

Research & audit — the short version

What the incumbent AI-leasing vendors ask clients to do (verified from their own setup guides)

  • RealPage: the client creates a user for the assistant, type User (No Email), same product access as a leasing agent, OneSite access. Our doc asks for exactly this, as “Clara PropFlow”.
  • Email: no mailbox or Microsoft asks at all — the market leader redirects ILS leads to its own per-property addresses (verified in the wild on a Denver property site). D2/D5 adopt the same model: yale25@propflowai.co.
  • Phone: 20 new vanity numbers per client instead of forwarding the office line; EIN collected for carrier registration.
  • Pattern to copy: name the exact role that must act, give copy-pasteable values, give a fallback contact, end with a CC line. The packet follows it.

How ILM actually behaves (40 verified findings)

  • A tour request never auto-books: “an appointment request is not scheduled until you receive a confirmation email”. Clara must meet or beat that promise.
  • Lead sources are per-source switches on Settings → Data Management → Adsource Numbers and Email; changes take 24–48h to propagate. Rollback is the same switch.
  • No self-serve API; write access needs AppPartner certification. A leasing-agent login is the practical path (the incumbents' precedent).
  • No dated ILM sunset was found anywhere — treat “ILM is going away” as a hunch to confirm with CONAM, not a plan input.
  • Fede’s live test: Zillow lead Tuesday → SMS opt-in same day → generic first text from a leasing agent Wednesday (no email address given).
  • ILM → Knock: no public migration playbook exists (RealPage’s “ILM to Knock” course is login-gated). What is documented: Knock repoints leads per property, per source, with a tracking email + tracking number and the same 24–48h ILS verification lag; customers report Knock↔OneSite reporting mismatches after cutover and a fast (pilot-first) rollout. No ILM end-of-life notice anywhere.

Camellia assumptions the code audit found (4 read-only auditors)

  • A PropFlow-owned inbox (clara@propflowai.co) is data-only: a lead emailed there never becomes an inquiry.
  • No parser recognizes a RealPage/ILM-relayed lead; it would be tagged “website” and can reproduce the fixed reply-threading bug.
  • There is no “outcomes-only” notification mode; the PM either mirrors a shared mailbox or hears nothing but escalations.
  • Without escalationOwnerEmail, no decision request is ever sent — and the confirm-before-remembering step (shipped Aug 21, PR 5989) never fires.
  • Global constants to make per-property: SendGrid sender, phone→property map, voice agent id, AppFolio tools wired everywhere, listings/scraper registries, split timezone fallback.

Already fixed on main this week (no work needed)

  • Placeholder rent roll can no longer produce “no units available” on any channel (6275, 6312).
  • A caller’s tenancy at a sibling property no longer hijacks identity (6334); tours can’t be rescheduled across properties (6336).
  • Quiet mode is enforced on every send path, including the Microsoft leg (6215).
  • Sandbox isolation that already holds: org-scoped identity lookups, isTest-aware metrics/insights crons, per-call voice personalization, no live number on the sandbox.
Reference — the full migration & cutover plan (Aug 25, unchanged)

1 · Their systems

  • Yardi — accounting, ledgers, rent only. PM has no report-scheduler access; rent roll must be scheduled by regional/IT as a daily email (with resident phone + email columns) to clara@propflowai.co. Not yet flowing: 0 of 115 leases ingested.
  • AppWork — maintenance + turnovers, incl. resident comms/ETA texts. Work orders still mirror into Yardi read-only. Out of scope; do not collide.
  • RealPage ILM (+ OneSite) — leasing, renewals, applications. Closed: no API (RealPage partner APIs don't cover it; even the incumbents can't integrate), no export at PM permission level. Being sunset by RealPage → eventual forced Knock migration. Holds per-source tracking numbers/emails ("Adsource Numbers and Email") that it syndicates to the ILSs; sends from a replyable tracking address ("Yale 25 Station @ RealPage").
  • Lead flow — Zillow / website / tracking-number calls → ILM guest card (Yale does not list on Apartments.com — corrected Aug 25; confirm the full adsource list from ILM's "Adsource Numbers and Email" screen before repointing) → auto-response + centralized regional team first touch → guest card assigned to on-site PM → manual 5-touch follow-up (policy: 3 touches in first 3 days, then weekly), manual application links, manual tour-slot blocking in RealPage's calendar. Guest-card notes can be overwritten by other agents' follow-ups.
  • Website — yale25stationapartments.com is Apartments247-hosted (not RealPage). Forms are JS, submitted to Apartments247's backend, delivered onward to ILM (their platform advertises guest-card integration with RealPage; email delivery is the universal fallback). Lead destination changes in the Apartments247 dashboard. Open question to them: email or guest-card integration for this community, and can the destination change.
  • Email/calendar — two mailboxes: PM's personal ConAm email (what she works from; business cards; outbound she initiates) and the shared community mailbox "Yale 25 Station" (vendors, invoices, residents). No community calendar exists. Prospect comms go out from ILM's tracking address, not a person.
  • Phone — ILS tracking numbers ring the office line but log in ILM; missed calls/voicemails become transcript emails inside ILM; office closed weekends. Emergency maintenance = IVR option → tech's cell. Website shows local tracking number (303) 395-9448.
  • IT — ticket portal; security assessment required before any access (their first ever, timeline unknown); email+calendar request declined Aug 24, reviewer apparently unaware of the existing vendor approval (~4 months old). PM can approve nothing; endorsement path = Dara Johnson (regional).
TODAY Zillow · Apts.com website · calls ILM tracking # + email per listing source, owned by RealPage ILM guest card auto-response + centralized 1st touch Assigned to on-site PM Manual work 5 touches · app links calendar blocking AFTER CUTOVER Same sources unchanged for renters PropFlow tracking # + email per source (the config flip, per ILS) Clara, 24/7 qualified answer · 5-touch cadence · tour booking Assignment queue escalation to PM PM keeps tours · applications (in RealPage) ILM stays alive in both pictures — applications & renewals remain there until Clara has a user account inside it.

2 · Repointing mechanics (verified)

  • Zillow + website are Yale's repoint surface — Yale does not list on Apartments.com. (Apartments.com mechanics, kept only for other ConAm communities that list there: up to 6 destination emails, 1 destination phone per listing, changed via support@apartments.com, 24–48h propagation.)
  • Zillow: lead delivery moved via rentalfeeds@zillow.com; supports HTTP-POST webhook straight into our system (fixed URL-encoded format).
  • Website — the assumption-break (decided Aug 25): PropFlow's intake today is email parsing, but Yale's website leads never exist as email — the form posts to Apartments247's platform, which feeds ILM by guest-card integration. Market research (Aug 25, sourced): email is the universal delivery denominator across this whole category; an arbitrary "POST JSON to your endpoint" is not a published menu item at Apartments247 or anywhere else (where CRM webhooks exist — Zillow Lead API — they're partner-program-gated). A247 does white-glove integration config (contact: integration@apartments247.com; PMS guest-card partners incl. AppFolio/Yardi/Entrata/RealPage — though a support note says they dropped RealPage syndication 9/30/2024, snippet-verified only; confirm what Yale's feed actually is today). One ticket, ranked asks: (1) email redirect of guest-card leads to Clara's mailbox — near-certain floor, do regardless; (2) can they POST guest cards as JSON to our /api/leads/website — plausible white-glove, not guaranteed; (3) alternatively emit MITS Lead Management XML (the legacy multifamily lead standard — Entrata still accepts it via sendMitsLeads but is deprecating it for plain REST; fine as a stopgap schema, don't build long-term on it). Later/strategic: PropFlow registers as a Zillow Lead API partner (webhook delivery, ~4–6 wk approval; software-vendor track, fits PropFlow, not a single property).
  • Competitor research (Aug 25, sourced) — our endpoint design is standard practice for the market's leaders, not exotic: Funnel Leasing runs almost exactly this design today (documented multi-tenant Partner API, per-client scoped keys split public/private by trust level); Entrata exposes a Leads REST API and is actively sunsetting its MITS-XML path toward it; Yardi — the biggest incumbent — still defaults new integrations to email parsing (24–48 h) with its "real" credentialed API a 3–4-week onboarding. The AI assistants (the incumbent vendors) don't accept website POSTs at all — they're embedded widgets or PMS-side consumers. Design refinements to adopt from the research: split keys by trust level; human-reviewable duplicate-merge, never silent auto-merge (fair-housing stakes); originating page/campaign as a first-class lead field (not a catch-all "website" bucket); keep a durable async fallback lane (our 5xx→email rule — the reason email parsing survives industry-wide); issue keys through a lightweight agreement step, not self-serve.
  • Intake-endpoint strategy (decided, Fede Aug 25 — full spec: lead-intake handoff): replacement, not integration — client websites post leads straight to PropFlow; Clara owns the lead from the first second. One multi-tenant endpoint, per-client keys scoped to property IDs, synthesizes the same internal payload as the email path into the existing queue (downstream untouched), rate-limited, alert-on-failure, email fallback on 5xx so no lead is ever lost. Status update (Aug 25 pm): the endpoint is SPEC-ONLY, build on demand — Camellia shipped the short-term email fix instead (provenance stamp #6251 + neutral sender, both live; its form-side API switch is parked in a hold PR). Yale is the likely build trigger: if Apartments247 confirms they can POST, F4 gets built with Yale as first consumer; if not, Yale rides the email-redirect floor and the endpoint stays on paper. ILS leads (Zillow, for Yale) keep arriving by email into the connected mailbox mid-migration; both lanes run side by side.
  • Unknown: what ILM does when an adsource is removed — undocumented; test on one low-volume source first, never assume the fallback.
  • Reference — the market leader's mechanism on RealPage: client creates a real CRM user for the assistant with leasing-agent permissions; existing ILS tracking numbers are redirected to vendor-owned numbers (one per source per property); email sends from its own domain, with ILSs asked to redirect lead mail to a per-community address in the vendor's portal. Classic ILM is unsupported even by them.

Write-back: PropFlow guest card → ILM (no API exists; three paths):

  • Application link = the natural sync point (default, no write-back): the prospect applying via ConAm's RealPage link creates the applicant record in OneSite themselves; application → lease → nightly Yardi sync runs untouched. Covers the money path with zero integration.
  • Email injection via ILM's own ingestion (optional): deliver a standard-format lead email to the property's adsource address → ILM mints the guest card itself, attributed to a "PropFlow" source. Initial card only; no ongoing state.
  • Browser automation as the Clara CRM user (build-on-demand): full fidelity (notes, statuses, assignment) via the real login; requires click-capture of real UI requests first (AppFolio lesson: ephemeral flow IDs, WAF fakes 200s). Likely never worth building against a sunsetting product — save it for Knock's real API.

3 · PropFlow changes (features + settings)

"CRM-mode" becomes per-property configuration: same product runs inbox-mode (Camellia: client Graph mailbox) or CRM-mode (Yale: PropFlow-owned identity + redirected sources).

#CapabilityTodayChangeSize
F1Per-property sender identity + reply-to routing — send from e.g. yale25@propflowai.co, display name "Yale 25 Station Leasing"; unique per-conversation Reply-To token; SendGrid Inbound Parse (MX on subdomain) routes replies in; threading via Message-ID/References.SendGrid From is one hardcoded global constant; no Inbound Parse; property-voiced send only via client Graph mailbox.Per-property senderIdentity record read by the SendGrid path; authenticate subdomain (SPF/DKIM); Inbound Parse webhook → existing inbound pipeline. Subdomain warm-up 3–6 wks — start first.Build
F2Multiple mailboxes per property, role-tagged (send / read_only / agent_personal).Property.emailIntegration is a single field doing send+receive; inbound routing keyed on receiving mailbox.Pluralize; call sites pick by role. teamMonitoredInbox flag reusable.Build
F3Per-source tracking numbers + emails with attribution.Source attribution by email parsing (Zillow/Apts.com parsers live). Twilio number→property map hardcoded in source, no source tag.Move phone map to per-property data with source tag stamped on inquiry; per-source inbound addresses on the F1 subdomain.Medium
F4Direct lead intakePOST /api/leads/website (decided Aug 25; handoff) + Zillow Lead API POST.Doesn't exist; all intake is email parsing — and Yale's website leads never exist as email (Apartments247 → ILM guest-card feed).Multi-tenant endpoint, per-client keys scoped to property IDs, same internal payload → existing queue; email fallback on 5xx. Spec parked (lead-intake handoff); Yale via Apartments247 is the likely build trigger if they confirm POST support.Medium — spec only, build on demand
F5Escalation as assignment — named queue with context, deadlines, nags (matches ILM's guest-card assignment model).EscalationMatter exists (named owner, SLA + nag ladder, reply threading); rollout may be test-bench-only.Verify prod rollout; set escalationOwnerEmail for Yale; assignment-list UI.Config + verify
F65-touch cadence (3 in 3 days, then weekly).Already the default (instant + 24h + 48h + 7d + 14d); editable per org.None. Per-property variance = later.Done
F7Tour debrief + floor-plan watch — structured post-tour notes; wanted-floor-plan → re-engage when one opens. (ILM wipes notes on follow-up; ~26–30 floor plans incl. one-of-one units.)Re-engagement cadence + AI notes + qualification facts on calendar events exist; no debrief loop, no availability watch.Post-tour PM prompt writing structured notes; daily match of wants vs. new availability → touch.Medium
F8Hard-gate qualified booking (bed count + move-in before tour).Prompt collects both, stamps structured, renders on calendar event + PM confirmation; tool doesn't require them.Soft gate on schedule_tour: require both unless prospect declined.Small
F9Enterprise login hardening — ConAm's mail scanner clicked each magic link 20–27×, consuming them; code emails untouched.Magic links assume no scanner.Code-based sign-in default for enterprise domains; links require a confirmation tap.Small
F10Operating-mode settingconnectionMode: inbox | crm + staffing mode (on-site/centralized/rotating) driving F1–F5 defaults.No field; precedent = per-property booleans + global-arm/property-allowlist pattern.New field on Property record; the switchboard.Small

4 · ConAm IT asks

  1. Create CRM user in ILM/RealPage: first "Clara", last "PropFlow", email clara@propflowai.co, leasing-agent permission set — the industry-standard mechanism. Gives application/renewal visibility, guest-card assignment to Clara, migration assistance.
  2. Repoint listing lead destinations — for Yale: Zillow rentalfeeds (webhook) + Apartments247 (website form; via their integration team). Apartments.com only for other ConAm communities that list there. Per-source, on our schedule, against the adsource list confirmed from ILM.
  3. Calendar read/write on the PM's Outlook calendar (ticket filed; Outlook = full write support in our stack; Google is read-only).
  4. Read-only access to the community mailbox (separate ticket) — observe vendor/resident traffic; never send from it.
  5. Schedule daily Yardi rent-roll email to clara@propflowai.co with resident phone + email columns (PM lacks report-scheduler access) + one-time tenant-contact export, monthly after.
  6. Security assessment with a named IT contact — we supply the security posture doc proactively; reference the existing vendor approval.

5 · Cutover plan

  1. Phase 0 — access & data: IT packet through Dara; named IT contact; rent roll flowing; listing-admin identified; F1 subdomain warm-up started (3–6 wks, parallel); SMS registration resolved (§7).
  2. Phase 1 — build: F1–F4, F9, F10; verify F5. Each proven end-to-end on the test property first.
  3. Phase 2 — shadow (1–2 wks): one low-volume source (or after-hours/weekend phone only) → PropFlow; also empirically tests ILM's source-removal behavior. PM reviews every conversation. Gate: sign-off on quality, zero misroutes, full tour context on calendar.
  4. Phase 3 — source-by-source (~2–4 wks): repoint remaining sources one at a time (24–48h each). Clara owns first touch + cadence + tour booking + application links for new leads; in-flight ILM leads drain via the PM (their ~3-week follow-up window empties it). Centralized team stops receiving Yale leads by construction.
  5. Phase 4 — steady state: ILM = system of record for applications/renewals (no execute-renewal API exists; renewals outreach-only). Monthly metrics: response rate, minutes-to-first-touch, tours booked, weekend coverage.

Rollback at any point: repoint listing contacts back to ILM's tracking values — same tickets in reverse, per source. Applications/renewals never left RealPage; nothing is stranded.

Go-live readiness punch list — from live test calls on the Yale line (Aug 25). Re-audited against production 31 Aug: every engineering item below is still open; none needs IT.

  • P0 — one canonical caller-identity lookup. Call-start recognition, schedule_tour, and reschedule_tour each resolve "whose phone is this?" differently and can disagree; live symptom: returning caller unrecognized 8 min after booking, reschedule failed with "no prospect found" while the tour existed, call escalated to a human. Bites any real prospect who contacts us on two channels.
  • P1 — tour confirmation loop. No leasing calendar connected (IT ask #3) → tours stick at "proposed" → confirmation SMS never fires (sender only fires on confirmed/cancelled). Decide: connect calendar, or enable no-calendar auto-confirm for Yale. (The send path itself is proven — first texts from the Yale line delivered Aug 25 18:11Z, §7.) Live consequence 29 Aug (an eval-robot call, but the mechanics are real): its tour for Sep 3 stuck at proposed, calendar sync failed, no confirmation sent.
  • P1 — Clara claims "confirmed" when the tour is only proposed. Tool's spoken confirmation says "confirmed" even when auto_confirmed=false; caller is promised something the system didn't do.
  • P2 — voice conversations get no topic labels (topics:[] despite a booked tour) — /conversations filtering blind to voice leasing traffic.
  • P2 — garbled-name handling: ASR heard "spread" for "Fred"; agent should confirm the captured name instead of missing it and re-asking (3 asks on the first test call).
  • P1 — SMS lacks the placeholder-data gate voice has: live test (Aug 25): texted "How much are the one bedrooms?" → Clara answered "we don't have any one-bedrooms open right now" straight off the 112-unit placeholder rent roll (and skipped the price question). The ADR-0080 data-quality gate suppresses placeholder data on voice injection only; the SMS/email tool path needs the same gate. Also: a bare "Hey" text deflected to "I'll check with the team" instead of greeting.
  • Org tenancy — DECIDED (see Decision 10): Yale stays in JPCO (ruled Aug 24, 25 and 27); CONAM staff are isolated by per-property scoping. The shared identity pool is accepted knowingly; revisit only if a cross-org owner view ships.
  • Test-config states to restore at go-live: Yale officePhone repointed 2026-08-25 from the real office line +1 303 395 9448 to a test cell (+1 404 285 9387) so error escalations stop ringing the real office — restore before launch. One transfer already reached the office line (106 s, Aug 25 12:03 MT). RESTORED 27 Aug, verified in prod 31 Aug — officePhone reads (303) 395 9448 again.
  • Data quality: rent roll is a 112-unit placeholder until IT ask #5 (Yardi feed) — voice injection correctly suppresses it; pricing/availability answers stay thin until real data lands.

6 · Mailbox / calendar mapping

IdentityRole
Clara's PropFlow identity (F1)All prospect-facing sending; replies route into PropFlow via Inbound Parse. Never a ConAm mailbox.
PM's personal ConAm email + Outlook calendarCalendar = where tours land (read/write). Email observed only if wanted; never sent from.
Community mailbox (shared)Read-only observe. No community calendar exists; none needed.

No do-not-reply addresses anywhere — every Clara address is replyable; replies are routed into the conversation (ILM's tracking address is replyable today; we don't regress below that).

7 · Registrations in flight (SMS)

  • A2P 10DLC (Yale local +1 720-734-8637): ✅ VERIFIED (API-checked Aug 25). The Aug 25 resubmission — privacy-policy/terms URLs attached, the two empty fields every rejection since March cited — was approved. Campaign QE2c6890… on the Standard vetted brand; brand score 23 = lowest T-Mobile daily-throughput tier (ample at pilot volume). SMS from the Yale local number is fully cleared.
  • Twilio appeal #28450505 is now moot (it was chasing evidence for the campaign that just verified). Proposed: one-line note on the ticket referencing the approval + close request — pending an explicit go; no writes until then.
  • Toll-free +1 833-854-8998 (hedge, unwired): TFV still IN_REVIEW as of Aug 25. With the local number verified the hedge is redundant — keep-or-release decision open (recommend: let TFV finish, park through pilot ramp, then release).
  • Not repurposable: +1 844-285-3526 is the AppFolio 2FA OTP sink (automation polls it) + prod test-property line; +1 833-408-5783 is the PR-preview auto-flipped line.
  • SMS gate cleared as of Aug 25 — the cadence can include texting from the local number once armed. (Voice was never gated.) First delivered texts from the line proven Aug 25 18:11Z.
  • Number reputation (inspected Aug 25): clean slate — no public spam listings found, essentially zero outbound call history, inbound always answered (good signals). Console checklist for +1 720 734 8637: compliance profile ✅; SHAKEN/STIR, Voice Integrity, Branded Calling, CNAM all Not Started. Levers, in order: (1) SHAKEN/STIR registration — free, foundational call attestation; (2) CNAM — outbound calls display "Yale 25 Station" instead of a bare number; (3) Voice Integrity — proactive registration with the analytics engines behind "Spam Likely" labels (First Orion/Hiya/TNS); (4) Free Caller Registry (freecallerregistry.com) — free one-shot submission to the same three engines; (5) Branded Calling — paid, logo-level display, optional/later. SMS side: brand vetting score 23 = lowest T-Mobile daily tier (ample at pilot volume; paid re-vetting only if volume demands). All registrations are external writes — per-action go required.

8 · Other risks

  • ConAm security assessment — gates all access; timeline unknown (their first).
  • Fresh-subdomain deliverability — 3–6 wk warm-up; Gmail bulk rules count the root domain in aggregate.
  • ILM sunset timing — a forced Knock migration mid-project changes the integration surface (Knock has real APIs); re-scope if announced.
PropFlow Docs