Dashboard
Sites
listing status, tenant, routing, calls in this range. Pause routing when a tenant is on vacation or behind on rent.Clients
who rents what, whether they are paid up, and how many leads each site sent them. Click a row to open the client.Rent roll
monthly rent minus Twilio number cost. Mark paid through when the tenant pays. Not Stripe billing — just the ledger you look at.Phone numbers
Every Twilio number on this account, which site it rings, and who it forwards to. Rent first, then assign. Unassign keeps the number (Twilio still bills). Release deletes it.
Rent a number
Twilio webhook URLs
Site setup
Listing is yours. Tenant tab is what they will log in to change. Numbers stay under Landlord → Numbers.Unique visitors
per day for the selected rangeToday's forecast
projected end-of-day totals from the last 7 days' hourly curveTop Sources
Top Pages
Devices
Widget Placements
Sources
last 30 minDevices
last 30 minWidget clicks
last 30 min — these are the money momentsthree different populations, do not add them up · AI-referred = a person arrived from ChatGPT / Perplexity / Copilot / Gemini (channel "AI Assistants") · agent-capable = the visitor's browser exposes an in-page agent API (Edge Copilot Mode) — capable, not necessarily active, so an upper bound · tool calls = a page-declared WebMCP tool was actually invoked — the real activity signal, zero until the sites ship tools
Do agent sessions still see the widget?
the WEBMCP.md gate · if agent-capable sessions view or click the widget less than everyone else, on-page agent tools are costing revenue · leads born in agent-capable sessions carry the--muag placement marker — agents must never submit the Esy form, so a rising count is a warning, not a win
AI assistants sending people
referrer-based · humans, not botsAgent-capable browsers
wherenavigator.modelContext existsWebMCP tool calls
each tool a page declared and an agent invoked · fired viamuaAgent()By site
a site on a tracker older than 2026-09-06 cannot report agent-capable visitsPages agents reach
pageviews by agent-capable and AI-referred visitorsMonetization Funnel
where visitors drop out between landing and earningTraffic, no widget seen
widget missing or below the foldSeen, never clicked
weak placement or listingsClicked, no revenue yet
leads not converting on Esy's sideMovers vs previous period
Gainers
Losers
Page decay
second half of the selected range vs the first half — money pages quietly slidingRevenue decaying
Traffic decaying
Engaged vs. Earns
each bubble is a page (size = visitors). Top-left = deeply read but under-monetized — your best widget-placement opportunities.Content Performance
every page's traffic, engagement, and revenue side by side — click a column to sort. RPM = revenue per 1,000 pageviews.Web Vitals
real-visitor page speed (p75, Google's threshold percentile). LCP = load, CLS = layout shift, INP = responsiveness. Green meets Google's "good" bar; red is "poor" and can cost rankings.Inside this silo
each row is the next level down — click a folder to drill in · Δ compares the previous period of the same length · new = first pageview ever landed inside the selected range · search clicks/impressions come from Search Console when imported · click a column to sortEsy widget coverage
each sub-silo with the Esy widget ids its pages show · dedicated = a widget that lives mostly on this silo · shared only = just the generic widget every silo gets · no widget = traffic but no impressions · sorted by visitors, so the top gaps are the ones worth a program-specific widgetContent cohorts
pages grouped by the month they first got a pageview, followed month by month since — is this month's new content earning like last month's did at the same age? · cells are per page so cohorts of different sizes compare · the oldest cohort holds every page that predates trackingImprove — striking-distance queries
search queries ranked 4–20 on pages that already earn revenue. These are the cheapest wins: better internal links, refreshed content, or a dedicated page pushes them to page one.Write — under-built high-RPM trades
trades that earn far more per pageview than the portfolio average but have thin content. Headroom = monthly $ if traffic grew to the portfolio's 75th percentile at current RPM.Refresh — decaying earners
pages whose revenue or traffic dropped sharply between the first and second half of the period. Rescue these before rankings follow the trend.Geo & Trades Performance
Rolled up from page URL slugs across every site — pageviews, widget CTR, conversions, revenue, and RPM per dimension. Click a column header to sort.
Search Performance
Search clicks & impressions joined to revenue by landing page. Revenue / query distributes each page's conversion revenue across the queries that drove its clicks — which search terms actually feed the money pages. Import data in Settings → Data & Integrations.
A/B Experiments
Whole run per test, not the date range. Start one withdata-experiments="name:2" on the tracker tag.Tracking Health
Per-site last-seen pageview, tracker version, and 24h volume. A site going silent during active hours is the earliest sign of a broken tracker (the worst kind of outage — silent data loss).
Alerts
Conversion data freshness
Backups & delivery
Esy Widget Performance
impression → view → click funnel from the tracker · conversions & revenue from your CSVs, joined by unique placement IDsClick economics by widget type
listing (request-info) vs search (find-schools) — which widget kind earns the clicksSchool economics
clicks on each school's widget card · conversions counted only after click tracking began, so $ / click compares like with likeWidget ranking
the live card order the sites fetch from/widget-ranking · auto-ranked by all-time $ / lead · type a slot number to pin a school there no matter what the maths say, ✕ to let it float again · sites pick up changes within ~25 min
Payout changes
schools whose $ / lead over the last 30 days moved 25%+ against the 90 days before — Esy changes payouts without notice, and this is where it shows · also fires the payout_change alertPayout per lead by month
each school's average payout per lead, month by month (lead count underneath) · top schools by revenueWhat gets clicked
which card element earns the click — school name vs logo vs button vs program linkYouTube
By day
YouTube revises recent days · AdSense revenue finalizes ~2 days laterTop videos
last import windowAmazon Associates
Clicks are first-party. Earnings come from an Associates Central Orders/Earnings CSV.
By
Recent orders
from the last uploaded Associates report · ship date, not click dateForm leads
Form snippet
Paste into a Hugo template. Keep the consent checkbox wording; the script stores the exact words shown.
Calls by
Recent calls
newest first · page from the tel/sms tap just before the ring · tag booked/spam and block junk callersBlocked callers
hangs up immediately on the next inbound. Leave site blank to block across every site.Revenue Attribution
Pacing
month-to-date vs the same day last month, then the year on the current paceThis month
Year
Time to convert
widget click to Esy payoutPath to conversion
page journey of recent converters, exact-attributedRecent Conversions
Manual adjustments
revenue with no per-conversion CSV row, such as Esy's "3rd Party Aggregators" lineAdd an adjustment
Added to the chosen day's totals. Re-entering the same site, date and label updates the amount.
Accounting — estimated vs. paid
Estimated = revenue we tracked (conversions). Paid = what you enter from your Esy statement. The difference surfaces scrubbing / bad-lead clawbacks. Negative = paid less than tracked. Click a Paid cell to edit.
AI Briefs
compiles the selected sites + period into a markdown report with an analysis prompt — copy it into ClaudeYour account
Scan this with Google Authenticator, 1Password, or Authy, then enter the 6-digit code to turn on two-factor:
Or enter manually: