Website Visitor Funnel Classifier and Routing
A prioritized list of recent website visitors, scored and sorted by buying intent.
Sample result
Run live demo| Company | Contact | Funnel Stage | Intent Score | |
|---|---|---|---|---|
| 1 | Keystone Networks | Bastian Silva, Head of Ops | Sales Now | 92 |
| 2 | SmileBright Centers | Dr. Anya Sharma, Clinical Dir. | Sales Watch | 71 |
| 3 | New Horizons Dental | Carla Ruiz, Practice Mgr | Net New | 65 |
| 4 | OrthoPartners Inc. | Leo Valdez, IT Manager | Nurture | 58 |
| 5 | Affinity Dental | (anonymous) | Support | 23 |
Example run
“Show me the most interesting website visitors from the last week.”
Found 152 visitor sessions in the last 7 days across 28 identified companies.
Identified potential contacts for top companies, including Bastian Silva at Keystone Networks and Dr. Anya Sharma at SmileBright Centers.
Scored all visitors. Keystone Networks is 'Sales Now' (92) after visiting the pricing page. SmileBright Centers is 'Sales Watch' (71) due to multiple visits.
Recent Website Visitor Analysis
Who it's for
Sales and marketing teams who need to find qualified buyers from their website traffic.
What it does
This skill analyzes recent website visitors, classifies them by funnel stage (e.g., Sales, Support), scores their buying intent, and recommends a specific next action for each lead.
What you need
Connect your website analytics platform. The skill analyzes data from the last 14 days by default, but you can specify a different time window.
What you get
A downloadable list that separates high-intent prospects from noise, so you know exactly who to contact first and why.
How it works
See the full instructions
Website Visitor Funnel Classifier
Turn recent website activity from Expertise Live into a filterable, signal-scored CSV that separates support and noise from real buyer signals. The default output is operational, not presentational.
What This Skill Does
- classifies recent Expertise Live activity into funnel buckets
- scores each row using a fixed signal model
- produces a CSV by default
- includes the best available contact and enrichment context
- gives a plain-language recommended next step for each row
- avoids CRM writes unless the user explicitly asks for a separate CRM-aware variant in a future run
What This Skill Does Not Do
- do not write to CRM by default
- do not route records externally
- do not handle live chat responses
- do not return a transcript-only summary when a CSV would be more useful
- do not infer customer or pipeline status without explicit evidence
Primary Systems
Use these systems in this order:
- Expertise Live
expertise_ai.get_metricsexpertise_ai.list_conversationsexpertise_ai.list_leadsexpertise_ai.list_recent_recommended_contactsexpertise_ai.get_conversationonly for 2 to 5 standout rows that need message inspection
- Expertise Enrichment only when top-priority rows still lack contact context
- Public web research only when the user explicitly asks for extra signal context beyond what Live provides
- Do not use HubSpot, Gmail, or Slack by default. Only use them if the user explicitly asks for a CRM-aware, customer-aware, or communication-aware overlay in that run.
Default Time Window
- If the user specifies a window, use it.
- If no window is specified, use the last 14 calendar days in the user's timezone.
- Interpret phrases like
today,yesterday,last week, andlast 2 weeksin the user's timezone, then convert the start and end to UTC for tool calls. - If the user asks for more than 30 days and does not explicitly ask for a full export, use the most recent 30 days and say so.
Exact Operating Procedure
Step 1. Count the window
Call expertise_ai.get_metrics for the selected window with:
group_by="day"include=["conversations","leads","unique_visitors"]
Use this for the summary counts in the chat reply.
Step 2. Pull conversation candidates
Call expertise_ai.list_conversations with:
begin_time=<window start in UTC>end_time=<window end in UTC>page_size=100include_pii=trueinclude_total_count=truesort_by="last_updated_desc"min_messages=2
Paginate until one of these is true:
next_page_tokenis null- 3 pages have been pulled
- 300 conversations have been collected
Step 3. Pull lead candidates
Call expertise_ai.list_leads with:
date_range=[<window start in UTC>, <window end in UTC>]page_size=100include_pii=trueinclude_context=trueinclude_total_count=true
Paginate until one of these is true:
next_page_tokenis null- 3 pages have been pulled
- 300 leads have been collected
Step 4. Pull identified-company candidates
Call expertise_ai.list_recent_recommended_contacts with:
company_limit=100contact_limit_per_company=3include_pii=truelookback_minutes=<window length in whole minutes>
Step 5. Only fetch detailed transcripts for standout rows
Do not fetch every conversation thread.
Only call expertise_ai.get_conversation for 2 to 5 rows that are likely to be shown in the final summary and where the preview text is not enough to classify safely.
Step 6. Normalize entities
Use this company key logic in order:
- email domain when available
- website domain when available
- lowercase company name
- anonymous conversation rows use
conversation_id
Step 7. Deduplicate with fixed precedence
If two rows collapse to the same company key, use this precedence:
- conversation row beats identified-company row
- identified-company row beats lead-only row
- if neither row has a conversation, keep the stronger funnel bucket
- if the bucket is tied, keep the higher signal score
- if the signal score is tied, keep the newer signal date
- if the signal date is tied, keep the row with more contacts
Step 8. Select one primary contact per row
Choose the primary contact in this order:
- contact directly linked to a conversation
- highest seniority title
- validated email present
- most recent signal date
Seniority Ranking For Contact Tie-Breakers
Use this exact order:
- founder, co-founder, owner, ceo, president
- c-suite, vp, head, director, partner
- manager, lead
- individual contributor or specialist
- unknown
If titles tie, prefer validated email, then the newest signal.
Funnel Buckets
Use only these buckets:
sales_nowsales_watchcustomer_expansionsupportnurturesuppressnet_new_identifiedunclear
Signal Context Layer
Each surviving row should carry signal context, not just a bucket.
Capture the strongest signal hits using these exact signal names where applicable:
direct_demo_intentpricing_or_packaging_interestsupport_or_access_issueproduct_education_onlysensitive_or_test_datarepeat_company_activitysenior_contact_matchmeeting_bookedexplicit_customer_contextidentified_company_only
For each row, keep:
top_signals: 1 to 3 strongest signal names joined by;signal_confidence:high,medium, orlowplay_namewhy_now
Use these default plays:
direct_demo_playpricing_interest_playsupport_cleanup_playcustomer_revisit_playidentified_watchlist_playsuppress_noise_playeducation_nurture_playunclear_monitor_play
Deterministic Classification Rules
Classify each surviving row into exactly one bucket.
A. Conversation rows
Start from the conversation category, then use visitor text, then fallback.
1. support
Use support when either condition is true:
- conversation category is
support - or the visitor text contains any of:
loginaccountpasswordbillinginvoiceissueerrorsupporthelpmigratemigrationsetupchatbot environmentchatsimple
2. sales_now
Use sales_now when the visitor text contains any of:
demobook a demopricingquotetalk to salesimplementationrolloutprocurementcontractenterprise planschedule a call
3. nurture
Use nurture when:
- conversation category is
product - or the visitor text is educational and contains any of:
workflowhow it worksuse casefeaturecase studyproof pointwhat isdifference between
- and none of the
sales_nowterms are present
4. suppress
Use suppress when the visitor text contains any of:
confidentialmastercardvisaamexpayment cardtest cardcard number
5. sales_watch
Use sales_watch when:
- conversation category is
sales - and
sales_nowdid not trigger
6. unclear
Anything not captured above becomes unclear.
B. Identified-company and lead-only rows with no conversation
1. customer_expansion
Only use customer_expansion when at least one of these is true:
- the source explicitly marks current-customer activity
- the row carries explicit customer wording in source context
- the user explicitly asked for a customer-aware overlay and that overlay confirms customer status
Never infer customer_expansion from company fame, brand recognition, or account familiarity alone.
2. sales_watch
Use sales_watch when at least one of these is true:
meeting_bookedis true- the same company has 2 or more recommended contacts in the selected window
- the primary contact seniority rank is 1 or 2 and the company has a non-empty company description
3. net_new_identified
Use net_new_identified when:
- the company has identified contact context
- there is no linked conversation
sales_watchdid not triggercustomer_expansiondid not trigger
4. unclear
Use unclear when:
- the company has weak or partial data
- there is no linked conversation
- no contact context was found
- and the row does not qualify for a safer bucket
C. Never promote identified-company traffic directly to sales_now
A deanonymized company visit alone is never enough for sales_now. It needs a real buying conversation, a meeting-booked signal, or another explicit high-intent trigger.
Signal Scoring Model
Score every surviving row on a 100-point model:
- intent strength: 0 to 35
- recency: 0 to 20
- contact path: 0 to 15
- enrichment quality: 0 to 15
- activity density: 0 to 15
1. Intent strength
- direct demo, pricing, procurement, quote, or contract intent: 35
- sales category without direct high-intent wording: 20
- product education or feature exploration: 10
- support or access issue: 5
- sensitive or test data: 0
2. Recency
- 0 to 3 days old: 20
- 4 to 7 days old: 15
- 8 to 14 days old: 10
- 15 to 30 days old: 5
3. Contact path
- conversation-linked contact: 15
- senior contact with validated email: 12
- validated email only: 8
- name only: 4
- no contact: 0
4. Enrichment quality
- company description plus title plus email plus LinkedIn: 15
- title plus email plus one of description or LinkedIn: 12
- name plus title plus email: 10
- partial contact only: 5
- none: 0
5. Activity density
- meeting booked or conversation plus multi-contact company context: 15
- 2 or more matched contacts in the window: 10
- single identified contact: 5
- none: 0
Penalties
Apply these penalties after scoring:
- sensitive or test data: set score to 0
- ambiguous entity match: minus 10
- no contact on non-conversation
sales_watchornet_new_identified: minus 5
Clamp the final score between 0 and 100.
Priority Rules
Priority must be explicit. Use only high, medium, or low.
sales_now: alwayshighcustomer_expansion:highif signal score is 70 or more, elsemediumsales_watch:mediumif signal score is 45 or more, elselowsupport: alwaysmediumnurture: alwayslowsuppress: alwayslownet_new_identified:mediumif signal score is 55 or more, elselowunclear: alwayslow
Enrichment Fill Rules
Only enrich when all of these are true:
- the row is
sales_now,sales_watch, ornet_new_identified - the row has no
contact_nameand nocontact_email - a company domain is available
- the row is among the top 5 highest-priority rows still missing contact context
Use this exact enrichment pattern:
- call
expertise_enrichment_people_searchwith:q_organization_domains_list=[domain]person_seniorities=["founder","c_suite","vp","head","director"]per_page=5
- choose the top candidate
- call
expertise_enrichment_people_enrichfor that candidate - keep the result only if it resolves a usable verified contact
Never enrich more than 5 rows in one run unless the user explicitly asks for a larger pass.
Never enrich support or suppress rows.
Signal Summary Rule
For each row, create one short summary, 24 words or fewer.
- If a conversation exists, summarize the visitor's actual intent.
- If no conversation exists, say what was detected, for example:
Identified company activity with matched contacts and no conversation.Known company revisit with senior contact context and no meeting booked.
Do not invent page-level detail that the source did not provide.
Play Assignment Rule
Assign one play per row using this order:
sales_nowwith direct demo or pricing language ->direct_demo_playsales_watchwith pricing or packaging language ->pricing_interest_playsupport->support_cleanup_playcustomer_expansion->customer_revisit_playsuppress->suppress_noise_playnurture->education_nurture_playnet_new_identified->identified_watchlist_play- anything else ->
unclear_monitor_play
Why-Now Rule
Create one why_now line, 18 words or fewer.
Examples:
Direct buying intent appeared in the selected window.Multiple matched contacts appeared with recent company activity.This row is noise and should stay out of rep queues.
CSV Contract
The default deliverable is a CSV with these columns in this exact order:
window_labelfunnel_filterprioritysignal_scoresignal_confidencetop_signalsplay_namewhy_nowsignal_dateaccount_namecompany_domainsource_typesignal_summaryconversation_urlcontact_namecontact_titlecontact_emaillinkedin_urllocationcompany_description_or_fitrecommended_next_stepnotes
Row limits
- default export size: up to 40 rows
- if the user explicitly asks for more, cap at 100 rows
Bucket caps for the default 40-row export
sales_now: 8sales_watch: 10customer_expansion: 6support: 6nurture: 4suppress: 4net_new_identified: 10unclear: 4
If the export is still under 40 rows after applying caps, fill the remaining slots with the newest leftover rows across all buckets in this order:
sales_nowcustomer_expansionsales_watchnet_new_identifiedsupportnurturesuppressunclear
Recommended Next-Step Rules
Use plain-language next steps only. Do not route into CRM by default.
sales_now:Follow up immediately. Capture identity if missing.sales_watch:Review soon. Watch for repeat activity or stronger intent.customer_expansion:Review for expansion or relationship follow-up.support:Handle through support or onboarding, not sales.nurture:Keep in nurture. Do not escalate to a rep yet.suppress:Suppress from rep queues.net_new_identified:Keep on a watchlist until intent strengthens.unclear:Needs more evidence before action.
Sparse-Data Fallbacks
Use these exact fallbacks:
1. No conversations, no leads, no recommended contacts
- return the counts
- create a header-only CSV
- say no qualifying website activity was found in the selected window
2. Only identified-company traffic exists
- skip conversation-based examples
- build the CSV from
net_new_identified,sales_watch,suppress, andunclearonly - say the window was company-signal heavy and conversation-light
3. Conversations exist but contact fields are missing
- keep the row
- leave contact fields blank
- do not invent contact details
- enrich only if the row meets the enrichment cap and priority rules
Deterministic Standout Row Selection
After the CSV is built, choose up to 5 standout rows for the chat summary in this exact order:
- highest signal-score
sales_nowrow - highest signal-score
customer_expansionrow - highest signal-score
sales_watchrow - highest signal-score
suppressrow - highest signal-score
net_new_identifiedrow
If a bucket has no row, skip it.
Tie-breakers for standout rows:
- newer signal date
- higher contact seniority
- conversation row beats non-conversation row
Good vs Bad Decisions
Good:
- a direct demo request becomes
sales_noweven if the visitor is anonymous - a login or migration question becomes
supporteven if the account looks interesting - an identified company with founder contact context but no conversation stays
net_new_identifiedorsales_watch - sensitive test data becomes
suppress
Bad:
- promoting every identified company to
sales_now - using CRM owner or lifecycle fields when the user did not ask for CRM overlay
- dropping a high-intent anonymous demo request just because there is no contact yet
- guessing customer status from company fame or brand size
Sample Output Row
window_label,funnel_filter,priority,signal_score,signal_confidence,top_signals,play_name,why_now,signal_date,account_name,company_domain,source_type,signal_summary,conversation_url,contact_name,contact_title,contact_email,linkedin_url,location,company_description_or_fit,recommended_next_step,notes
last_14_days,sales_now,high,78,high,direct_demo_intent,direct_demo_play,Direct buying intent appeared in the selected window.,2026-07-13 14:28 EDT,Unidentified visitor,,live_conversation,"Direct demo request on marketplace page",https://app.expertise.ai/conversations?id=example,,,,,Highest-intent buyer signal with no captured identity,"Follow up immediately. Capture identity if missing.","Conversation row outranks identified-company-only rows."
User-Facing Response Contract
After creating the CSV, reply with:
- the time window used
- summary counts for unique visitors, conversations, and leads
- bucket counts for the exported rows
- the file link
- 2 to 5 standout rows chosen by the deterministic selection rule
- any data gaps or caveats
Keep the chat summary short. The CSV is the main deliverable.
Guardrails
- do not write to CRM by default
- do not use HubSpot by default
- do not pretend every enriched company is pipeline
- do not send support traffic to sales just to make the output look exciting
- do not overclaim identity confidence
- do not confuse contact enrichment with sales readiness
- do not present a deanonymized company visit as pipeline without stronger buying evidence
- do not fabricate contact or company fields
- do not enrich more than 5 rows in one run unless the user explicitly asks for a larger pass
More in Target Account Signals
- Sample result
ExpertiseApp9:15 AM
Target account engagement on LinkedInAccount:Sable NetworksContact:Elodie BianchiTitle:Head of Pre-constructionSignal:Liked post on reducing project overrunsSource:LinkedIn - Sample result
New account brief and contacts
Name Title Email Milo Renner Practice Owner milo.renner@foxglovetechvet.com Dr. Anya Sharma Head Veterinarian anya.sharma@foxglovetechvet.com Leo Vance Office Manager leo.vance@foxglovetechvet.com - Sample result
ExpertiseApp9:15 AM
High-intent visit from target accountAccount:Glint LabsTier:Tier 1Signal:Visited pricing & integration pagesTime on Page:3 mins (Enterprise Plans)Contact:Malik Vasquez, Director of Ops