Skip to content
← All systems

AI phone receptionist · multi-tenant SaaS

In build

Nova Reception

A phone number that answers, understands, and writes to a database.

An AI receptionist for Indian service businesses. It takes the call, answers from the business's own knowledge base, books against a real calendar, captures the lead, and hands off to a human when it should — for one salon or for forty under a single login.

48K
TypeScript LOC
17
Agent tools
543
Test cases
9
Workspace packages

The hard part

The AI offered a 3:30 PM slot. The caller said yes 18 seconds later. In those 18 seconds, someone else booked 3:30. What happens?


Nothing bad — because 3:30 was never free during those 18 seconds. Offering a slot takes an expiring hold on it, and the booking itself is guarded by a Postgres btree_gist exclusion constraint. A double-booking is impossible at the database level rather than unlikely at the application level.

Design decisions

01

The agent cannot invent a fact

It never states a price, an opening hour, an availability or a policy that did not come back from a tool result. 17 tools cover business info, hours, the service catalogue, knowledge search, customers, availability, booking, rescheduling, cancelling, lead capture, transfer, voicemail and hangup. The three tools that change the world — book, reschedule, cancel — require a spoken yes first.

02

Tenant identity is never a model parameter

Every function touching tenant data takes businessId as its first argument, and business_id is not a field on any tool schema. The AI cannot supply it; the server injects it. A prompt-injected caller has no vocabulary for reaching another tenant's data.

03

Two deployables, on purpose

A serverless function cannot hold a live phone call — no inbound WebSocket server, an execution-time cap, and a media session is nothing but in-process state. The web app ships to Vercel; the voice runtime is a persistent Node process on Railway. The split is a documented architectural decision, not an accident.

04

Mock mode that actually works

Telephony, speech, LLM, email, billing and storage each sit behind an interface with a working mock. The whole product runs with zero API keys against a local Postgres, which is what keeps the test suite fast and the onboarding three commands long.

05

Designed for the bad day

A failure ladder defines a spoken script for every degradation level, so a caller never gets silence. Per-tenant spend caps and a kill switch mean a runaway loop cannot bill ₹50,000. A latency budget targets P50 under 800ms from caller-stops-talking to audio-starts, instrumented rather than hoped for.

06

Compliance built in, not bolted on

A DPDP consent layer records consent events with a hash of the exact notice text shown, so what someone agreed to is provable later. Call recording defaults to off, per business. Retention and erasure are jobs, not manual SQL.

Stack

  • TypeScript (strict)
  • Next.js 15
  • Fastify + ws
  • Prisma
  • PostgreSQL 16
  • pgvector
  • BullMQ
  • Exotel
  • Turborepo
  • pnpm

My part in it

Sole architect and engineer — product spec, data model, agent design, and the unit-economics model behind the pricing.


What is not done

Phases 0 through 5 have landed: schema, core booking logic, the agent and its eval harness, the voice runtime, and the web app. Hardening is phase 6 and is not done. No paying tenant is live on it yet.