Inspiration

Speed-to-lead is one of the best-documented, least-automated problems in sales — contacting a lead within minutes instead of hours measurably changes whether it converts, but it rarely happens because someone has to drop everything the instant a form comes in. CALL-E made it possible to build the thing that should already exist: an agent that places that first call itself and comes back with a real qualification, not just a "submitted" timestamp.

## What it does

A prospect fills out a lead form, and within about a minute MinuteOne calls them back, runs a qualification conversation built from a business's own config, scores the answers, and routes the result — qualified, not qualified, wants a callback, no answer, wrong number, declined. Configuring the business happens entirely in-app via a /setup wizard: business info → qualifying questions → a live test of the actual form.

MinuteOne launches as a focused single-tenant demo — one business, no accounts — with a multi-tenant self-serve product (sign up, your own business config, your own embeddable form, your own scoped dashboard) already prototyped and next on the roadmap.

## How I built it

Next.js 16 with Drizzle ORM over SQLite locally / Turso when deployed, on Netlify. CALL-E has no REST SDK — only an OAuth-protected MCP server — so the real call provider is an @modelcontextprotocol/sdk client driving plan_call → run_call → get_call_run polling directly. Dispatch is one shared core, called by a local poller in dev and a Netlify scheduled function in production, with an atomic conditional UPDATE so two overlapping ticks can never double-dial the same lead. Dry-run is the default everywhere — the whole flow is explorable with zero credentials and zero real calls placed.

## Challenges I ran into

Placing one real verification call surfaced more than any amount of dry-run testing did. CALL-E's real API has no structured-output parameter — a fully answered, successfully completed conversation was scoring itself as a failure, because the qualification answers only ever came back as prose in a transcript, not the JSON keys the scoring logic expected. Fixed with a two-tier recovery: an optional LLM extraction pass, falling back to a free local regex/keyword parser when no LLM credential is set. The same call also showed the poll-timeout ceiling was tuned for a demo conversation, not a real one — a genuinely completed call got clipped and logged as a timeout.

Scoping the multi-tenant architecture was its own challenge: the config system, dispatch worker, intake API, and review UI all needed to agree on how a business gets resolved behind one function, so single-tenant today and multi-tenant next stay the same codebase instead of a rewrite. back as prose in a transcript, not the JSON keys the scoring logic expected. Fixed with a two-tier recovery: an optional LLM extraction pass, falling back to a free local regex/keyword parser when no LLM credential is set. The same call also showed the poll-timeout ceiling was tuned for a demo conversation, not a real one — a genuinely completed call got clipped and logged as a timeout.

Scoping the multi-tenant architecture was its own challenge: the config system, dispatch worker, intake API, and review UI all needed to agree on how a business gets resolved behind one function, so single-tenant today and multi-tenant next stay the same codebase instead of a rewrite.

## Accomplishments that I'm proud of

Verifying against a real CALL-E call instead of stopping at dry-run — and finding two genuine integration bugs that only a real call could have surfaced, then fixing both. A demo that needs zero credentials and places zero real calls by default, so anyone can try the full flow immediately. And an architecture where "add multi-tenancy" is a config-resolution change, not a rewrite.

## What I learned

A "should support X" assumption about a third-party integration doesn't survive contact with the real API — the only way to find out is to place the call, not read the docs.

## What's next for MinuteOne

The multi-tenant self-serve product: accounts, per-business config, an embeddable lead-capture form, and a dashboard scoped to just your own leads — already prototyped, next to ship. Beyond that: business hours and scoring editable in /setup, and the real call transcript surfaced in the review console instead of just the summary.

Built With

Share this project:

Updates