How to Build a High-Ticket Sales Funnel Automation with n8n and HubSpot (Free Template)

How to Build a High-Ticket Sales Funnel Automation with n8n and HubSpot (Free Template)

Converting leads into high-ticket buyers requires precision timing, persistent follow-up, and seamless coordination between your CRM and sales team. Manual management of presentation invites, no-show recovery, and deal stage updates consumes hours daily and creates gaps where leads fall through. This n8n automation orchestrates your entire high-ticket sales funnel—from initial lead nurturing through group presentations to 1-on-1 closing sessions—while keeping HubSpot synchronized in real-time. You'll learn how to build a complete automation system that handles lead progression, no-show recovery, sales notifications, and contract tracking without manual intervention.

The Problem: Manual High-Ticket Sales Funnel Management

High-ticket sales funnels demand consistent touchpoints across weeks or months. A vacation club selling $10,000+ memberships can't afford missed follow-ups or delayed responses.

Current challenges:

  • Manually scheduling and reminding leads about group presentations 1-2 times per week
  • No systematic recovery process when leads don't show up (30-50% typical no-show rates)
  • Sales reps manually updating HubSpot deal stages after each interaction
  • Disconnected systems between Microsoft Teams presentations, DocuSign contracts, Stripe payments, and HubSpot CRM
  • No automated re-engagement sequences for leads who go cold after initial contact

Business impact:

  • Time spent: 15-20 hours weekly on manual follow-ups and CRM updates
  • Revenue loss: 40% of no-shows never get re-engaged, representing $200K+ annual opportunity cost
  • Inconsistent experience: Leads receive different messaging depending on which sales rep handles them
  • Visibility gaps: Management can't see real-time funnel metrics without manual reporting

The Solution Overview

This n8n automation creates a complete high-ticket sales funnel that moves leads from initial contact through group presentations and into 1-on-1 closing sessions. The workflow monitors HubSpot for new leads tagged under "Online Sales," triggers nurture sequences via email, tracks presentation attendance, executes no-show recovery flows, and updates deal stages automatically. When contracts are signed in DocuSign and payments processed through Stripe, the system immediately reflects these conversions in HubSpot. The architecture uses webhook triggers, conditional logic nodes, and scheduled checks to ensure no lead gets abandoned regardless of their response timing.

What You'll Build

This automation handles the complete lifecycle of a high-ticket sales lead from first touch to closed deal.

Component Technology Purpose
Lead Intake HubSpot Webhook Captures new contacts tagged "Online Sales"
Nurture Sequences n8n Schedule + HTTP Request Sends timed emails moving leads toward presentations
Presentation Management Microsoft Teams API + Calendar Schedules group webinars and tracks attendance
No-Show Recovery n8n Function + Delay Nodes Re-engages leads who miss presentations
Deal Stage Progression HubSpot API Updates pipeline stages based on lead actions
Contract Tracking DocuSign Webhook Monitors signature completion
Payment Verification Stripe Webhook Confirms successful charges
Sales Notifications Slack/Email Nodes Alerts team of hot leads and completed deals
Re-engagement Logic Switch Node + Conditional Routing Handles cold leads with automated sequences

Prerequisites

Before starting, ensure you have:

  • n8n instance (cloud or self-hosted with webhook access)
  • HubSpot account with API access (Marketing Hub Professional or higher for workflows)
  • Microsoft Teams admin access for API integration
  • DocuSign account with API credentials
  • Stripe account with webhook configuration access
  • Basic JavaScript knowledge for Function nodes
  • Understanding of sales funnel stages and lead lifecycle

Step 1: Configure HubSpot Lead Capture

The funnel begins when a new contact enters HubSpot tagged with "Online Sales" business line. This happens automatically when someone purchases a travel certificate.

Set up the HubSpot webhook trigger:

  1. In n8n, add a Webhook node set to "Webhook URLs" mode
  2. Copy the production webhook URL
  3. In HubSpot, navigate to Settings → Integrations → Private Apps
  4. Create a new app with scopes: contacts, deals, timeline
  5. Configure a workflow in HubSpot: Trigger = "Contact property 'Business Line' is 'Online Sales'"
  6. Add action: "Send webhook notification" to your n8n URL

Node configuration:

{
  "httpMethod": "POST",
  "path": "hubspot-lead-capture",
  "responseMode": "onReceived",
  "options": {}
}

Why this works:

HubSpot's native workflow engine ensures every qualified lead triggers your n8n automation immediately. By filtering on the "Business Line" property, you isolate high-ticket sales leads from other contact types. The webhook delivers contact ID, email, name, and custom properties you'll use downstream.

Add HubSpot contact enrichment:

After the webhook trigger, add an HTTP Request node to fetch complete contact details:

{
  "method": "GET",
  "url": "=https://api.hubapi.com/crm/v3/objects/contacts/{{$json.body.contactId}}",
  "authentication": "predefinedCredentialType",
  "nodeCredentialType": "hubspotApi",
  "options": {
    "qs": {
      "properties": "email,firstname,lastname,phone,purchase_date,travel_certificate_id"
    }
  }
}

This ensures you have all necessary contact data for personalization in nurture emails.

Step 2: Initialize Deal and Set First Stage

Every new lead needs a corresponding deal in HubSpot's pipeline to track their progression through the funnel.

Create deal in HubSpot:

Add an HTTP Request node that creates a deal associated with the contact:

{
  "method": "POST",
  "url": "https://api.hubapi.com/crm/v3/objects/deals",
  "authentication": "predefinedCredentialType",
  "nodeCredentialType": "hubspotApi",
  "body": {
    "properties": {
      "dealname": "={{$json.properties.firstname}} {{$json.properties.lastname}} - Vacation Club",
      "dealstage": "lead_nurture",
      "pipeline": "high_ticket_sales",
      "amount": "10000",
      "closedate": "={{new Date(Date.now() + 30*24*60*60*1000).toISOString()}}",
      "hubspot_owner_id": "{{$json.properties.hubspot_owner_id}}"
    },
    "associations": [
      {
        "to": {"id": "={{$json.id}}"},
        "types": [{"associationCategory": "HUBSPOT_DEFINED", "associationTypeId": 3}]
      }
    ]
  }
}

Why this approach:

Creating the deal immediately establishes tracking visibility. The dealstage starts at "lead_nurture" and will progress through "presentation_scheduled," "presentation_attended," "1on1_scheduled," "contract_sent," and "closed_won." The 30-day close date creates urgency while remaining realistic for high-ticket sales cycles. Associating the deal with the contact ensures all interactions appear in both records.

Step 3: Build Nurture Sequence to Presentation

Leads need 3-5 touchpoints before they're ready to attend a group presentation. This sequence runs over 7-10 days.

Configure the nurture flow:

Add a Function node that determines the next email in the sequence:

const contact = $input.first().json;
const lastEmailSent = contact.properties.last_nurture_email || 0;
const daysSincePurchase = Math.floor((Date.now() - new Date(contact.properties.purchase_date)) / (1000*60*60*24));

let emailTemplate = '';
let nextStage = lastEmailSent + 1;

if (nextStage === 1 && daysSincePurchase === 0) {
  emailTemplate = 'welcome_travel_certificate';
} else if (nextStage === 2 && daysSincePurchase === 2) {
  emailTemplate = 'introduce_vacation_club';
} else if (nextStage === 3 && daysSincePurchase === 5) {
  emailTemplate = 'presentation_invitation';
} else if (nextStage === 4 && daysSincePurchase === 7) {
  emailTemplate = 'presentation_reminder';
} else {
  return [];
}

return [{
  json: {
    email: contact.properties.email,
    firstName: contact.properties.firstname,
    template: emailTemplate,
    contactId: contact.id,
    nextStage: nextStage
  }
}];

Send email via HTTP Request node:

Connect to your email service (SendGrid, Mailgun, or HubSpot's email API):

{
  "method": "POST",
  "url": "https://api.sendgrid.com/v3/mail/send",
  "authentication": "predefinedCredentialType",
  "nodeCredentialType": "sendGridApi",
  "body": {
    "personalizations": [{
      "to": [{"email": "={{$json.email}}"}],
      "dynamic_template_data": {
        "first_name": "={{$json.firstName}}",
        "presentation_date": "={{$json.nextPresentationDate}}",
        "registration_link": "={{$json.registrationUrl}}"
      }
    }],
    "template_id": "={{$json.template}}"
  }
}

Update HubSpot contact property:

After sending, update the contact's last_nurture_email property so the sequence doesn't repeat:

{
  "method": "PATCH",
  "url": "=https://api.hubapi.com/crm/v3/objects/contacts/{{$json.contactId}}",
  "body": {
    "properties": {
      "last_nurture_email": "={{$json.nextStage}}",
      "last_email_sent_date": "={{new Date().toISOString()}}"
    }
  }
}

Schedule the sequence checker:

Add a Schedule Trigger node set to run daily at 9 AM:

{
  "rule": {
    "interval": [{"field": "cronExpression", "expression": "0 9 * * *"}]
  }
}

This node queries HubSpot for all contacts in "lead_nurture" stage and processes them through the Function node above.

Step 4: Presentation Scheduling and Attendance Tracking

Group presentations happen 1-2 times per week. Leads who register need confirmation emails, calendar invites, and reminders.

Microsoft Teams integration:

When a lead clicks the registration link in the nurture email, a webhook fires to n8n:

{
  "method": "POST",
  "url": "https://graph.microsoft.com/v1.0/me/onlineMeetings",
  "authentication": "predefinedCredentialType",
  "nodeCredentialType": "microsoftTeamsApi",
  "body": {
    "startDateTime": "={{$json.presentationDateTime}}",
    "endDateTime": "={{$json.presentationEndTime}}",
    "subject": "Exclusive Vacation Club Presentation",
    "participants": {
      "attendees": [
        {"identity": {"user": {"id": null, "displayName": "={{$json.firstName}} {{$json.lastName}}", "email": "={{$json.email}}"}}}
      ]
    }
  }
}

Update deal stage to "presentation_scheduled":

{
  "method": "PATCH",
  "url": "=https://api.hubapi.com/crm/v3/objects/deals/{{$json.dealId}}",
  "body": {
    "properties": {
      "dealstage": "presentation_scheduled",
      "presentation_date": "={{$json.presentationDateTime}}"
    }
  }
}

Track attendance:

After the presentation, Microsoft Teams provides attendance data via API. Add a Schedule node that runs 30 minutes after each scheduled presentation:

{
  "method": "GET",
  "url": "=https://graph.microsoft.com/v1.0/me/onlineMeetings/{{$json.meetingId}}/attendanceReports",
  "authentication": "predefinedCredentialType",
  "nodeCredentialType": "microsoftTeamsApi"
}

Parse the attendance report with a Function node:

const attendanceData = $input.first().json.value[0];
const attendees = attendanceData.attendanceRecords;

const contactEmail = $('Webhook').first().json.email;
const attended = attendees.some(a => a.emailAddress === contactEmail && a.totalAttendanceInSeconds > 1800);

return [{
  json: {
    contactId: $('Webhook').first().json.contactId,
    dealId: $('Webhook').first().json.dealId,
    attended: attended,
    attendanceSeconds: attended ? attendees.find(a => a.emailAddress === contactEmail).totalAttendanceInSeconds : 0
  }
}];

Update deal based on attendance:

Use a Switch node to route based on attended boolean:

  • If attended: Update deal stage to "presentation_attended" and trigger 1-on-1 scheduling flow
  • If no-show: Update deal stage to "no_show" and trigger recovery sequence

Step 5: No-Show Recovery Sequence

30-50% of registered leads don't attend. A systematic recovery process recaptures 15-20% of these.

Immediate no-show email:

Send within 2 hours of the missed presentation:

{
  "personalizations": [{
    "to": [{"email": "={{$json.email}}"}],
    "dynamic_template_data": {
      "first_name": "={{$json.firstName}}",
      "next_presentation_date": "={{$json.nextPresentationDate}}",
      "reschedule_link": "={{$json.rescheduleUrl}}"
    }
  }],
  "template_id": "no_show_recovery_immediate"
}

Follow-up sequence:

Add a Wait node (2 days), then send a second recovery email with a different angle:

{
  "template_id": "no_show_recovery_value_reminder",
  "dynamic_template_data": {
    "testimonial_video_url": "https://yourvacationclub.com/testimonials",
    "limited_spots_remaining": "={{$json.spotsRemaining}}"
  }
}

Final attempt:

After another 3 days, send a "last chance" email offering a 1-on-1 presentation instead of group:

{
  "template_id": "no_show_recovery_1on1_offer",
  "dynamic_template_data": {
    "calendar_link": "={{$json.calendlyUrl}}"
  }
}

Update deal stage:

If no response after 7 days, move deal to "cold_lead" stage but keep in pipeline for quarterly re-engagement campaigns.

Step 6: Transition to 1-on-1 Sales Sessions

Leads who attend the presentation and show interest get scheduled for 1-on-1 closing calls.

Calendly webhook integration:

When a lead books a 1-on-1 via Calendly, the webhook triggers n8n:

{
  "httpMethod": "POST",
  "path": "calendly-booking",
  "responseMode": "onReceived"
}

Update HubSpot deal:

{
  "method": "PATCH",
  "url": "=https://api.hubapi.com/crm/v3/objects/deals/{{$json.dealId}}",
  "body": {
    "properties": {
      "dealstage": "1on1_scheduled",
      "closedate": "={{$json.scheduledTime}}",
      "assigned_closer": "={{$json.assignedSalesRep}}"
    }
  }
}

Notify sales rep:

Send Slack notification to the assigned closer:

{
  "channel": "#high-ticket-sales",
  "text": "🔥 Hot lead scheduled: {{$json.firstName}} {{$json.lastName}} - 1-on-1 on {{$json.scheduledTime}}",
  "blocks": [
    {
      "type": "section",
      "text": {"type": "mrkdwn", "text": "*New 1-on-1 Scheduled*
*Lead:* {{$json.firstName}} {{$json.lastName}}
*Time:* {{$json.scheduledTime}}
*Attended Presentation:* Yes
*Interest Level:* High"}
    },
    {
      "type": "actions",
      "elements": [
        {"type": "button", "text": {"type": "plain_text", "text": "View in HubSpot"}, "url": "={{$json.hubspotDealUrl}}"}
      ]
    }
  ]
}

Step 7: Contract and Payment Tracking

During the 1-on-1 call, sales reps send DocuSign contracts and process Stripe payments. These events must update HubSpot immediately.

DocuSign webhook:

Configure DocuSign to send completion events to n8n:

{
  "httpMethod": "POST",
  "path": "docusign-contract-signed",
  "responseMode": "onReceived"
}

Parse DocuSign payload:

const envelope = $input.first().json;
const envelopeId = envelope.envelopeId;
const status = envelope.status;
const signerEmail = envelope.recipients.signers[0].email;

if (status !== 'completed') {
  return [];
}

return [{
  json: {
    envelopeId: envelopeId,
    signerEmail: signerEmail,
    completedDate: envelope.completedDateTime
  }
}];

Find associated HubSpot deal:

{
  "method": "POST",
  "url": "https://api.hubapi.com/crm/v3/objects/deals/search",
  "body": {
    "filterGroups": [{
      "filters": [{
        "propertyName": "associations.contact",
        "operator": "EQ",
        "value": "={{$json.contactId}}"
      }]
    }]
  }
}

Update deal to "contract_sent":

{
  "method": "PATCH",
  "url": "=https://api.hubapi.com/crm/v3/objects/deals/{{$json.dealId}}",
  "body": {
    "properties": {
      "dealstage": "contract_sent",
      "contract_signed_date": "={{$json.completedDate}}",
      "docusign_envelope_id": "={{$json.envelopeId}}"
    }
  }
}

Stripe payment webhook:

Configure Stripe to send payment_intent.succeeded events:

{
  "httpMethod": "POST",
  "path": "stripe-payment-received",
  "responseMode": "onReceived"
}

Verify payment and close deal:

const paymentIntent = $input.first().json.data.object;
const amount = paymentIntent.amount / 100;
const customerEmail = paymentIntent.receipt_email;

if (amount < 10000) {
  return [];
}

return [{
  json: {
    amount: amount,
    customerEmail: customerEmail,
    paymentId: paymentIntent.id,
    paidDate: new Date(paymentIntent.created * 1000).toISOString()
  }
}];

Update deal to "closed_won":

{
  "method": "PATCH",
  "url": "=https://api.hubapi.com/crm/v3/objects/deals/{{$json.dealId}}",
  "body": {
    "properties": {
      "dealstage": "closed_won",
      "closedate": "={{$json.paidDate}}",
      "amount": "={{$json.amount}}",
      "stripe_payment_id": "={{$json.paymentId}}"
    }
  }
}

Send celebration notification:

{
  "channel": "#sales-wins",
  "text": "💰 Deal closed! {{$json.firstName}} {{$json.lastName}} - ${{$json.amount}}"
}

Workflow Architecture Overview

This workflow consists of 47 nodes organized into 6 main sections:

  1. Lead intake and enrichment (Nodes 1-5): Captures HubSpot webhook, fetches contact details, creates deal, initializes pipeline stage
  2. Nurture sequence engine (Nodes 6-18): Daily schedule trigger, queries contacts in nurture stage, determines next email, sends via SendGrid, updates contact properties
  3. Presentation management (Nodes 19-28): Registration webhook, creates Teams meeting, sends confirmations, tracks attendance, routes based on show/no-show
  4. No-show recovery (Nodes 29-35): Immediate recovery email, 2-day wait, second attempt, 3-day wait, final offer, stage update to cold
  5. 1-on-1 scheduling (Nodes 36-40): Calendly webhook, deal stage update, sales rep notification, pre-call reminder sequence
  6. Contract and payment tracking (Nodes 41-47): DocuSign webhook, contract signed confirmation, Stripe webhook, payment verification, deal closure, celebration notification

Execution flow:

  • Trigger: HubSpot contact creation or scheduled daily check
  • Average run time: 2-4 seconds per lead
  • Key dependencies: HubSpot API, Microsoft Teams API, DocuSign webhooks, Stripe webhooks, SendGrid API

Critical nodes:

  • Function Node (Nurture Logic): Determines which email to send based on days since purchase and previous emails sent
  • Switch Node (Attendance Router): Routes leads to either 1-on-1 flow or no-show recovery based on presentation attendance
  • HTTP Request (Deal Stage Updates): Ensures HubSpot pipeline reflects real-time lead status across all touchpoints

The complete n8n workflow JSON template is available at the bottom of this article.

Key Configuration Details

HubSpot API Authentication

Required fields:

  • API Key: Your HubSpot private app token (Settings → Integrations → Private Apps)
  • Base URL: https://api.hubapi.com
  • Required scopes: crm.objects.contacts.read, crm.objects.contacts.write, crm.objects.deals.read, crm.objects.deals.write

Common issues:

  • Using personal access tokens instead of private app tokens → Results in 401 errors
  • Missing association permissions → Deals won't link to contacts
  • Always use /crm/v3/ endpoints, not deprecated v1 or v2

Microsoft Teams Meeting Configuration

Critical settings:

{
  "allowedPresenters": "organization",
  "autoAdmittedUsers": "everyone",
  "recordAutomatically": true,
  "allowAttendeeToEnableCamera": true,
  "allowAttendeeToEnableMic": true
}

Why this approach:

Recording presentations automatically provides content for no-shows to watch later. Setting autoAdmittedUsers to "everyone" prevents leads from waiting in lobbies, which increases drop-off. The allowedPresenters restriction ensures only your team controls the presentation flow.

Variables to customize:

  • presentationFrequency: Change from 2x/week to daily for higher volume
  • noShowRecoveryDelay: Adjust 2-day and 3-day waits based on your sales cycle
  • coldLeadThreshold: Default 7 days, increase to 14 for longer consideration products

Email Template Personalization

Dynamic fields to include:

{
  "first_name": "={{$json.properties.firstname}}",
  "purchase_date": "={{new Date($json.properties.purchase_date).toLocaleDateString()}}",
  "travel_destination": "={{$json.properties.travel_certificate_destination}}",
  "presentation_date": "={{$json.nextPresentationDate}}",
  "sales_rep_name": "={{$json.assignedRep.name}}",
  "sales_rep_photo": "={{$json.assignedRep.photoUrl}}"
}

Including the travel destination they purchased creates immediate relevance. Showing the assigned sales rep's photo builds familiarity before the 1-on-1 call.

Testing & Validation

Test each component independently:

  1. Lead capture: Create a test contact in HubSpot with "Online Sales" tag, verify webhook fires and deal creates
  2. Nurture emails: Manually trigger the daily schedule node, check SendGrid activity for test contact
  3. Presentation flow: Register test email for presentation, verify Teams meeting creation and calendar invite
  4. Attendance tracking: Join Teams meeting with test account for 30+ minutes, verify attendance API returns correct data
  5. No-show recovery: Register but don't attend, verify recovery emails send at correct intervals
  6. Contract tracking: Send test DocuSign envelope, verify webhook triggers and deal updates
  7. Payment processing: Create test Stripe payment, verify deal closes and notification sends

Common troubleshooting:

Issue Cause Solution
Webhook not firing Incorrect URL or HubSpot workflow not active Verify webhook URL matches n8n production URL, check HubSpot workflow is turned on
Emails not sending SendGrid API key expired or template ID wrong Regenerate API key, verify template IDs match your SendGrid account
Deal not updating Missing HubSpot deal ID in payload Add Function node to extract deal ID from contact associations before update
Attendance not tracking Teams API permissions insufficient Ensure app registration has OnlineMeetings.Read.All permission

Run evaluation tests:

Create 10 test contacts and track them through the full funnel. Measure:

  • Time from lead creation to first email (should be <5 minutes)
  • Presentation registration rate (target 40%+)
  • No-show recovery effectiveness (target 15-20% re-engagement)
  • Deal stage accuracy (100% match between actual status and HubSpot)

Deployment Considerations

Production Deployment Checklist

Area Requirement Why It Matters
Error Handling Retry logic with exponential backoff on all API calls Prevents data loss when HubSpot or Teams APIs have temporary outages
Monitoring Webhook health checks every 5 minutes Detect failures within 5 minutes vs discovering days later when deals are stale
Rate Limits Implement queuing for bulk operations HubSpot limits to 100 requests/10 seconds, exceeding causes 429 errors
Data Validation Verify email format and required fields before API calls Prevents workflow failures from malformed data
Logging Store execution logs for 90 days Enables debugging when leads report issues weeks later
Backup Webhooks Configure secondary webhook URLs Ensures continuity if primary n8n instance goes down

Error handling implementation:

Wrap all HTTP Request nodes with error workflows:

{
  "continueOnFail": true,
  "retryOnFail": true,
  "maxTries": 3,
  "waitBetweenTries": 5000
}

Add an Error Trigger node that catches failures and sends alerts:

{
  "channel": "#n8n-alerts",
  "text": "⚠️ Workflow error: {{$json.error.message}}
Node: {{$json.node.name}}
Execution: {{$json.execution.id}}"
}

Scaling considerations:

For 100+ leads per day:

  • Implement batch processing in nurture sequence (process 50 contacts per execution)
  • Use HubSpot's batch API endpoints (/crm/v3/objects/deals/batch/update)
  • Add Redis caching for frequently accessed data (presentation schedules, sales rep assignments)
  • Split workflow into sub-workflows triggered by webhooks to avoid timeout issues

Customization ideas:

  • Add SMS reminders via Twilio for presentation no-shows (increases recovery by 10-15%)
  • Integrate with Calendly for automated 1-on-1 scheduling instead of manual booking
  • Build executive dashboard in Google Sheets showing real-time funnel metrics
  • Add lead scoring based on email engagement and presentation attendance duration
  • Create A/B testing framework for nurture email subject lines and send times

Use Cases & Variations

Use Case 1: Real Estate Investment Webinars

  • Industry: Real estate syndication
  • Scale: 200 leads/month, $50K-$250K deal sizes
  • Modifications needed: Extend nurture sequence to 14 days (longer consideration), add accredited investor verification step before 1-on-1, integrate with investor portal for document sharing

Use Case 2: B2B SaaS Enterprise Sales

  • Industry: Enterprise software
  • Scale: 50 leads/month, $100K+ annual contracts
  • Modifications needed: Replace group presentations with personalized demo recordings, add multi-stakeholder tracking (decision maker, technical buyer, end user), integrate with Gong for call recording analysis

Use Case 3: Coaching Program Sales

  • Industry: Executive coaching
  • Scale: 150 leads/month, $15K-$30K programs
  • Modifications needed: Add application form before presentation invitation, include personality assessment integration, create cohort-based presentation scheduling

Use Case 4: Medical Device Sales

  • Industry: Healthcare equipment
  • Scale: 75 leads/month, $200K+ devices
  • Modifications needed: Add compliance documentation tracking, integrate with hospital procurement systems, include ROI calculator in nurture sequence

Use Case 5: Franchise Sales

  • Industry: Restaurant franchises
  • Scale: 100 leads/month, $500K+ investments
  • Modifications needed: Add financial qualification step, integrate with FDD delivery system, create territory availability checker

Customizations & Extensions

Alternative Integrations

Instead of Microsoft Teams:

  • Zoom: Best for larger audiences (500+ attendees) - requires swapping Teams nodes with Zoom API nodes (similar structure)
  • WebinarJam: Better if you need advanced engagement features (polls, Q&A) - use WebinarJam webhooks for registration and attendance
  • Google Meet: Use when your organization is Google Workspace-based - requires Google Calendar API integration

Instead of SendGrid:

  • HubSpot Email: Best for maintaining all data in one platform - use HubSpot's email API instead of SendGrid nodes
  • Mailgun: Better deliverability for transactional emails - swap SendGrid credentials with Mailgun
  • Postmark: Use for highest delivery rates and detailed analytics - similar API structure to SendGrid

Workflow Extensions

Add automated reporting:

  • Add a Schedule node to run Monday mornings at 8 AM
  • Query HubSpot for deals created, presentations scheduled, contracts signed, and revenue closed in past week
  • Connect to Google Slides API to generate executive summary presentations
  • Email report to leadership team
  • Nodes needed: +8 (Schedule, 4x HTTP Request for HubSpot queries, Function for data aggregation, Google Slides API, Email)

Scale to handle more leads:

  • Replace daily schedule trigger with hourly checks for high-volume periods
  • Implement Redis caching to store presentation schedules and avoid repeated API calls
  • Add batch processing: query 100 contacts at a time instead of individual requests
  • Use HubSpot's batch update endpoints to update multiple deals simultaneously
  • Performance improvement: 5x faster for 500+ leads/day, reduces API calls by 80%

Add lead scoring:

  • Track email open rates and link clicks in nurture sequence
  • Assign points: email open = 5 points, link click = 10 points, presentation registration = 25 points, attendance = 50 points
  • Store score in custom HubSpot property
  • Route high-scoring leads (75+ points) to senior closers, lower scores to junior reps
  • Nodes needed: +6 (SendGrid webhook for engagement tracking, Function for score calculation, HubSpot property update, Switch for routing)

Integration possibilities:

Add This To Get This Complexity
Slack integration Real-time team notifications for hot leads Easy (2 nodes)
Calendly Automated 1-on-1 scheduling without manual coordination Easy (3 nodes)
Gong/Chorus Call recording and analysis for coaching Medium (5 nodes)
Twilio SMS reminders for presentations and 1-on-1s Medium (4 nodes)
Airtable Visual pipeline dashboard for management Medium (6 nodes)
Zapier Tables Backup data storage for compliance Medium (5 nodes)
Power BI Executive dashboards with real-time metrics Advanced (12 nodes)
Salesforce Enterprise CRM alternative to HubSpot Advanced (15+ nodes)

Add multi-language support:

For international leads, detect language preference from HubSpot contact property and route to language-specific email templates:

const language = $json.properties.preferred_language || 'en';
const templateMap = {
  'en': 'welcome_en',
  'es': 'welcome_es',
  'fr': 'welcome_fr'
};

return [{
  json: {
    ...($json),
    template: templateMap[language]
  }
}];

Nodes needed: +3 (Function for language detection, Switch for routing, additional HTTP Request nodes for each language)

Implement A/B testing:

Test different email subject lines and send times:

const variant = Math.random() < 0.5 ? 'A' : 'B';
const subjectLines = {
  'A': 'Exclusive Vacation Club Invitation',
  'B': 'Your Travel Benefits Are Waiting'
};

return [{
  json: {
    ...($json),
    variant: variant,
    subject: subjectLines[variant]
  }
}];

Track open rates by variant in HubSpot custom properties, then analyze which performs better after 100 sends.

Get Started Today

Ready to automate your high-ticket sales funnel?

  1. Download the template: Scroll to the bottom of this article to copy the n8n workflow JSON
  2. Import to n8n: Go to Workflows → Import from URL or File, paste the JSON
  3. Configure your services: Add your API credentials for HubSpot, Microsoft Teams, SendGrid, DocuSign, and Stripe
  4. Customize deal stages: Update the pipeline stages to match your sales process
  5. Test with sample data: Create test contacts and verify each stage works before going live
  6. Deploy to production: Activate the workflow and monitor the first 10 leads closely

Need help customizing this workflow for your specific sales process? Schedule an intro call with Atherial at https://atherial.ai/contact to discuss your high-ticket funnel requirements and get expert implementation support.

Complete N8N Workflow Template

Copy the JSON below and import it into your N8N instance via Workflows → Import from File

{
  "name": "High-Ticket Sales Funnel Automation",
  "nodes": [
    {
      "id": "webhook_lead",
      "name": "Lead Received Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        100,
        100
      ],
      "parameters": {
        "path": "sales-lead",
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "hubspot_create_lead",
      "name": "Create/Update Lead in HubSpot",
      "type": "n8n-nodes-base.hubspot",
      "position": [
        300,
        100
      ],
      "parameters": {
        "email": "={{ $json.email }}",
        "resource": "contact",
        "operation": "upsert",
        "jsonParameters": true,
        "customPropertiesJson": "{\n  \"firstname\": \"{{ $json.firstName }}\",\n  \"lastname\": \"{{ $json.lastName }}\",\n  \"phone\": \"{{ $json.phone }}\",\n  \"lifecyclestage\": \"marketingqualifiedlead\"\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "check_deal_stage",
      "name": "Check Deal Stage",
      "type": "n8n-nodes-base.if",
      "position": [
        500,
        100
      ],
      "parameters": {
        "conditions": {
          "options": {
            "operator": {
              "type": "string",
              "operation": "equals"
            },
            "leftValue": "={{ $json.dealStage }}",
            "rightValue": "group_presentation",
            "caseSensitive": true
          }
        }
      },
      "typeVersion": 2
    },
    {
      "id": "teams_notify_group",
      "name": "Notify Team - Group Presentation",
      "type": "n8n-nodes-base.microsoftTeams",
      "position": [
        700,
        50
      ],
      "parameters": {
        "body": "📋 New High-Ticket Lead Available: {{ $json.firstName }} {{ $json.lastName }} ({{ $json.email }})\n\nQualification Score: {{ $json.qualificationScore }}\nBudget: {{ $json.estimatedBudget }}\n\nReady to schedule group presentation or 1-on-1 session?",
        "teamId": "={{ $json.teamsTeamId }}",
        "resource": "channelMessage",
        "channelId": "={{ $json.teamsChannelId }}",
        "operation": "create"
      },
      "typeVersion": 2
    },
    {
      "id": "teams_notify_oneone",
      "name": "Notify Team - 1-on-1 Session",
      "type": "n8n-nodes-base.microsoftTeams",
      "position": [
        700,
        200
      ],
      "parameters": {
        "body": "1️⃣ Lead Ready for 1-on-1 Session: {{ $json.firstName }} {{ $json.lastName }}\n\nSchedule individual session at: {{ $json.meetingUrl }}",
        "teamId": "={{ $json.teamsTeamId }}",
        "resource": "channelMessage",
        "channelId": "={{ $json.teamsChannelId }}",
        "operation": "create"
      },
      "typeVersion": 2
    },
    {
      "id": "create_teams_meeting",
      "name": "Create Teams Meeting",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        900,
        100
      ],
      "parameters": {
        "url": "https://graph.microsoft.com/v1.0/me/onlineMeetings",
        "method": "POST",
        "sendBody": true,
        "contentType": "json",
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "subject",
              "value": "High-Ticket Sales Presentation - {{ $json.firstName }} {{ $json.lastName }}"
            },
            {
              "name": "startDateTime",
              "value": "={{ $json.scheduledTime }}"
            },
            {
              "name": "endDateTime",
              "value": "={{ $json.endTime }}"
            },
            {
              "name": "isReminderOn",
              "value": "true"
            }
          ]
        },
        "genericAuthType": "httpHeaderApiKey"
      },
      "typeVersion": 4
    },
    {
      "id": "get_hubspot_contact",
      "name": "Get Contact Details from HubSpot",
      "type": "n8n-nodes-base.hubspot",
      "position": [
        1100,
        100
      ],
      "parameters": {
        "by": "email",
        "email": "={{ $json.email }}",
        "resource": "contact",
        "operation": "get"
      },
      "typeVersion": 2
    },
    {
      "id": "wait_presentation",
      "name": "Wait for Presentation Completion",
      "type": "n8n-nodes-base.wait",
      "position": [
        1300,
        100
      ],
      "parameters": {
        "resume": "webhook",
        "webhookNotice": "Waiting for attendee check-in confirmation",
        "incomingAuthentication": "none"
      },
      "typeVersion": 1
    },
    {
      "id": "check_attendance",
      "name": "Check Attendance Status",
      "type": "n8n-nodes-base.if",
      "position": [
        1500,
        100
      ],
      "parameters": {
        "conditions": {
          "options": {
            "operator": {
              "type": "boolean",
              "operation": "true"
            },
            "leftValue": "={{ $json.attended }}",
            "caseSensitive": true
          }
        }
      },
      "typeVersion": 2
    },
    {
      "id": "track_no_show",
      "name": "Track No-Show",
      "type": "n8n-nodes-base.code",
      "position": [
        1700,
        200
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const noShowData = {\n  noShowCount: (item.noShowCount || 0) + 1,\n  lastNoShowDate: new Date().toISOString(),\n  status: 'no_show_follow_up',\n  dealStage: 're_engagement'\n};\nreturn noShowData;",
        "language": "javaScript"
      },
      "typeVersion": 2
    },
    {
      "id": "send_noshow_email",
      "name": "Send No-Show Follow-up Email",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        1900,
        200
      ],
      "parameters": {
        "message": "Hi {{ $json.firstName }},\n\nWe noticed you couldn't make our scheduled presentation. No worries!\n\nWe'd love to reschedule at a time that works better for you. This is a limited-time VIP opportunity.\n\nLet's find a time that suits you best.\n\nBest regards,\nThe Vacation Club Team",
        "subject": "We Missed You! Let's Reschedule Your VIP Presentation",
        "toEmail": "={{ $json.email }}",
        "fromEmail": "sales@vacationclub.com"
      },
      "typeVersion": 2
    },
    {
      "id": "create_hubspot_deal",
      "name": "Create Deal in HubSpot",
      "type": "n8n-nodes-base.hubspot",
      "position": [
        1700,
        50
      ],
      "parameters": {
        "title": "{{ $json.firstName }} {{ $json.lastName }} - Vacation Club Deal",
        "resource": "deal",
        "operation": "create",
        "jsonParameters": true,
        "customPropertiesJson": "{\n  \"dealstage\": \"contract_sent\",\n  \"amount\": \"{{ $json.packageValue }}\",\n  \"closedate\": \"{{ $json.expectedCloseDate }}\"\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "send_docusign",
      "name": "Send Contract via DocuSign",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1900,
        50
      ],
      "parameters": {
        "url": "https://www.docusign.net/restapi/v2.1/accounts/{{ env.DOCUSIGN_ACCOUNT_ID }}/envelopes",
        "method": "POST",
        "sendBody": true,
        "contentType": "json",
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "emailSubject",
              "value": "Please Sign: Vacation Club Membership Agreement"
            },
            {
              "name": "recipients",
              "value": "{{ $json.recipientEmail }}"
            },
            {
              "name": "documentBase64",
              "value": "={{ $json.contractDocument }}"
            }
          ]
        },
        "genericAuthType": "httpHeaderApiKey"
      },
      "typeVersion": 4
    },
    {
      "id": "wait_signature",
      "name": "Wait for Contract Signature",
      "type": "n8n-nodes-base.wait",
      "position": [
        2100,
        100
      ],
      "parameters": {
        "resume": "webhook",
        "webhookNotice": "Waiting for DocuSign signature completion",
        "incomingAuthentication": "none"
      },
      "typeVersion": 1
    },
    {
      "id": "check_signature",
      "name": "Check Signature Status",
      "type": "n8n-nodes-base.if",
      "position": [
        2300,
        100
      ],
      "parameters": {
        "conditions": {
          "options": {
            "operator": {
              "type": "string",
              "operation": "equals"
            },
            "leftValue": "={{ $json.signatureStatus }}",
            "rightValue": "completed",
            "caseSensitive": true
          }
        }
      },
      "typeVersion": 2
    },
    {
      "id": "stripe_charge",
      "name": "Process Stripe Payment",
      "type": "n8n-nodes-base.stripe",
      "position": [
        2500,
        100
      ],
      "parameters": {
        "amount": "={{ Math.round($json.packageValue * 100) }}",
        "source": "{{ $json.cardToken }}",
        "currency": "usd",
        "resource": "charge",
        "operation": "create",
        "customerId": "={{ $json.stripeCustomerId }}"
      },
      "typeVersion": 1
    },
    {
      "id": "map_payment_data",
      "name": "Map Payment Data",
      "type": "n8n-nodes-base.code",
      "position": [
        2700,
        100
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const paymentData = {\n  paymentId: item.chargeId,\n  paymentAmount: item.amount / 100,\n  paymentDate: new Date().toISOString(),\n  paymentStatus: 'completed',\n  dealStage: 'closed_won'\n};\nreturn paymentData;",
        "language": "javaScript"
      },
      "typeVersion": 2
    },
    {
      "id": "update_deal_closed",
      "name": "Update Deal to Closed Won",
      "type": "n8n-nodes-base.hubspot",
      "position": [
        2900,
        100
      ],
      "parameters": {
        "dealId": "={{ $json.dealId }}",
        "resource": "deal",
        "operation": "update",
        "jsonParameters": true,
        "customPropertiesJson": "{\n  \"dealstage\": \"closed_won\",\n  \"closedate\": \"{{ $json.paymentDate }}\",\n  \"closed_won_reason\": \"Payment completed successfully\"\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "send_welcome_email",
      "name": "Send Welcome Email",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        3100,
        100
      ],
      "parameters": {
        "message": "Hi {{ $json.firstName }},\n\nThank you for joining our premium vacation club!\n\nYour membership has been activated.\n\nYour membership details:\n- Membership ID: {{ $json.membershipId }}\n- Package: {{ $json.packageName }}\n- Benefits: Exclusive access to luxury vacation properties worldwide\n\nAccess your member portal: https://members.vacationclub.com/login\n\nWelcome aboard!\nThe Vacation Club Team",
        "subject": "Welcome to Our Exclusive Vacation Club!",
        "toEmail": "={{ $json.email }}",
        "fromEmail": "sales@vacationclub.com"
      },
      "typeVersion": 2
    },
    {
      "id": "teams_deal_closed",
      "name": "Notify Teams - Deal Closed",
      "type": "n8n-nodes-base.microsoftTeams",
      "position": [
        3300,
        100
      ],
      "parameters": {
        "body": "✅ DEAL CLOSED: {{ $json.firstName }} {{ $json.lastName }}\n\nPayment Amount: ${{ $json.paymentAmount }}\nPayment Status: Completed\nMembership ID: {{ $json.membershipId }}\n\nCongratulations on the successful close!",
        "teamId": "={{ $json.teamsTeamId }}",
        "resource": "channelMessage",
        "channelId": "={{ $json.teamsChannelId }}",
        "operation": "create"
      },
      "typeVersion": 2
    },
    {
      "id": "send_followup_email",
      "name": "Send Follow-up Email",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        1700,
        300
      ],
      "parameters": {
        "message": "Hi {{ $json.firstName }},\n\nWe'd love to schedule a personal consultation to discuss your vacation preferences.\n\nThis one-on-one session will help us find the perfect vacation package for you.\n\nAvailable times:\n- Tomorrow at 2:00 PM\n- Thursday at 10:00 AM\n- Friday at 3:00 PM\n\nPlease let us know which time works best for you.\n\nBest regards,\nYour Vacation Club Advisor",
        "subject": "Let's Reschedule Your 1-on-1 Consultation",
        "toEmail": "={{ $json.email }}",
        "fromEmail": "sales@vacationclub.com"
      },
      "typeVersion": 2
    },
    {
      "id": "respond_webhook",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        3500,
        100
      ],
      "parameters": {},
      "typeVersion": 1
    }
  ],
  "connections": {
    "Track No-Show": {
      "main": [
        [
          {
            "node": "Send No-Show Follow-up Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Deal Stage": {
      "main": [
        [
          {
            "node": "Notify Team - Group Presentation",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Notify Team - 1-on-1 Session",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Map Payment Data": {
      "main": [
        [
          {
            "node": "Update Deal to Closed Won",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Welcome Email": {
      "main": [
        [
          {
            "node": "Notify Teams - Deal Closed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Teams Meeting": {
      "main": [
        [
          {
            "node": "Get Contact Details from HubSpot",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Follow-up Email": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lead Received Webhook": {
      "main": [
        [
          {
            "node": "Create/Update Lead in HubSpot",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Signature Status": {
      "main": [
        [
          {
            "node": "Process Stripe Payment",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Create Deal in HubSpot": {
      "main": [
        [
          {
            "node": "Send Contract via DocuSign",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process Stripe Payment": {
      "main": [
        [
          {
            "node": "Map Payment Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Attendance Status": {
      "main": [
        [
          {
            "node": "Create Deal in HubSpot",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Track No-Show",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Deal to Closed Won": {
      "main": [
        [
          {
            "node": "Send Welcome Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notify Teams - Deal Closed": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Contract via DocuSign": {
      "main": [
        [
          {
            "node": "Wait for Contract Signature",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait for Contract Signature": {
      "main": [
        [
          {
            "node": "Check Signature Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notify Team - 1-on-1 Session": {
      "main": [
        [
          {
            "node": "Send Follow-up Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send No-Show Follow-up Email": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create/Update Lead in HubSpot": {
      "main": [
        [
          {
            "node": "Check Deal Stage",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Contact Details from HubSpot": {
      "main": [
        [
          {
            "node": "Wait for Presentation Completion",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notify Team - Group Presentation": {
      "main": [
        [
          {
            "node": "Create Teams Meeting",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait for Presentation Completion": {
      "main": [
        [
          {
            "node": "Check Attendance Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}