Building Bookee: An AI Voice Assistant That Books My Meetings
How I rebuilt an AI receptionist from 5 platforms to 3 systems — fixing invisible calendar bugs, preventing double-bookings, shipping real Stripe deposits, and landing at $0.12 per qualified lead.
Client
Self (summerchang.co)
Role
Builder · Full-Stack Developer
Tools
Vercel, Dograh, Claude API, Twilio, Google Calendar, Notion
Timeline
May 2026
tl;dr
LinkedIn was sending leads, but most weren't qualified — four calls would yield one actual client. I built Bookee, an AI voice assistant that calls leads within 60 seconds of form submission, qualifies them with a real conversation, and books a meeting on my calendar. The v1 used 5 platforms stitched with webhooks. The v2 uses 3 systems and costs $0.12 per qualified lead.
5 → 3
Platforms reduced from v1 to v2
$0.12
Cost per qualified lead
60s
Form to phone call
Attention broke my pipeline.
LinkedIn posts drove hundreds of DMs and calendar requests. Four calls would yield three hours of conversation and one actual client. Designers wanted mentorship. Founders were "just exploring." The content was working — for the wrong audience. I needed a front desk, not more content.
Five platforms, stitched with webhooks.
The first version used n8n, Vapi, ElevenLabs, Airtable, and Cal.com — five platforms stitched with webhooks. It cut intake time from 18 hours to 5. But the system was fragile. Eight webhook connections, each one a failure point. Debugging across four dashboards when it broke was the real job.
“The v1 proved the concept. The v2 is the product.”
One form, six autonomous steps.
The rebuild replaced everything with three systems: Vercel (backend), Dograh (voice), and Google Calendar (booking). When a lead fills out the form, the system takes over. Verification and research run in parallel, so the call fires within 60 seconds.
Capture
Lead submits name, email, phone, and website URL
Verify
Twilio Lookup confirms the phone and checks carrier type
Research
Claude API searches the web, generates a business summary
Call
Dograh triggers an outbound AI call within 60 seconds
Book
Agent checks real Calendar availability, offers slots
Confirm
Meeting created with Meet link, invite sent, Notion updated
Twilio Lookup and the Claude research run together via Promise.all — that alone cut 3–5 seconds off the pipeline.
Three systems, one data flow.
The frontend captures the lead. The backend owns verification, research, and triggering. Dograh runs the call and calls back into the backend for calendar operations. After the call, a webhook closes the loop in Notion.
Twelve bugs, twelve fixes.
| The bug | The fix | |
|---|---|---|
| Invisible calendar bookings | Events returned real IDs but never appeared — service-account auth writes to an invisible calendar owned by the service account, not me. | Switched to OAuth2 with a personal refresh token. |
| npm peer-dep conflict | vaul wants React 16/17/18; the project runs React 19, so install failed. | Installed with --legacy-peer-deps. |
| Access blocked on Google OAuth | The consent screen was stuck in Testing mode, so only allowlisted users could authorize. | Published the app to production. |
| Production serving old code | The PR was merged to a feature branch, not main — Vercel kept deploying the old version. | Merged the PR to main. |
| book-slot returning a generic error | The catch block swallowed the real exception, hiding the cause. | Added a temporary debug field — GOOGLE_CALENDAR_ID was wrong. |
| 404 from the Calendar API | GOOGLE_CALENDAR_ID pointed at an old group calendar that no longer existed. | Set it to 'primary'. |
| get-slots showing everything free | Google's freebusy API silently returns 200 with an errors array for unreadable calendars instead of busy slots. | Detect the errors array and return 500 instead of lying about availability. |
| Google invite email not arriving | When the organizer is also an attendee, Google suppresses the notification. | Not a bug — test with a different email address. |
| The phone didn't ring | Stored as +115106810766 instead of +15106810766 — Dograh created the call run but Twilio couldn't dial. | Removed the extra digit. One character, all the calls. |
| Double-booking risk | A slot could get taken between display and insert. | book-slot re-checks freebusy right before inserting and returns 'that slot was just taken.' |
| Dograh 402 — trial exhausted | Dograh's free trial tokens ran out mid-testing. | The founder granted 2,000 tokens to unblock it — an upside of open source. |
| Leaked secrets in git history | A real Notion token was committed to the README early on, and the Dograh key carried over. | Rotated both and verified .gitignore excludes every .env file. |
The hardest bug
The hardest bug wasn't in the AI or the voice — it was an extra digit in a phone number. Dograh created the call run, but Twilio couldn't dial. One character fix.
Four nodes, one conversation.
The Dograh voice agent has four nodes: Global (rules for every node), Start Call (greeting + business mention), Main Agenda (scheduling flow), and End Call (wrap-up).
The biggest prompt issue was repetition — the greeting mentioned the business, then the Start Call prompt told the agent to mention it again, and the Global Node echoed business context into every node. The fix was making the business mention conditional and one-shot: mention it once in the opening, then never again.
TCPA compliance isn't optional.
Automated calls require consent under TCPA. These aren't just legal requirements — they're trust signals.
Consent
Checkbox names the caller ID (+1 510 681-0766)
Backend gate
Blocks submission if consent is false
Audit trail
Consent flag, timestamp, exact text — all in Notion
AI disclosure
Stated at the top of every call
Voicemail
Detection enabled to avoid wasted minutes
Pipeline speed
Twilio + Claude run in parallel via Promise.all
Shipping it for real — pricing, payments, an open-source tier.
Getting it working end-to-end was the first half. Making it something someone could actually buy was the second.
“A human receptionist costs $3,000+/month. Bookee runs for under $10 — roughly 300× cheaper. That's the whole pitch.”
Two tiers, not five
I started with a three-tier ladder and cut it down. Final: Self-Deploy (free, open source) and Done-For-You at $3,497 — a refundable $874.25 deposit, live in 24–48h. The free tier ships as a GitHub template with fresh git history and no secrets.
Real money
Took Stripe deposits from test to live: a dedicated live account, a live webhook (checkout.session.completed) pointed at bookee.tech/api/webhook/stripe, and a verified $874.25 deposit.
Idempotency, because Stripe retries
A guard skips re-triggering if Notion already shows 'deposit paid,' and the success page retrieves the real session by session_id instead of trusting the URL.
Vercel's Lead Agent vs. Bookee.
When Vercel shipped its own lead agent, it forced the question: what is Bookee, exactly? They sit at opposite ends of the same problem.
| Vercel Lead Agent | Bookee | |
|---|---|---|
| The job | Qualifies the lead, drafts a reply | Calls the lead, books the meeting, takes the deposit |
| Human role | In the loop — reviews and sends | Out of the loop — untouched by human hands |
| Finish line | A drafted response | A booked, paid meeting |
| Speed | As fast as the human | Under 60 seconds, every time |
| Best for | High-touch sales teams | Solo operators and service businesses |
The one thing worth borrowing from Vercel: durable execution — retries plus visibility would have surfaced the Dograh 402 instead of letting it fail silently.
“Bookee is the opposite end of the same problem: instant, autonomous call + booking + payment.”
v1 → v2, by the numbers.
| Before (v1) | After (v2) | |
|---|---|---|
| Platforms | 5 (n8n, Vapi, ElevenLabs, Airtable, Cal.com) | 3 (Vercel, Dograh, Google Calendar) |
| Failure points | 8+ webhook connections | 4 API endpoints |
| Voice cost | $0.05/min (Vapi) | ~$0.01/min (Dograh) |
| Monthly cost | $30–50/mo | $8–12/mo |
| Cost per qualified lead | not tracked | $0.12 |
| Pipeline speed | 12–25s sequential | 3–5s faster (parallelized) |
Open source both ways: the v1 lives as an n8n template; the v2 ships as a self-deploy template. Live at bookee.tech.
Key Takeaways
- 1Speed-to-lead is a real competitive edge — automate it
- 2Service-account auth is invisible — use OAuth2 for real calendar access
- 3Google's freebusy API silently fails for unreadable calendars — always check the errors array
- 4Parallelizing API calls (Promise.all) cut 3–5 seconds off the pipeline
- 5Voice AI prompt repetition kills the conversation — mention context once, then drop it
- 6The hardest integration bugs hide in the smallest places (one extra digit)
- 7TCPA consent isn't optional — build it into the form and the database
- 8$0.12 per qualified lead makes the unit economics work for any service business
Tools I like
- DograhOpen-source voice AI platform for outbound and inbound calls
- Claude APIWeb search + AI summary for lead research before the call
- TwilioPhone number validation ($0.005/check) and telephony
- NotionLead database, consent records, and lightweight CRM
- Google Calendar APIReal availability checks, event creation, and Meet links via OAuth2
- StripeLive deposits and checkout for the Done-For-You tier, with idempotent webhooks
Personalized greetings — resolving template variable rendering with the Dograh founder. Embeddable widget — one script tag for any website (WordPress, Squarespace, Wix). Vertical templates for service businesses (salons, coaches, agencies). AWS hackathon submission. ElevenLabs voice clone integration.
Personalized greetings — resolving template variable rendering with the Dograh founder. Embeddable widget — one script tag for any website (WordPress, Squarespace, Wix). Vertical templates for service businesses (salons, coaches, agencies). AWS hackathon submission. ElevenLabs voice clone integration.
