Estimate open and read-time tracking

The portal records who opened an estimate, when it was first opened, and how many seconds they actually spent reading it.

What it is

A visibility-aware timer on the estimate page that accumulates only the seconds the tab is actually visible, flushing every 30 seconds and guaranteeing a final flush on unload via sendBeacon. The server stamps first-open on the link, logs an estimate-opened notification once, and accumulates total time on the viewer row.

Also called: did they open my quote · how long did they look at it · estimate opened alert

See it, piece by piece
01

You hear about it the first time they open the quote

Following up was a guess: call the same day and you are nagging, call Friday and somebody else has been out to the site. The first open stamps the estimate and fires one alert to whichever roles you route it to, in the bell and by email. It fires once for the deal rather than once per page load, so a buyer who opens it four times on a Sunday night does not produce four alerts on a Monday morning.

Settings — Notifications
Notifications
Pick which roles get notified for each event. Project-level assignees (set on each project’s detail page) always receive project notifications regardless of the role toggles here.
Notifications are on for this account · since 3/14/2026Stop all notifications for this account
All notifications
22 events · 14 sending email · 22 showing in the bell.
Turn off all emailTurn off all notifications
Covers every event in the table below. Alerts sent by your build-stage automations are configured separately under Settings → Stage Automations and are not affected by this switch.
EventsEveryone (by role)
ShowAllInternalTo customersCategoriesSingleMultiple
EventAdminSalesProject ManagerCrew LeadWorkerChannels
Sales Pipeline· 4
New lead
A new lead entered the pipeline (ad form, website form, GHL merge, or manual add).
In-appEmailSMS
Lead assigned to you
A lead was assigned to a rep (distribution engine or manual).
In-appEmailSMS
Follow up: new lead not contacted
A new lead has gone 4h without contact.
In-appEmailSMS
Lead import completed
A bulk lead import finished (the ONLY notification bulk imports emit).
In-appEmailSMS
Estimates & Orders· 4
Estimate sent
Customer received the estimate link.
In-appEmailSMS
Estimate opened
Customer opened the estimate for the first time.
In-appEmailSMS
Estimate approved
Customer approved the estimate.
In-appEmailSMS
Project info submitted
Customer filled out the intake form.
In-appEmailSMS
Project Management· 3
Project started
Someone clicked Start Project on an estimate.
In-appEmailSMS
Project stage completed
A build stage was marked complete.
In-appEmailSMS
Project completed
Final stage was marked done.
In-appEmailSMS
Estimates & Orders → Estimate opened, with the roles and channels it goes to. The real screen, drawn from the product’s own design system. Sample data — no customer information appears here.
02

Read time, because ten seconds and twelve minutes are different calls

The quote counts only the seconds it is actually the tab in front of somebody, and stops the moment they switch away. A glance and a real review arrive as two different numbers instead of one identical open event. Totals are capped at a day, so a tab left open on a laptop overnight cannot report as twenty-four hours of interest.

Custom Building Estimate
Cedar Hollow
Cedar Hollow Builders
Custom Building Estimate
Zimmerman Equipment Barn
Prepared for Marla ZimmermanAugust 24, 2026
Building
40′ × 64′ × 16′
Footprint
2,560 sq ft
Roof pitch
4/12
Your investment
$84,320.00
Review & approveView your 3D building
Private, encrypted link prepared for youValid through September 23, 2026
Pricing held for
6d 04h 17m 38s
The page the timer runs on — seconds accrue only while this is the visible tab. The real screen, drawn from the product’s own design system. Sample data — no customer information appears here.
03

It tells you who opened it, not just that somebody did

Time is recorded against the viewer who identified themselves on the link, so a quote forwarded to a spouse, a business partner or a lender shows up as a second reader rather than as more minutes on the first. A buyer who sends your document on has moved, and that is worth knowing before you pick up the phone.

04

Checking your own quote never trips the alert

A builder opening their own customer link used to mark the estimate as read, so the one signal worth acting on was the one you could not trust. Internal visits are excluded where the page records and again where the server writes — shutting one door and not the other changed nothing, because the heartbeat tripped the alert a few seconds later anyway. The check runs against the real sign-in rather than anything the browser claims, so nobody opts out of being counted by editing a request.

05

The minutes right before they call you are not the ones you lose

Read time is sent every thirty seconds and once more as the tab closes, using the browser's send-on-exit path so the final stretch still arrives. That last run through the payment schedule before somebody phones is the most informative part of the whole session, and a timer that only reports on a clean page load misses exactly that.

How it works
  1. 1Time accrues only while document.visibilityState is visible
  2. 2A 30s heartbeat POSTs to /api/client-portal/track; unload uses navigator.sendBeacon
  3. 3The route accepts both JSON and beacon text bodies and clamps the reported seconds to 24 hours
  4. 4First open stamps opened_at and fires a once-only builder notification
  5. 5Internal platform visits are excluded, verified against the real session
Why we built it

Knowing a quote has been opened four times is the difference between calling with a reason and calling to nag. For a stretch the tracking never ran at all — it read the wrong storage under the wrong key, so it exited immediately and no read-time was ever recorded, and builders were following up blind while believing they had data. Builder previews are excluded on both the page and the recording endpoint, since fixing one door and not the other fixes nothing, and the check runs against the real platform session because trusting the browser would let a customer opt out of tracking by editing a request.

The problem
  • No signal on whether a quote was read
  • Follow-up timing based on guesswork
  • Builder previews firing false open alerts
Sound familiar?
What you get
A first-open alert tells the builder when to call
Read-time separates a glance from a serious review
Only genuine customer visits are counted

See it on your own jobs

Twenty minutes, your numbers, no slide deck. We’ll build one of your real buildings in front of you and send you the estimate link at the end — yours to keep either way.

or keep browsing features →