Live 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)
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.
| Status | Item | Owner | Evidence |
|---|---|---|---|
| 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. | Fede | doc | |
| 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). | Fede | sent 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). | Fede | ILM, confirmed 28 Aug |
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.
| Status | Item | Owner | Evidence |
|---|---|---|---|
| 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). | Eng | proven live, e2e | |
| Sandbox isolation gaps closedShipped overnight; sweep windows show 0 Camellia and 0 real-Yale activity. | Eng | merged 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. | Eng | merged 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. | Eng | merged 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. | Eng | merged + 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. | Eng | ack 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 |
Turn the Camellia-shaped assumptions the audits found into per-property settings, so the third property is a config change, not a fork.
| Status | Item | Owner | Evidence |
|---|---|---|---|
| operatingMode / connectionMode on the Property recordShipped overnight with the inbox→conversation lane (dual-gate armed per D9). | Eng | merged 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. | Eng | merged overnight | |
| Phone→property map as data, not codeBuilt overnight, PR green except one stuck CI check (re-run queued); merges this morning. | Eng | PR 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. | Eng | verified already gated — no work | |
| One timezone fallbackIn the same open PR as the phone map; merges this morning. | Eng | PR 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 |
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.
| Status | Item | Owner | Evidence |
|---|---|---|---|
| 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. | Eng | done 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. | Eng | 3 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 |
Clara owns new leads end to end: phone, Zillow email, texts, tours and their changes; applications tracked in ILM; lease-signed as a bonus.
| Status | Item | Owner | Evidence |
|---|---|---|---|
| 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 |
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.
| # | Channel | Test | Proves | Status | Evidence |
|---|---|---|---|---|---|
| E1 | Outside lead email arrives at yale25@propflowai.co | Receive route delivers; an inquiry + prospect are created | PASS | 31 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. | |
| E2 | Clara replies for real | Send path works; from "Yale 25 Station Leasing <yale25@propflowai.co>"; lands in the sender's inbox (not spam) | PASS | 31 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"). | |
| E3 | Lead replies again | Threading: the reply joins the same conversation, Clara keeps context | FAIL | 31 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. | |
| E4 | Lead asks the rent | Placeholder-data gate holds on the email path: honest deferral, no fake number | PASS (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. | |
| E5 | Question Clara can't answer | Escalation forward reaches the (newly set) escalation address | PASS | 31 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.) | |
| E6 | Public address yale25@propflowai.co (send + reply) | Mail to the public address reaches Clara; her reply comes from it; a reply to her reply is answered | PASS | 2 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). | |
| S1 | SMS | Inbound text to the Yale number | Conversation created; real reply sent from the Yale number | PASS | 31 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). |
| S2 | SMS | Book a tour by text | Tour created; honest wording (proposed vs confirmed); confirmation text arrives | PASS | Tour booked by text ("Jordan Meyer", Wed 3pm): tour row created as proposed, wording honest ("team will confirm shortly"), no false confirm. |
| S3 | SMS | Reply STOP | Opt-out honored; no further sends | PASS | STOP → immediate unsubscribe confirmation; a follow-up message got silence. Opt-out recorded and honored. |
| S4 | SMS | Ask the rent by text | Placeholder-data gate holds on the SMS path | PASS | "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. |
| S5 | SMS | Robot's queued follow-up texts | Queued cadence inventoried BEFORE un-mute; fires deliberately or is cancelled — never by surprise | PASS | 31 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. |
| V1 | Voice | Inbound call | Answered as Yale 25 Station (right property, right greeting) | PASS | Robot: "Hi, is this Yale 25 Station?" → "Yes, it is." Right property, no Camellia bleed. |
| V2 | Voice | Book a tour on the call | Tour created; "confirmed" said only when actually confirmed | PASS | "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). |
| V3 | Voice | Hang up, call right back | Returning caller recognized — live re-proof of the fixed identity bug | PASS | Same caller rang back 2.5 min later: "Hi, Riley" + exact tour details. The fixed identity bug re-proven live. |
| V4 | Voice | Reschedule the tour by phone | Existing tour moved, not duplicated; no "no prospect found" | PASS | Same tour id moved Mon 4pm → Tue 2pm, no duplicate, still honestly "proposed". |
| V5 | Voice | Spanish call | Full conversation in Spanish, no language flips | PASS | Full conversation in natural Spanish, no flips or resets. |
| V6 | Voice | Ask the rent on the phone | Placeholder-data gate holds on voice (its original home) | PASS | Quoted $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. |
| V7 | Voice | Call after hours | Message taken instead of dialing a closed office | PASS | 3 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. |
| X1 | Cross | Call, then text from the same number | Same person recognized across channels — one conversation history | PASS | Proven 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. |
| X2 | Cross | Tour booked on voice → confirmation text | Channel hand-off: the booking triggers the SMS confirmation | FIX DEPLOYED — live proof = Fede's call | 31 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. |
| X3 | Cross | Voice conversation gets a topic label | Settles the stale "no labels" audit claim with a live row | PASS | All 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. |
| C1 | Calendar | Connect test calendar; book a tour | Event appears with prospect details; tour auto-confirms against a clean slot | PENDING | needs a Microsoft account — Fede gate |
| C2 | Calendar | Book into a busy slot | Conflict detected; alternatives offered instead of double-booking | PENDING | — |
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).
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?
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.
zms-1234@reply.zillow.com).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.
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.
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.
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).
How much of Clara’s work should land in the manager’s inbox: just the results, everything, or a daily summary?
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?
When Clara needs a human — “is unit 204 pet-friendly?” — who gets the text first?
Do we give each property one switch that says how it works (corporate-managed, centralized, on-site), or keep stacking little switches?
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.)
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.
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?
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 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.

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.
| Stage | Where it lives on Yardi | How ConAm staff learn it | How PropFlow can learn or write it without an API |
|---|---|---|---|
| Lead arrives | CRM 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 booked | CRM 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 submitted | RentCafe 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 + decision | Yardi 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 signed | Applicant 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 + availability | Voyager → 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.
| Capability | A · Front door, no Yardi | B · A + email bridge + reports | C · A + RentCafe API token | D · SIPP Prospect + Applicant | E · Clara gets a CRM IQ login |
|---|---|---|---|---|---|
| Answer every lead | Yes (works on the sandbox today) | Yes | Yes | Yes | Yes |
| Book / move / cancel tours | On Jaise's Microsoft calendar only | Same | Also written to CRM IQ's calendar (verified: LeaseHawk does this) | Yes | Typed into CRM IQ by the robot |
| Send the apply link | Yes, RentCafe link with PropFlow lead source | Yes | Yes | Yes | Yes |
| Guest card in ConAm's CRM | No | Yes, by email (body format to get from Yardi) | Yes, by API | Yes | Yes, typed |
| Know application received / approved / lease signed | Only 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 publicly | Yes, by API (Applicant + Screening modules) | Yes, read off the "Applicants by stage" tile |
| "Already a lead?" dedupe | Only leads that reached us; one-time prospect export at cutover | CRM IQ dedupes on its side (inferred) | Prospect search not confirmed | Yes | Yes, by searching |
| Cost to PropFlow | $0 | $0 | RentCafe 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 do | Steps 2–4 of the packet + new apply link + route staff notifications to the community mailbox | A + ask their Yardi rep for the @assist.rent address and a scheduled applicant report | A + 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 agreement | Create a leasing-agent user scoped to Yale 25 (same ask as the dead RealPage step 1) |
| Earliest live | Days (as soon as IT does steps 2–4) | A + ~1 week after their cutover | A + our RentCafe agreement (weeks; "3–4 weeks" per the vendor that documents it) | 2–4 months to contract (verified, Yardi's number), then pilot | Days after cutover |
| Risk | Tours invisible in CRM IQ | Email format and dedupe unverified; residential report delivery to an outside address unverified | Application status may still be blind; needs Sean's signature and a second agreement | Slowest; a second $25K module for applications | RentCafe'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 |
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.
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.
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.
escalationOwnerEmail, no decision request is ever sent — and the confirm-before-remembering step (shipped Aug 21, PR 5989) never fires./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).Write-back: PropFlow guest card → ILM (no API exists; three paths):
"CRM-mode" becomes per-property configuration: same product runs inbox-mode (Camellia: client Graph mailbox) or CRM-mode (Yale: PropFlow-owned identity + redirected sources).
| # | Capability | Today | Change | Size |
|---|---|---|---|---|
| F1 | Per-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 |
| F2 | Multiple 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 |
| F3 | Per-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 |
| F4 | Direct lead intake — POST /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 |
| F5 | Escalation 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 |
| F6 | 5-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 |
| F7 | Tour 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 |
| F8 | Hard-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 |
| F9 | Enterprise 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 |
| F10 | Operating-mode setting — connectionMode: 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 |
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.
| Identity | Role |
|---|---|
| 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 calendar | Calendar = 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).