Lead qualifying & booking AI agent

Chats with website visitors, qualifies them, finds a free slot in your calendar and books the call.

AI agentAdvanced Saves ~12 hours/month AI AgentsBy Flowngn team

Works with n8n · Make · Zapier

How it works

Trigger: Chat — a visitor starts a conversation on your website
  1. A visitor tells the agent what they need.
  2. The agent asks about their company, budget and timeline, one question at a time.
  3. For a good fit, it checks your calendar and offers 2–3 free slots.
  4. It books the call, invites the visitor, and saves the lead to HubSpot.

What it can do

Unlike a fixed flow, an agent decides which of its tools to use, in what order — and remembers the conversation.

  • Qualifies leads with your own ideal-customer description
  • Reads your calendar and offers real free slots
  • Books a 30-minute call and sends the invite
  • Saves every lead with a summary to HubSpot — even if they don't book

System prompt

The instructions that shape the agent. It's already inside the n8n template — copy it into Make or Zapier, and adjust the YOUR_… parts.

System prompt
You are the website assistant for YOUR_COMPANY. You help visitors understand whether we can help them, and book a 30-minute intro call with qualified leads.

Today is {{ $now.toFormat('cccc d LLLL yyyy, HH:mm') }}. Our timezone is YOUR_TIMEZONE. We take calls Sunday to Thursday, 10:00–17:00.

Qualify by asking, one question at a time: what they need, their company and role, rough budget, and timeline. A good fit is: YOUR_IDEAL_CUSTOMER.

Tools:
- "Check availability": lists our calendar events in a time range. Use it to find free 30-minute slots, then offer 2–3 options.
- "Book meeting": creates the calendar event and invites the visitor. Only book after they pick a slot and give their name and email.
- "Save lead": saves or updates the contact in our CRM. Save every visitor who shares an email, even if they don't book.

Rules:
- Never promise prices, discounts or results.
- If they're not a good fit, be kind, explain briefly, and still save the lead.
- Confirm the final time in their timezone before booking.

Safety rules

Built into the prompt and the tools:

  • Never promises prices, discounts or results
  • Confirms the time in the visitor's timezone before booking
  • Only books after the visitor gives their name and email

Uses your own AI key (Claude, OpenAI or another model). Cost depends on the model and conversation length — a small, fast model keeps most conversations to a fraction of a cent.

Diagram

Website chatChat TriggerBooking agentAI AgentClaude modelAnthropic Chat Mo…◷MemorySimple MemoryCCheck availabi…Google Calendar T…CBook meetingGoogle Calendar T…HSave leadHubSpot Tool
Trigger AI Agent tool

Build it

Pick your tool — same automation, step by step.

Copy and paste straight into an n8n canvas (Ctrl+V), or download and use Import from File. Then connect your own credentials and replace every YOUR_… placeholder. AI steps use a Claude model node — swap it for OpenAI, Gemini or Ollama if you prefer.

Workflow JSON
Show code (239 lines)
{
  "name": "Lead qualifying & booking AI agent (Flowngn)",
  "nodes": [
    {
      "parameters": {
        "content": "## Lead qualifying & booking AI agent\nChats with website visitors, qualifies them, finds a free slot in your calendar and books the call.\n\n**Setup**\n1. Open each node and connect your own credentials.\n2. Replace every YOUR_… placeholder.\n3. Test once, then activate.\n\nFree template from Flowngn",
        "height": 260,
        "width": 340
      },
      "id": "310bce97-ca1c-4fa1-afb0-6f75bd0040c2",
      "name": "Setup notes",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -420,
        -60
      ]
    },
    {
      "parameters": {
        "public": true,
        "mode": "hostedChat",
        "initialMessages": "Hi! 👋 Tell me a bit about what you're working on — I can check if we're a fit and book a call.",
        "options": {
          "responseMode": "lastNode"
        }
      },
      "id": "310bce97-ca1c-4fa1-afb0-6f75bd0040c2",
      "name": "Website chat",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "typeVersion": 1.1,
      "position": [
        0,
        0
      ],
      "webhookId": "310bce97-ca1c-4fa1-afb0-6f75bd0040c2"
    },
    {
      "parameters": {
        "options": {
          "systemMessage": "=You are the website assistant for YOUR_COMPANY. You help visitors understand whether we can help them, and book a 30-minute intro call with qualified leads.\n\nToday is {{ $now.toFormat('cccc d LLLL yyyy, HH:mm') }}. Our timezone is YOUR_TIMEZONE. We take calls Sunday to Thursday, 10:00–17:00.\n\nQualify by asking, one question at a time: what they need, their company and role, rough budget, and timeline. A good fit is: YOUR_IDEAL_CUSTOMER.\n\nTools:\n- \"Check availability\": lists our calendar events in a time range. Use it to find free 30-minute slots, then offer 2–3 options.\n- \"Book meeting\": creates the calendar event and invites the visitor. Only book after they pick a slot and give their name and email.\n- \"Save lead\": saves or updates the contact in our CRM. Save every visitor who shares an email, even if they don't book.\n\nRules:\n- Never promise prices, discounts or results.\n- If they're not a good fit, be kind, explain briefly, and still save the lead.\n- Confirm the final time in their timezone before booking."
        }
      },
      "id": "310bce97-ca1c-4fa1-afb0-6f75bd0040c2",
      "name": "Booking agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 1.9,
      "position": [
        300,
        0
      ]
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "value": "claude-sonnet-5",
          "mode": "list"
        },
        "options": {}
      },
      "id": "310bce97-ca1c-4fa1-afb0-6f75bd0040c2",
      "name": "Claude model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "typeVersion": 1.3,
      "position": [
        -40,
        220
      ]
    },
    {
      "parameters": {
        "contextWindowLength": 10
      },
      "id": "310bce97-ca1c-4fa1-afb0-6f75bd0040c2",
      "name": "Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "typeVersion": 1.3,
      "position": [
        130,
        220
      ]
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Lists events on our calendar between two dates, so you can find free 30-minute slots.",
        "operation": "getAll",
        "calendar": {
          "__rl": true,
          "value": "primary",
          "mode": "id"
        },
        "returnAll": true,
        "timeMin": "={{ $fromAI('start', \"Start of the time range, ISO 8601\", 'string') }}",
        "timeMax": "={{ $fromAI('end', \"End of the time range, ISO 8601\", 'string') }}",
        "options": {
          "singleEvents": true,
          "orderBy": "startTime"
        }
      },
      "id": "310bce97-ca1c-4fa1-afb0-6f75bd0040c2",
      "name": "Check availability",
      "type": "n8n-nodes-base.googleCalendarTool",
      "typeVersion": 1.3,
      "position": [
        300,
        220
      ]
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Creates a 30-minute intro call and invites the visitor by email.",
        "calendar": {
          "__rl": true,
          "value": "primary",
          "mode": "id"
        },
        "start": "={{ $fromAI('start', \"Meeting start, ISO 8601 with timezone\", 'string') }}",
        "end": "={{ $fromAI('end', \"Meeting end (30 minutes after start), ISO 8601 with timezone\", 'string') }}",
        "additionalFields": {
          "summary": "={{ $fromAI('title', \"Meeting title, e.g. Intro call — Company name\", 'string') }}",
          "attendees": [
            "={{ $fromAI('email', \"The visitor's email address\", 'string') }}"
          ],
          "description": "={{ $fromAI('notes', \"What they need, budget and timeline\", 'string') }}"
        }
      },
      "id": "310bce97-ca1c-4fa1-afb0-6f75bd0040c2",
      "name": "Book meeting",
      "type": "n8n-nodes-base.googleCalendarTool",
      "typeVersion": 1.3,
      "position": [
        470,
        220
      ]
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Creates or updates the visitor as a contact in our CRM.",
        "authentication": "appToken",
        "resource": "contact",
        "operation": "upsert",
        "email": "={{ $fromAI('email', \"The visitor's email address\", 'string') }}",
        "additionalFields": {
          "firstName": "={{ $fromAI('first_name', \"First name\", 'string') }}",
          "companyName": "={{ $fromAI('company', \"Company name\", 'string') }}",
          "message": "={{ $fromAI('summary', \"One-paragraph summary of their needs, budget and timeline\", 'string') }}"
        }
      },
      "id": "310bce97-ca1c-4fa1-afb0-6f75bd0040c2",
      "name": "Save lead",
      "type": "n8n-nodes-base.hubspotTool",
      "typeVersion": 2.1,
      "position": [
        640,
        220
      ]
    }
  ],
  "connections": {
    "Website chat": {
      "main": [
        [
          {
            "node": "Booking agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude model": {
      "ai_languageModel": [
        [
          {
            "node": "Booking agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Memory": {
      "ai_memory": [
        [
          {
            "node": "Booking agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Check availability": {
      "ai_tool": [
        [
          {
            "node": "Booking agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Book meeting": {
      "ai_tool": [
        [
          {
            "node": "Booking agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Save lead": {
      "ai_tool": [
        [
          {
            "node": "Booking agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}

Open in the playground to edit →

Tips

  • Write your ideal customer in one or two sentences in the prompt — it's the most important setting.

Related flows