RPP Direct Mail CTA and QR Funnel Brief

Generated 2026-08-18 by Woz · Sources: revparpro repo, AceHQ vault, live RPP Supabase (read only), CoStar/STR terms, USPS, ANA, Census, vendor pages; 12 research reports and 5 panel positions archived at ~/agents-runtime/docs/rpp-mailer-funnel-brief/
Decision: progressive gate. Contact info unlocks the full June report, naming the exact competitive set is the commitment act (tested required vs optional), and the STR upload never gates the free report (deferred to phase 2 as an optional, members-first shortcut with subject-only plus roster retention). Ace's hypothesis is adopted for contact info and rejected for the upload; every panel seat, including the Gemini contrarian, dissented on the upload independently.

Implementation-ready handoff for the printed CTA, the QR scan experience, the free June report, contact capture, competitive-set definition, the STR-upload question, and the $9/month founding-member offer. Produced 2026-08-18 by running the handoff prompt (prompts/RPP Direct Mail CTA and QR Funnel Handoff.md) through a 12-agent research pass and an independent five-seat panel (Hormozi, Ive, Wynn, a Woz technical lens, ChaseAI on Gemini as the cross-vendor contrarian). Panel transcripts and the 12 research reports are archived at ~/agents-runtime/docs/rpp-mailer-funnel-brief-archive/ (research/ and panel/). Published page: https://rpp-mailer-funnel-brief.pages.dev

0. Verified vs assumed, up front

Verified (source in the same line)

Assuming (not checked)

1. The decision: progressive gate (option D). No STR upload before the free report.

Recommendation. Contact information unlocks the full June report. Naming the exact competitive set is the commitment act, offered right after the report opens (arm B tests making it required). The STR file upload is removed from the free path entirely in drop 1; when it ships, it is an optional shortcut for the set step, subject-only plus roster retention, offered first to paying founding members. Ace's both-gates hypothesis is adopted for contact information and rejected for the upload.

Why (decisive evidence).

  1. The upload adds time and effort at the worst moment. Paper is opened at the desk or the mailroom; the scan happens on a phone; the STAR workbook lives in an inbox and must be the Excel version because the parser rejects PDF (research/09-gap-1). Hormozi's July line stands: "Effort at step one must be zero" (specs/str-upload-public-tool-design.md section 6).
  2. The file adds nothing the deliverable needs. The audit and the exact-set report both run on the roster (verified above). Hand-naming produces the same roster and is a stronger intent signal than a file drop (Hormozi, Wynn).
  3. The upload asks strangers to breach their STR agreement (Sec. 4.2 above). Management-company revenue teams, the core customer, know the clause and are the leads most likely to refuse (Wynn). The Texas incumbent Source Strategies invites STR-report sharing, which shows market comfort, not CoStar consent (research/06).
  4. No analog gates a free report on a confidential upload; first look is ungated, email gates history and saved sets, payment gates comp control (research/06: BoozeReports, AirDNA, Source Strategies).
  5. The intake path is not safe to point strangers at today (bucket policy, no purge, no routing). Fixing it properly costs 3 to 5 days on the print critical path (Woz lens).
  6. Every panel seat, including the Gemini contrarian, landed on D independently after receiving the same raw evidence.

What Ace keeps. The commitment he wants exists: it is naming the set. Arm B of the experiment makes it required before the report opens, so the hypothesis "commitment raises lead quality" is tested without the contract exposure.

2. Printed CTA block (the only mailer change)

Text column 6.19 in wide, block 2.26 in tall (research/03). Widen the QR column to about 1.4 in so the typeable URL fits on one line (Ive). Move the QR label 0.11 in below the symbol, out of the quiet zone. Encode https://revparpro.com/r/{CODE}?s=q (36 bytes, fits QR version 3 at level M, so larger modules in the same 0.87 in; Woz lens). Print the URL without ?s=q so QR and typed visits split cleanly.

Line Copy Chars Type
Headline Get the full June report for your hotel, free. 46 18pt / 600 ink
Supporting All 47 area hotels that filed, two years of history, and your own set of the hotels that matter. 96 9.6pt slate
Price June is free. Founding members keep it coming for $9 a month. 60 11.5pt / 600 ink
QR label Open your report 3 words 7.5pt / 700 action blue, uppercase
Under label RevParPro.com/r/ABCD2345 per piece 7.5pt slate
Method line Source: June 2026 Texas public hotel filings. unchanged 7.5pt slate

The "47" is per-hotel variable data (count of tract hotels with a June filing). "Two years" is supported by the 24-month series verified for the printed set. Nothing else on the page changes. Do not fill the 0.73 in of empty space above the method line (Ive: the one calm moment on a dense page).

3. The journey, step by step

  1. Scan or type. revparpro.com/r/{code} logs the hit (token, timestamp, user agent, referrer, QR vs typed) and 302s to the destination stored on the token, app.revparpro.com/t/{code} by default. Destinations change by updating the row; nothing is reprinted. Unknown or voided code: a static recovery page with a code field and a hotel-name lookup.
  2. Known hotel, zero input. The page names the hotel and month, shows the whole area (all 47 filed tract hotels), the printed suggested set (13), and an empty "Your set", plus three headline figures. Nothing is asked. No account, no score, no fake locked rows, no upload, no price.
  3. Unlock. One button opens a sheet over the data: work email (required), name (optional), role chips. Hotel, month, campaign, and piece are static, not fields. Submit opens the full June report on screen and emails a link to a copy.
  4. Full June report. Rank in the set, gap to the named leader, named June movers with dollar swings, 24-month history per hotel, share vs fair share with 12-month trend, prior-June and 12-month levels, the whole-area table, methodology behind an info icon.
  5. Choose the hotels that matter. Picker: the printed 13, the other tract hotels, and a name search limited to the subject's radius. Tick 4 to 12. Save rebuilds June on the exact set and re-sends the copy. Arm B moves this step before the report opens.
  6. Founding-member card. After the report and after the set is saved: $9 a month, the promise, one button. If Stripe is not live on mail day, the button reserves the spot; the checkout ships before the July issue.
  7. Checkout. Hosted Stripe Checkout, $9/month, cadence and terms disclosed there, webhook writes the entitlement, confirmation email.
  8. Monthly issue. Generated when the set's members have filed the period, the week the state publishes, about four to five weeks after month end; emailed link plus on-screen; completeness line (n of N peers filed); re-issue on late filings.
  9. Follow-up. Email only, data-driven, capped, one-click unsubscribe. No calls or texts in the pilot.
  10. STR upload (phase 2, members first). Optional shortcut inside "Your set": Excel only, subject line plus roster kept, file deleted within 7 days, right-to-share on the GM, hand-pick beside it at equal weight.

4. Screen copy

Rule (Ace, 2026-08-17): data screens carry names, numbers, labels, and status; every explanation lives behind a small info icon.

4.1 Scan landing (zero input)

4.2 Unlock sheet

4.3 Full June report

4.4 Set picker

4.5 Founding-member card (after report and set)

4.6 Checkout and confirmation

4.7 Unknown, expired, or voided code

4.8 STR upload states (phase 2, members first; copy locked now so product does not redesign later)

5. Field table

Field Prefilled from token or requested Why needed Required
Hotel (str_number, name, address) Prefilled Personalization, report subject yes
Report month Prefilled (report_period) Fixes the free issue to June 2026 yes
Campaign, batch, variant, drop date, market Prefilled Attribution and the A/B arm yes
Mail piece ID Prefilled (one token per piece) Per-piece attribution, void on misprint yes
Printed set (13 str_numbers) and printed snapshot (14 rows plus headline numbers) Prefilled Page echoes the paper exactly even after Comptroller revisions yes
Channel (QR vs typed) Captured on hit (?s=q) Tests whether the QR earns its place auto
Work email Requested Deliver report, monthly issue, opt-out channel yes
Name Requested Personal salutation in email no
Role Requested (chips) Check-writer signal for scoring no
Phone Not collected in pilot TCPA and Texas SB 140 exposure; email-only follow-up no
Consent (email) timestamp and text version Captured CAN-SPAM proof auto
Defined set (str_numbers, source printed/manual/roster) Requested (picker) Exact-set rebuild, roster for the audit, intent signal arm B yes, arm A no
Self-reported June occupancy and average rate Requested, optional, phase 2 Lets the GM line up their own numbers without any file no
Founding reserve flag Requested (button) Waitlist before checkout exists no
Stripe customer and subscription IDs, status, period end Captured by webhook Entitlement on subscribe
Session key Issued once after unlock Lets the lead edit its set later with no account auto
Upload consent, data policy, purge_after (phase 2) Captured Retention and deletion proof on upload

6. State and flow diagram

flowchart TD
  A[Scan QR or type URL] --> B{r/code valid?}
  B -- no or void --> U[Unknown code page: retype code or find hotel] --> G
  B -- yes --> C[Log mail.scan, 302 to destination]
  C --> D[Known hotel, zero input: whole area, suggested 13, your set empty, 3 tiles]
  D --> E{Open the full June report}
  E --> G[Unlock sheet: work email, name, role]
  G -- fail --> G
  G -- success --> H{Arm}
  H -- A --> R[Full June report on screen + emailed link]
  H -- B --> P[Set picker required: tick 4 to 12] --> R
  R --> P2[Choose the hotels that matter, optional] --> R2[June rebuilt on exact set, copy re-sent]
  R --> O[Founding-member card: $9 a month]
  R2 --> O
  O -- checkout live --> K[Stripe Checkout] --> W[Webhook: entitlement, confirmation email]
  O -- not live --> V[Reserve founding spot: wants_founding]
  W --> M[Monthly issue when set members have filed, week of state publish]
  V --> M2[Email when July is ready, pay $9 then]
  R --> F[Follow-up: email only, capped]
  R2 --> X[Phase 2 members: STR upload shortcut] --> X1{xlsx?}
  X1 -- no --> X2[Unsupported: pick by hand]
  X1 -- yes --> X3[Parse in memory: subject line + roster] --> X4[Purge file within 7 days] --> R2

7. Tracking events and attribution

Events land in a new funnel_events(event, code, token_id, lead_id, props, ts) table, service-role writes only; Resend webhooks write email.delivered, email.opened, email.clicked into the same table (Woz lens). No PostHog for 1,000 pieces.

Event Properties
mail.scan code, s (q or typed), user_agent, referrer, cf_country, outcome (ok, unknown, void), first_or_repeat derived in SQL
page.view code, step
gate.start / gate.submit / gate.success code, role, error
report.view code, period, arm
set.edit / set.save code, added, removed, size, source (printed, manual, roster)
self_report.submit code
founding.view / founding.reserve code
checkout.start / checkout.complete code, lead_id, stripe_subscription_id
issue.sent / issue.opened subscription_id, period, completeness (n of N)
upload.start / upload.success / upload.reject / upload.delete (phase 2) code, reason
unsubscribe lead_id

Attribution fields on teaser_tokens: channel, campaign, batch, variant, mail_piece_id (unique), report_period, printed_set jsonb, printed_snapshot jsonb, mailed_at, expires_at, status, destination. Dashboard: one SQL view per variant (mailed, unique scans, QR vs typed, gate submits, sets saved, reserves, paid), emailed daily through the existing daily-ops email pattern.

8. STR-upload privacy and retention, and the no-upload alternative

Position (confirmed with Ace 2026-08-18 evening): do not accept the file in the free path, ever. Ship "pick your hotels" instead (60 seconds of clicking on a page that already lists the printed 13). The upload ships as a paid-member convenience with the July issue (phase 2), never on the printed piece or in the free report. In parallel, Woz emails integration@str.com asking for the written data-sharing path that Cloudbeds and HotelIQ hold (the "express written consent" Sec. 4.2 names); a yes widens the upload, a no leaves the roster-only member convenience or removes it, with nothing else in the funnel changing. One attorney hour before the July issue: Sec. 4.2/4.4 plus the consent copy below, and the origin of the "STR tract" and "STR ID" labels printed on the mailer. When the upload ships, the requirements are:

9. Lead scoring and follow-up rules

Scores are proposals; the pilot calibrates them.

Behavior Score Meaning
Scan, no form 10 Weak; no contact exists, no follow-up possible; the second mail touch is the follow-up
Contact captured 30 Warm
Report opened twice or copy forwarded +20 Interested
Set defined 50 Real prospect (the commitment act)
Upload (phase 2) 60 Strong intent
Founding reserve 70 Hot
Subscribed 100 Customer

Multipliers for the platform (management companies are the core customer): email domain matches a census management_company (11 of the 14 sample hotels carry one, research/07); role Revenue or corporate; one domain across two or more tokens (a company reading its portfolio). Any multiplier fires a human touch within one business day; everything else stays on email-only nurture.

Follow-up sequence (email only, max one message per week, unsubscribe on every one, physical address in the footer):

10. The smallest credible experiment (first 500 to 1,000 pieces)

11. Hormozi's position, panel record, unknowns, next action

Hormozi (independent, Claude persona, sourced to his corpus): D, tightened. "The file is not the value. The roster is." Contact information: agree. STR upload: dissent, "not on strangers, not in drop one, never as the price of a free report." Value Equation: the upload loads time delay and effort at step one; the audit needs only the roster; the upload filters out the best leads (management-company people who know the clause). Strongest objection to himself: Ace is right that email alone buys tire kickers; the answer is that naming the set is the act, and whether it must come before the report is the test. Evidence that would change him: arm B holding 70%+ of A's unlock rate with better $9 conversion (make the set required, still no upload); CoStar offering a written consent path (upload becomes a member option sooner); hand-named sets diverging badly from uploaded rosters. Founding terms proposed, none printed: qualifies = any hotel from this mailing that subscribes before the July report ships; cap set by Ace and shown at checkout only; $9 held for the first 12 months, not forever, delivery cost unmeasured; cancel any time; first paid report refunded on request. Directive: "ship the token route and the set-naming step. Hold the upload. Mail 500."

Panel record. Ive: D; the paper made a promise, the first screen must keep it before it asks; objection: naming all 47 at zero input may make the email step feel thin. Wynn: D with set definition as the real gate; would run an arm with the upload required to test Ace's hypothesis directly (not adopted: the intake path is unsafe and star@ is unrouted); STR retention subject-only plus roster. Woz lens: D on feasibility and honesty, A as fallback; upload deferred out of the pilot; picker is the long pole; nothing on paper may promise what is not deployed on print day. ChaseAI (Gemini, cross-vendor): D; the funnel dies in the first 30 seconds if the phone is asked for a file; skip the upload for the first batch; stop and fix the paper if scans stay under 2% (his threshold); do not put "STR" in the product name. Consensus formed independently on the same raw evidence, with a contrarian seat present.

Agreement. Contact info before the full report; zero-input value first; naming the set is the commitment; upload never gates the free report; STR retention subject-only plus roster when it ships; email-only follow-up; typeable URL beside the QR; no "STR" in the product name.

Dissent preserved. How much to name at zero input (Ive's arm for drop 2: whole area named vs rank and count only). Whether to test the upload as a required arm at all (Wynn yes, others no). Whether the set step should be required or optional (the drop-1 experiment).

Unknowns.

Next action. Woz builds the pre-print list in section 12 starting with the migration and the /r/ route. Ace answers the five decisions in section 12 and opens the Stripe account now (the account, not the code, is the blocker).

12. Engineering handoff and Ace decisions

Before any piece prints (6 to 7 dev days sequential per the Woz lens sizing in panel/woz-lens.md section 8, an estimate not a measurement; the picker is the long pole):

  1. Migration: teaser_tokens new columns, teaser_leads new columns, funnel_events, lead_defined_sets, member_subscriptions (S).
  2. Per-piece token mint with a real collision retry, printed set and snapshot stored, CSV for the print run, QR at version 3 with a clean quiet zone (S).
  3. landing/functions/r/[code].ts Pages Function on the revpar-pro project with logging and 302, plus a CI job to deploy landing/ (S). Unknown-code page.
  4. Engine printed mode: buildMarketSet loads the 13 printed ids (S).
  5. June report page at /t/{code}: zero-input landing, unlock sheet, full report, picker with radius-limited search, arm switch (M).
  6. Founding reserve button (XS). Remove the fake locked rows and the score from the public page.
  7. QR quiet-zone fix on the mailer, typeable URL under the label (XS). Within two weeks after drop: Stripe Checkout plus webhook (S, blocked on the account), follow-up emails (S), variant dashboard (S). Before the first July issue: report_issues generator triggered after the daily 6 AM sift-sync when the set's members have filed (M). Deferred: public STR upload (phase 2, members first, section 8), PDF rendering, tract-movers tile (needs a review gate). Broken promises if slipped: "your own set of the hotels that matter" (picker), "keep it coming" (generator by the July issue), "$9 a month" (checkout within two weeks), and every scan if the quiet zone stays wrong.

Ace decides (one line each):

  1. Founding terms: accept the proposals in section 11 or change them.
  2. Product name for the checkout and landing page (no "STR" in it).
  3. Mail list: 438 (both bands, two markets) or 315 core, and whether Houston joins drop 1.
  4. Return address for the piece.
  5. Merchant account: does a Stripe account exist anywhere; if not, open one this week.

Sources