Self-booking launch · companion doc

Engineering & HubSpot notes

The dependency list + "here's what already exists" reference behind the marketing plan. For Vlad T, Codrut & ops — not marketing's build. The marketing plan lives in its own doc (review-board.html); this is the technical companion so nothing surprises us on launch day.

3 things to lock before Monday the launch gates

Lock 1
Attribution has to survive the booking page
If the new booking page doesn't carry the ad tag (hsa_ad) + UTMs, every booking looks like it came from nowhere — we can't tell which ad or keyword worked, and the whole cost-per-attended read goes dark.
Fix → verify the ad tag + UTMs pass end-to-end, booking → HubSpot.
Lock 2
Reuse the contact by phone, tag the brand
The booking system should look up the phone number and reuse an existing contact (not make a second one), and stamp PRE vs Serenium — or the same person becomes two records and gets double-branded texts (the live bug). HubSpot won't do this on its own; it only auto-merges by email.
Fix → upsert-by-phone + brand tag at book-time (booking system, or paid Ops Hub automation).
Lock 3
Switch off the old chase for self-bookers
A self-booker already sitting in the old "please book" SMS cycle keeps getting it — removing them from a list doesn't stop a sequence already running. So they'd get "You're booked ✓" and "Attempt 4: call us to book."
Fix → add a "if booked, exit" rule to every old workflow; test it actually unenrolls a seed contact.

The flow is already built "Booking v3" · real HubSpot fields

These are real fields that already exist in HubSpot (confirmed via the API). Marketing doesn't need a new property architecture — it just reads these and attaches copy. The property names in early drafts (self_book_status, verification_path, etc.) were illustrative; the real ones below already do the job.

Real field (exists today)What it is / what it drives
booking_v3_intake_status contactIntake progress — drives the intake nudges.
self_book_json contactThe self-booking payload — proof the self-book path is already wired.
njmmis_eligibility + njmmis_verified_at contactNJ Medicaid auto-verification — this is the "instant" Medicaid path.
insurance · active_insurance · insurance_carrier · qualify_insurance · primary_insurance contactPlan + eligibility info — drives every eligibility message.
appointment_source dealThe real "self-book flag." Bookings live on the existing appointment deal — no separate pipeline needed.
appointment_status · appointment_timeslot · appointment_type dealThe booking itself, on the appointment deal.
n1st_appt_date contactFirst appointment date — reminders + no-show logic.

The one marketing ask to engineering

  • Tell marketing exactly which field or event flips on each moment — booked · intake started · intake complete · each eligibility result (good / maybe / bad) — with the timing. That's all that's needed to point the copy at the right trigger.

HubSpot & ops viability native · needs-more · risky

The engine is mostly native HubSpot. What decides whether Monday works lives outside the parts marketing controls: the booking system writing clean/deduped/brand-tagged data, how fast workflows fire, the dialer (external), and where SMS actually sends from.

ComponentVerdictNote
State properties + branch-on-value workflowsnativeFields already exist (above). Real cost is who writes them + when.
SLA holding workflow (delay → escalate)nativeWorks only if the resolved eligibility is written back to HubSpot.
Switch off old attempting-cycle for self-bookersriskyNeeds an exit rule on every old workflow. Most likely launch-day bug.
"Instant" confirmation from a workflowriskyWorkflows lag seconds-to-minutes. The booking system should send the instant "you're booked."
Reuse contact by phone before enrollmentnot automaticHubSpot auto-merges on email, not phone. Needs the booking system (upsert-by-phone) or paid Ops Hub automation.
Send SMS from workflowintegrationSent via the phone-system SMS integration wired into HubSpot (logged as NCC PhoneSystem). Confirm the actual provider + where STOP / opt-out / quiet-hours / 10DLC live.
Webhook / custom-code actionsOps Hub ProConfirm we have it — the phone-dedup path assumes it.
booked → verified → attended → revenue reportneeds BigQueryAttended = AMD/EHR; revenue = separate Financial-Only EAT-* deals. A join, not a HubSpot report.

Open questions & decisions

Needs a call in the room (Peter / ops)

  • bad → can't book off-ramp: self-pay / waitlist / referral? (blocks the pending-review + off-ramp copy)
  • Medicaid-forward vs plan-agnostic as the default paid angle.
  • Callback SLA the call center can actually hit — before we promise "we'll call within X." Confirm the real Medicaid vs commercial split (the "~40%" was an estimate).
  • Soft-launch scope — PRE-only Monday, Serenium later?
  • Order is now decided (10 Jul call): book first, verify in the back office. Open: SLA on the back-office verification, and who writes the copay/coinsurance/deductible back to HubSpot so comms can send the cost message.

Confirm with Vlad T / Codrut before build

  • Exact field/event that flips on book, intake-started, intake-complete, and each eligibility result — names + who writes + timing.
  • Does the booking system upsert-by-phone, stamp brand, and preserve the ad tag / UTMs? Does it send its own instant confirmation?
  • Is the intake form HubSpot-native or external? Does it fire distinct "started" vs "complete"?
  • Is the dialer HubSpot tasks or a synced tool (Aircall / Kixie)? Who writes the eligibility result back to HubSpot?
  • Do we have Ops Hub Pro? What's the actual SMS provider, and is STOP/opt-out synced into a suppression field? Is A2P 10DLC registered, separate numbers per brand?

From the 10 Jul call — Vlad T's engineering tasks

  • A/B funnel tracking: instrument booking-first vs intake-first paths so dropout + conversion are readable over the 2-week window (marketing reads it).
  • Returning-patient copy: the returning funnel must state the 6-month rule (seen >6mo ago → new-patient intake).
  • Finalize HubSpot flows on the new book-first structure; preserve hsa_ad/UTMs through the booking page.

Peter's 7 points — the HubSpot mechanics reference

The message for each of these lives in the marketing plan (the comms journey). Here's only the HubSpot plumbing behind each.

1 Patient-facing messaging
Message the state, never a promise
HubSpot → copy lives in workflow SMS/email actions, keyed off the state fields.
2 Follow-up sequences
Confirm → intake → resolve
HubSpot → one workflow per trigger (booked · intake complete · eligibility resolved), branching on payer + eligibility.
3 HubSpot logic / lifecycle
Read existing fields + suppress old lists
HubSpot → map self-bookers to SQL/Opportunity; exit-rule the old workflows; dedup + brand-tag at book-time.
4 After someone self-books
Confirm the appointment, not the insurance
HubSpot → booking system sends the instant confirm; HS runs backend + sets deal stage on appointment_source.
5 After intake start / complete
Nudge the unfinished, congratulate the done
HubSpot → branches off booking_v3_intake_status; completion → appointment reminders.
6 Manual cases — Medicare / EAP
Reassure, hold the spot, promise nothing
HubSpot → carrier fields route to a call task + holding sequence; no auto-cancel.
7 Pending / needs staff review
Never a dead end
HubSpot → pending → holding workflow + SLA timer (delay → escalate); bad → off-ramp workflow (content pending policy).