Lead Management
PRD: Lead funnel
Section titled “PRD: Lead funnel”Problem: What problem is this solving?
Section titled “Problem: What problem is this solving?”- Many businesses don’t manage leads very well.
- HoneyGrid loses the conversion signal after sending leads to customers.
- Ads can’t be optimized as well as they could with more conversion data.
Who experiences the problem?
Section titled “Who experiences the problem?”This problem primarily affects:
- HoneyGrid customers who struggle to grow and get a good ROI from their marketing campaigns because they fail to convert the leads we generate.
- The leads who aren’t contacted right away or at all which is a bad experience.
- HoneyGrid because we lose visibility into the lead lifecycle and cannot report deep-funnel conversions (Lead qualified, Appt scheduled, First visit completed) to the Ad Platforms. This lack of visibility makes it difficult to differentiate between bad leads and poor lead management.
Success: How do we know if we’ve solved this problem?
Section titled “Success: How do we know if we’ve solved this problem?”- Acceptance KPI - Leads created in HoneyGrid
- Acceptance KPI - Lead interactions in HoneyGrid
- Correlated KPI - Average time to contact leads
- Performance KPI - Qualified lead rate
- Performance KPI - Converted lead rate
- Insight KPI - Loss reasons, Unqualified reasons
- Core KPI - Cost per lead (CPL)
- Core KPI - Customer acquisition cost (CAC)
HoneyGrid and advertisers will have better visibility into lead quality and conversion rate benchmarks.
HoneyGrid will report conversions to Google, Facebook, Yelp, and Nextdoor which will improve lead quality.
Advertisers will have a way to know and improve their conversion rate.
Solution: How will we solve this problem?
Section titled “Solution: How will we solve this problem?”User stories
Section titled “User stories”- Users can see a list of new leads in HoneyGrid
- Users can move new leads to qualified, scheduled, or close them as lost
- Loss reason = Not qualified
- Unqualified reasons = No response, Medicaid, Service not offered, Insurance out-of-network, Wrong number, Other
- New leads that cannot be contacted within 30 days are automatically closed lost (create a workflow that sleeps for 30 days from lead creation and then closes the lead as lost if it’s uncontacted)
- Loss reason = No contact
- Unqualified reason = No contact
- Users can move qualified leads to scheduled or close them as lost
- Loss reasons = Lost contact, Scheduling difficulty, Price, Other
- Qualified leads that go cold for 30 days are automatically closed lost (create a workflow that sleeps for 30 days from lead qualification and then closes the lead as lost if it’s uncontacted)
- Loss reason = Lost contact
- Scheduled leads must have appointments attached to them
- Appointments are Orders that can be matched through integrated data
- Users can see a list of all past HoneyGrid leads
- Time to contact
- Time to qualify
- Outcome
- Unqualified with reason
- Lost with reason
- Won with appointments
- Users can see their conversion rate, average time to qualify, and average time to schedule
- Users can see a breakdown of their loss reasons
- Leads are automatically moved to scheduled or completed during matchback
- Leads are automatically moved to scheduled when HoneyGrid receives an email notification about an appointment scheduled online
- Phone leads are automatically moved to the correct status and conversion stage
Engineering Spec
Section titled “Engineering Spec”Spec: Lead funnel
Section titled “Spec: Lead funnel”Initial questions
Section titled “Initial questions”- What scope should this project include?
- Data structures
- Contact
- Activity
- Tags
- Screens - Mark will find key screens and define
- Lead list (add fields)
- Lead details (add fields)
- Nav structure update: Leads, HoneyGrid, Settings (with subnav)
- Included:
- View and interact with leads in the HoneyGrid UI
- Not included:
- Automation
- Data structures
- How should we model Contacts / {{Object Name: Opportunities}} / {{Object Name: Order?}}
- Can we label the opportunities differently for various industries?
- Appt requests
- Quote requests
- Can we label the orders differently?
- Appointments
- Jobs
- Should contacts be unique in our system?
- Yes
- Can we label the opportunities differently for various industries?
- Do activities fall within the Contact? Opportunity?
- Required:
- Contact
- Activity type
- Date-time (auto-generated)
- Optional:
- Opportunity => closed won
- Order => set appointments
- Content
- Text
- Files
- Required:
- What events should we count as conversions?
- Contacted
- Qualified
- Scheduled appt (scheduled order)
- Ordered (completed order)
- How should we assign value to conversions?
- There are two types of conversion values to consider — Those reported to the user and those reported to the advertising platform
- Conversion value should be reported to users in terms of value to their business. Integration with CRM/PMS applications will make it possible to calculate a true ROAS for the business
- More granular conversions provide better signals back to the advertising platform’s algorithms to optimize ad targeting. The raw values are not important, but relative values are. We can value conversions on a relative scale such as
- Contacted = 1
- Qualified = 2
- Scheduled order = 5
- Completed order = 10
- What lead statuses should we support?
- What is the conversion id for facebook?
- How do we set up google tracking params to always get gclid?
- How should the HoneyGrid nav/app be structured?
- Leads
- Left panel: Inbox
- Layout: list? Like Remi’s Inbox
- Fields: Name, status, last activity, location (if multiple locations)
- Main content: Lead details and activity
- Left panel: Inbox
- Campaigns (future)
- HoneyGrid
- Media - Property of a location (future)
- Add assets
- Images
- Videos
- Copy
- Headline
- Description
- Calls-to-actions
- How would we handle media with location-specific things?
- Merge tags - Dentist in {{city}}
- Create an asset group
- Add assets
- Settings
- Locations
- Users
- Data sources
- Connections
- Leads
Schema
Section titled “Schema”- Can we record and transcribe the outbound calls?
- How should we handle lead value?
- What is a campaign?
- Grid
- Lead tracking - Phone numbers
- External campaigns (Google, Facebook, USPS)
- Landing pages
- Assets
- What screens are users going to land on?
- Leadboard - Default anything that is not closed, paginated if necessary
- Name (display, search)
- Open/Closed - Contact status
- Status (display) - Contact status?
- New
- Contacted
- Qualified
- Converted
- Phone number (search)
- Email (search)
- Last activity type and date/time (display, filter)
- Location (if multiple locations)
- Lead details
- All based on an ID
- Inbox
- Activity - New messages/interactions
- Leadboard - Default anything that is not closed, paginated if necessary
- How will we want to query this data?
- Event-based
- Harder for list-based queries if we get all the lead metadata
- Status - Which column?
- Source
- Date/time
- Time to contact
- Contacted vs not
- Contacted rate
- Qualified vs not
- Qualified rate
- Closed vs open
- Converted vs not (Conversion rate)
- Event-based
- How can we keep reporting fast?
- Pre-compute/cache
- What layout is best for the lead details?
- Kanban board - Based on Status column
- Inbox
- Left panel is a list of leads sorted by most recent activity
- Last activity date and label
- Tags
- HoneyGrid vs Customer
- 1st contact attempt, contacted, qualified
- 1st contact attempt => 2nd contact attempt
- Table
/** A contact is a potential customer of the business.*/interface Contact { id: string; name: string; // DEFAULT: 'unknown'; email: string; // DEFAULT: ''; activities: Activity[]; // Any sort of interaction with the Contact. This could be a phone call, text message, email, etc. opportunities: Opportunity[]; // For dental, this would be an appointment request. Over time, a contact may request multiple appointments orders: Order[]; // For dental, this would be an appointment. Over time, a contact may have multiple appointments tied to multiple opportunities tags: string[]; createdDate: string; // iso timestamp of the contact creation updatedDate: string; deletedDate: string; // iso timestamp when the contact was deleted lastActivityDate: string; // iso timestamp of the last activity lastOrderDate: string; // iso timestamp of the last order lastOpportunityDate: string; // iso timestamp of the last opportunity}
interface Order { id: string; orderDate: string; // iso timestamp of the order (e.g. dental appointment date) value: number; // This can be populated by industry benchmark or integration with CRM/PMS system notes: string; opportunity: string; // reference to the opportunity that was created from this order createdDate: string; // iso timestamp of the order creation updatedDate: string; // iso timestamp of the order update deletedDate: string; // iso timestamp when the order was deleted verifiedDate: string; // iso timestamp when the order was verified with the customer's CRM/PMS system}
interface Opportunity { id: string; sourceMedia: 'phone' | 'form' | 'online-scheduling' | 'email'; sourcePlatform: 'google' | 'facebook' | 'usps' | null; status: 'new' | 'first-contact-attempt' | 'second-contact-attempt' | 'third-contact-attempt' | 'closed-lost' | 'scheduled'; isNewCustomer: boolean | null; // true = yes, false = no, null = not sure yet DEFAULT: null campaign: string | null; // reference to campaign DEFAULT: null; isBusinessHours: boolean; // Was the lead created generated during business hours for the location? unqualifiedReason?: 'no-contact' | 'no-response' | 'medicaid' | 'service-not-offered' | 'insurance-out-of-network' | 'wrong-number' | 'other' unqualifiedReasonDetail?: string; // If unqualifiedReason is 'other' give the user an input to describe why createdDate: string; // iso timestamp of the opportunity creation firstContactAttemptDate: string | null; // iso timestamp of first contact attempt DEFAULT: null secondContactAttemptDate: string | null; // iso timestamp of second contact attempt DEFAULT: null thirdContactAttemptDate: string | null; // iso timestamp of third contact attempt DEFAULT: null contactedDate: string | null; // iso timestamp when contact was made for this opportunity DEFAULT: null qualifiedDate: string | null; // iso timestamp when the contact was qualified for this opportunity DEFAULT: null closedLostDate: string | null; // iso timestamp of closed lost event DEFAULT: null closedWonDate: string | null; // iso timestamp of closed won event DEFAULT: null gclid?: string; // Leads from Google will come with a gclid that we can use to report conversions back to Google fbid?: string; // Leads from Facebook will come with a fbid that we can use to report conversions back to Facebook yelpId?: string; // Leads from Yelp will come with a yelpId that we can use to report conversions back to Yelp nextdoorId?: string; // Leads from Nextdoor will come with a nextdoorId that we can use to report conversions back to Nextdoor value: number; // The amount the opportunity is worth. DEFAULT: 0. When contactedDate is set = 100. When qualifiedDate is set = 500.}
type Activity = CallActivity | EmailActivity | TextActivity
interface BaseActivity { id: string; type: string; direction: 'inbound' | 'outbound'; opportunity?: string; // reference to an opportunity, if there is one ongoing createdDate: string;}
interface CallActivity extends BaseActivity { type: 'call'; callRecordingUrl?: string; // url for recording of initial inbound call transcript?: string; summary?: string;}
interface EmailActivity extends BaseActivity { type: 'email'; fromAddress: string; toAddress: string; text: string; html: string;}
interface TextActivity extends BaseActivity { type: 'text', from: string; to: string; text: string;}
interface FormSubmissionActivity extends BaseActivity { type: 'formSubmission';}Resources:
Section titled “Resources:”- Google Ads tracking template docs: https://support.google.com/google-ads/answer/6076199?sjid=6610510847741978280-NC
- Call Rail’s tracking template instructions: https://support.callrail.com/hc/en-us/articles/5711744970509-Adding-tracking-templates-to-Google-Ads
- Facebook datasets: https://www.facebook.com/business/help/750785952855662?id=490360542427371
- Implementing facebook conversion api: https://www.facebook.com/business/help/232481544843294?id=818859032317965
- Testing Facebook events: https://www.facebook.com/business/help/1624255387706033?id=818859032317965
1. Data & Storage
Section titled “1. Data & Storage”Existing Data We’ll Use
Section titled “Existing Data We’ll Use”- (instruction) List current data/tables we’ll need
- (instruction) Any modifications needed
New Data We’ll Need
Section titled “New Data We’ll Need”- (instruction) New data models/fields to create
- (instruction) Basic storage approach
Not sure if we have this or not
Section titled “Not sure if we have this or not”- Contact / Lead / Opportunity (we need to decide the object model)
- Type: Phone call, Lead form, Text message
- Lead ID - I think we need a good way to connect ID fields and track all activity under one umbrella
- Name
- Phone
- Address?
- Preferred communications: SMS, Email, Phone call
- Are you a new patient?
- Appointment reason
- Appointment preference
- Stage: New, Qualified, Scheduled
- Result: Open, Won, Lost
- Appointments
- Loss reason
- Unqualified reason
- Lifecycle metadata:
- Created by
- Created at
- Updated by
- Updated at
- Qualified by
- Qualified at
- Scheduled by
- Scheduled at
- Closed by
- Closed at
- Orders / Appointments
- First name
- Last name
- Date and time
- Activity?
- Contact
- Opportunity
- Date and time
- Description ie Call, Email, SMS
2. User Touchpoints
Section titled “2. User Touchpoints”- (instruction) Which users are we building this solution for?
- (instruction) Which other users will be affected by this solution?
- Advertiser
- Owner - Probably won’t use the feature day to day but will want funnel reporting
- Manager - Usage will both operational and reporting depending on the advertiser
- Member - HoneyGrid and advertisers need someone to handle the leads. It’s hard to motivate these people to do a good job or care much about the results. We should have an easy UI for operational team members but be realistic about what kind of adoption we’ll see. This is why we’ll likely follow up with Lead management to offload/automate scheduling.
- Partner
- Consultant - Partners will want to know HoneyGrid’s overall performance and have tools to use that data to bring more advertisers to HoneyGrid.
- Contractor
- Graphic design - N/A
- Copy - N/A
- Ad buyer - N/A
- Scheduler - N/A
- HoneyGrid
- Sales - We’ll want to get our performance data to the point we’re comfortable and proud talking about it and leading with it in sales. We can’t really do that right now. This will help us have the data to analyze and share with potential customers and partners.
- Finance - Little direct effect.
- Product - We are the main consumer of aggregate and advertiser-level funnel performance data. We don’t have a clear enough signal around conversion quality until we do this. We can follow up with Conversion signal once this project is finished.
- Operations
- Graphic design - Little effect.
- Copy - Little effect
- Ad buyer - Another main consumer of funnel performance data to optimize accounts.
- AI agent - N/A
- Scheduler - N/A
- (instruction) New endpoints needed
- (instruction) Modifications to existing endpoints
- (instruction) Basic request/response structure
- Contacts / Leads / Opportunities
- Create
- Update stage
- Close
- Orders / Appointments
- Create
- Update
- Delete
- (instruction) List screens to build/modify
- (instruction) Key user interactions
- (instruction) Critical user flows
- Leads inbox
- List of leads in the left rail
- Lead details
- Activity feed
- Tags
- Opportunity details
- Order details
- Lead details
- Details
- Listen to phone call
- See email content
3. Technical Approach
Section titled “3. Technical Approach”Implementation Outline
Section titled “Implementation Outline”- (instruction) High-level approach
- (instruction) Major components to build
- (instruction) Key libraries/services needed
- (instruction) Any significant technical decisions
Potential Gotchas
Section titled “Potential Gotchas”- (instruction) Technical uncertainties
- (instruction) Performance concerns
- (instruction) Security considerations
- (instruction) Dependencies on other work
4. Quick Plan
Section titled “4. Quick Plan”MVP Scope
Section titled “MVP Scope”- (instruction) Must-have features
- (instruction) Nice-to-have features
- (instruction) What we’re explicitly not doing
Milestones
Section titled “Milestones”- Lead ingestion 1.a. Receive phone call leads from CallRail (Nextdoor, Yelp, Google) 1.b. Receive leads from Go High Level form submissions (Nextdoor, Google) — Landing page per platform. Helps with attribution. Enables reflecting back to the user the platform they came from. — Leverage Cloudflare to track bot traffic and location of users landing on the landing page 1.c. Receive form submissions from Yelp 1.d. Receive phone calls from Patient Prism
- Lead storage 2.a. Store leads in Airtable — Finish Call Scoring workflow — Part of the Airtable schema needs to include the tagging information 2.b. Once schema is solid, also store leads in HoneyGrid database (Eduardo?)
- Lead reporting 3.a. Report offline conversions to Google Ads 3.b. Report offline conversions to Facebook 3.c. Report offline conversions to Yelp 3.d. Report offline conversions to Nextdoor 3.e. Report leads metrics to advertiser in HoneyGrid Dashboard (Eduardo)
Phase 2
Section titled “Phase 2”- Lead management