An AI lead generation agent that books meetings while you sleep
How we build AI lead gen agents that actually book meetings overnight: the workflow, the prompts we use, the guardrails that stop it from embarrassing you.
- ↳A working lead gen agent is three small agents (qualifier, replier, scheduler) not one big prompt.
- ↳The scheduler is the only part that touches your real calendar, and it should hold a lock before writing anything.
- ↳Guardrails matter more than prompts: rate limits, an allow-list of intents, and a human-in-the-loop for anything above a dollar threshold.
- ↳Log every tool call with the exact input and output. When the agent books the wrong meeting at 3am, you need the trace.
The pitch is seductive. An AI lead generation agent that reads inbound messages, qualifies the person, replies in your voice, and drops a meeting on your calendar while you sleep. I’ve built a version of this for three clients now, and one for us at EdsDev. It works. It also breaks in ways that are genuinely funny if it isn’t your calendar.
Here is how I actually build these, what the prompts look like, and the guardrails I wish I’d added on day one instead of day thirty.
What the agent actually does
Forget the demo videos. A useful agent has a small job description you could write on an index card.
Ours, for context: read inbound from the contact form and a shared inbox, decide if the sender is a real lead or a recruiter pitching Upwork developers, ask up to two clarifying questions, then offer three time slots from my Google Calendar and confirm the booking. That is it. It does not send cold outbound. It does not write proposals. It does not talk to existing clients (those go to a separate queue).
The smaller you make the job, the better the agent gets. Every time I’ve tried to give one agent three jobs, the middle job is the one that goes sideways at 2am.
The three-agent split
I stopped writing one giant prompt around mid-2024. Now I split any lead gen workflow into three agents that call each other through tools:
- Qualifier reads the message, extracts fields (company, use case, budget signal, timeline), returns a score and a reason.
- Replier writes the response in the founder’s voice, given the qualifier’s output and the last three emails in the thread.
- Scheduler the only one with write access to Google Calendar. Takes a confirmed intent and books it.
Each one is a separate Claude call with its own system prompt and its own tool list. The qualifier cannot touch the calendar. The replier cannot mark a lead as unqualified. This separation is the single biggest reliability win I’ve found. If the replier hallucinates a meeting time, the scheduler refuses because the slot isn’t in its offered set.
Here’s the shape of it, roughly:
async function handleInbound(msg: InboundMessage) {
const qualified = await qualifier.run({ message: msg, thread: msg.thread });
if (qualified.score < 0.4) {
await archive(msg, qualified.reason);
return;
}
const reply = await replier.run({
message: msg,
qualification: qualified,
voiceExamples: await getRecentSentEmails(20),
});
if (reply.intent === "book_meeting") {
const slots = await scheduler.offerSlots({ timezone: qualified.timezone });
await send(reply.body + renderSlots(slots));
} else {
await queueForReview(reply);
}
}
Notice the queue-for-review branch. Roughly 30% of replies go there in the first two weeks of a new deployment. That number drops as the voice examples get better.
The qualifier prompt, roughly
I’m not going to paste the full production prompt because it’s client-specific, but the structure is public. The qualifier gets:
- A description of the ideal customer in specifics (“Canadian SMB, 5-50 employees, currently doing X manually”).
- Three examples of qualified leads with reasoning.
- Three examples of unqualified leads (recruiters, students, competitors doing recon).
- A schema to return:
{ score: 0-1, reason: string, extracted: {...}, timezone: string | null }.
The examples do more work than the instructions. I’ve rewritten the instructions section four times and it barely moves the needle. Adding one weird real example (“this looked qualified but was actually a competitor, here’s the tell”) moves the score 5-10 points.
The replier is where voice lives
The replier gets the last 20 emails I’ve actually sent to leads, verbatim. Not a style guide. Not “write in a friendly professional tone.” Actual emails, with the greetings, the typos I didn’t fix, the way I say “quick note” too often.
Claude 3.5 Sonnet and now Sonnet 4 are both good enough at this that a stranger reading the reply usually can’t tell. My mom can tell. My co-founder can tell. But the lead can’t, and that’s the bar.
The replier returns structured output: { intent: "book_meeting" | "ask_clarifying" | "decline" | "escalate", body: string, confidence: number }. If confidence is below 0.7, it escalates to me regardless of intent.
The scheduler and its guardrails
This is the dangerous one. It writes to a real calendar. If it double-books me, I look like an idiot to a paying customer. Here is what protects that:
- Slot locking. Before offering three times to a lead, the scheduler puts a tentative hold on all three for 45 minutes. If the lead doesn’t confirm, the holds expire.
- A hard allow-list of intents. The scheduler only accepts a payload from the replier with a signed slot ID. It cannot invent a time.
- Rate limits. Max 6 bookings per day, max 2 per hour. If it wants to book more, it pages me. This has fired exactly once, when a Product Hunt post drove a spike.
- A dollar threshold for anything past the meeting. The agent can book. It cannot send a contract, cannot quote a price, cannot commit to a deadline. Those go to me.
We log every tool call to a Cloudflare D1 table with the input, output, model, and latency. When something breaks, I read the trace before I read the prompt.
Where this overlaps with support
A lot of the same plumbing works for an ai agent for customer support. The qualifier becomes a classifier (billing, bug, feature request, churn risk). The replier still writes in voice. The scheduler becomes a ticket-creator or a refund tool. The guardrails matter even more because ai chatbots for customer service are talking to people who are already annoyed.
The pattern is the same: small agents, one tool each, structured output, log everything, human-in-the-loop above a threshold.
What breaks, honestly
A few things I did not expect:
- Timezones. The agent kept offering 4am slots to people in Australia because it inferred timezone from language, not from the actual sent time or an explicit ask. Fix: always ask, don’t infer.
- Threading. Gmail’s threading via References headers is fine. Outlook’s is a mess. If you support both, test both.
- The follow-up loop. If a lead doesn’t respond to the three offered slots, when does the agent nudge? I set it to 48 hours, once. Any more and it feels desperate.
- The agent being too helpful. Early version would answer detailed technical questions in the reply, which meant the meeting never happened because the lead already got what they wanted. Now the replier is explicitly told to leave the interesting questions for the call.
What I’d build next
Honestly, I’m not sure the fully-autonomous version is better than a semi-autonomous one. The version I use daily drafts everything and books nothing without a one-tap approval from my phone. It’s 90% as fast and 100% less scary. For clients with higher volume, full auto makes sense. For a founder doing 5-15 inbound a week, drafts are probably enough.
If you want help building one of these against your actual inbox and calendar, get in touch and tell me what your qualifier would need to know.
Common questions
▸How long does it take to build an AI lead generation agent like this?
For a single inbox and calendar, about 2-3 weeks to get to production, with another 2-4 weeks of tuning based on real conversations. Most of the first phase is not code, it's collecting voice examples, writing qualification rules, and setting up logging. The code itself is maybe 800-1200 lines. The tuning phase is where you fix the weird stuff: the recruiter who looks like a lead, the timezone inference, the follow-up cadence.
▸Can I use this with tools like Cursor or Claude Code instead of hiring someone?
Yes, if you are comfortable with TypeScript and API keys. The three-agent split, the calendar tool, and the logging table are all standard patterns. What you cannot vibe-code is the guardrails and the tuning. That part is boring, high-consequence, and needs real testing against your actual mail. I've cleaned up two of these where the initial build worked in the happy path and shipped bookings to the wrong customer in edge cases.
▸What does it cost to run per month?
For a low-volume inbox (under 500 inbound a month), the model costs are typically $15-40 on Claude Sonnet, plus about $5 for Cloudflare Workers and D1 storage. If you use a shared calendar API like Cal.com or Google Calendar directly, that's free. The main cost is the initial build and the ongoing prompt tuning, not the runtime.
▸How do I stop the agent from saying something embarrassing?
Three things do most of the work. First, structured output with a confidence score, and anything under a threshold gets human review. Second, a strict tool allow-list so the agent physically cannot send a contract or quote a price. Third, log every reply before it sends and review the first 100 in production. Almost every real issue I've seen was visible in the logs by message 20.
▸Does this work for cold outbound too?
I don't build cold outbound agents, and I'd push back on anyone selling you one. The reply rates are already low, the deliverability risk is real, and an AI writing cold email at scale is how you get your domain flagged. Inbound qualification and reply is a different problem. The lead already asked. You are helping them faster, not interrupting them.
Related posts
An AI lead generation agent that books meetings while you sleep
How we build AI lead generation agents that actually book meetings: the workflow, the prompts, the guardrails, and the bits that quietly break at 3am.
Building an AI chatbot for small business that actually knows your products
The RAG stack we ship for small businesses that need a chatbot to answer questions about their actual products, not hallucinate a generic FAQ. Real code, real costs.
AI agent for customer support vs. the chatbot you already tried: what's actually different
You bought a chatbot. It answered FAQs and pissed off your customers. Here's what an actual AI agent does differently, and where it still falls on its face.