Back to Insights
Technology

How to Build an AI Receptionist Platform with Claude Code

Four accounts, one spec, and Claude Code builds a receptionist platform on VoiceDock, Supabase and Vercel that answers calls and texts the caller a booking link. Every step from the video, every red light we hit, and what to check before a real client goes live.

Published October 12, 2026
19 min read

This guide follows the build from the video step by step, so you can do all of it from this page. You set up four accounts, hand Claude Code one spec, and it builds and deploys an AI receptionist platform: a receptionist that answers a business's phone, answers questions and texts the caller a link to the business's own booking page, with every call in a dashboard where each client sees only their own calls. A new client is one row in the database and one assistant, not new code.

Every command you type is on this page. The two spec files and the .claude folder that Claude Code works from are in the kit, which you download from Resources in the VoiceDock dashboard with a free account. The setup takes about ten minutes, the build takes Claude a good deal longer, and the text message in part 2 depends on how quickly Telnyx verifies you.

What you are building

The receptionist answers the phone for a business and answers questions about it. When a caller wants an appointment, it offers to text them a link to the booking page the business already has. Every call lands in your dashboard with a summary and, once part 2 is done, with the status of the text message. These are the parts and what each one does in this build:

PartWhat it does here
VoiceDockAnswers the call, runs the conversation on GPT-Live-1 and sends a report to your app when the call ends.
Your app on VercelA Next.js app that checks every incoming request, shows the dashboard and runs the text-message tool.
SupabaseClients, calls, text messages and logins. The database itself keeps each client's rows apart.
Telnyx (part 2)The phone number, and the text message to the number that called.
Claude CodeBuilds all of the above from the spec, and later adds what your clients ask for.

The reason to build a platform rather than one receptionist is the third client. A template you copy per business works for one or two of them. After that every change has to be made in every copy, and nobody remembers which copy is which. Here a client is a row in your database and an assistant in VoiceDock, so a change to the code reaches every client at once. ▶ 1:14

What you need before you start

WhatNotes
Claude CodeNeeds a paid Claude plan, such as Pro or Max. Install it with one line (below), then type claude in your terminal.
Node.js and GitFrom nodejs.org and git-scm.com, installed with the default options. Restart your terminal afterwards. The spec checks for both before it starts.
AccountsGitHub, Vercel and VoiceDock for part 1, Telnyx for part 2. Supabase comes through Vercel, so there is no second account with its own billing to manage.
The kitSPEC-PART-1.md, SPEC-PART-2.md, a .claude folder, and COMMANDS.txt with every command in this guide. In the VoiceDock dashboard under Resources; the latest version is always there.
Install Claude Code
# Windows (PowerShell)
irm https://claude.ai/install.ps1 | iex

# Mac
curl -fsSL https://claude.ai/install.sh | bash

No Node.js or Git yet? Ask Claude how to install them on your computer. It takes five to ten minutes, and it is the only part of this guide that differs per machine. ▶ 2:34

Part 1: set up (about ten minutes)

Do these steps in order. Everything here works right away, so there is nothing to wait for. Where a step needs an account you do not have yet, pause, create it and come back.

01Create an empty GitHub repository

Watch this step in the video: ▶ 4:29

In GitHub, choose New repository. Give it a name you will recognise, such as voice-receptionist-platform, make it private and tick Add a README. Private, because this repository will hold your clients' platform. The README matters for a different reason: Vercel cannot import a repository that is completely empty, and the README is enough to make it not empty. Keep the repository's URL at hand for step 5.

02Create a Vercel project from it

Watch this step in the video: ▶ 6:21

In Vercel, choose Add New, then Project, and import the repository from GitHub. If it is not in the list, connect your GitHub account or refresh the page. Because the repository has no code yet, Vercel cannot detect the framework, so set Framework Preset to Next.js yourself and click Deploy. This first deployment fails because there is no app yet. That is expected: the project now exists, and that is all this step is for.

03Add Supabase to the Vercel project

Watch this step in the video: ▶ 7:59

In the project, open Storage, choose Supabase and create a database. Pick the region closest to the callers of your clients. If your clients are in Europe, an EU region keeps their call records there, which is one part of where the data of a call is processed. On the free plan an organisation can run two Supabase projects at a time, so if you already have two, this one needs a paid plan.

Then connect the database to the project, for all environments. This is the step that is easiest to leave half done: the database exists, but the project cannot see it. Check Settings, then Environment Variables. You should see NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY and SUPABASE_SECRET_KEY. You never copy a key yourself; the integration puts them there.

04Tell Supabase where your app lives

Watch this step in the video: ▶ 10:39

You sign in to your dashboard with a link that Supabase emails to you. When you click it, Supabase sends you back to your app, and it only does that to addresses it knows. In Supabase, open Authentication, then URL Configuration. Set the Site URL to your Vercel production address, for example https://your-project.vercel.app, and under Redirect URLs add the same address followed by /**. The two stars allow every page under that address.

You find the production address under Domains in the Vercel project. If you would rather have a name you can predict than the one Vercel generates, add a free address ending in .vercel.app there first, for example voice-receptionist-yourname.vercel.app, and use it in both fields. A domain of your own works too, but then you also set up its DNS records, which this guide leaves out. Skip this step and the login link opens a localhost page or an error.

05Clone the repository in your own terminal

Watch this step in the video: ▶ 14:48

Open a terminal and go to the folder where you keep your projects. git clone creates the project folder for you, so do not make it yourself. Use the URL of your own repository from step 1; your account name differs from the one in the video, so the command cannot be copied as it is.

Terminal
cd <where you keep your projects>    # for example C:\Projects or ~/Projects
git clone https://github.com/<you>/<your-repo>.git
cd <your-repo>

The first time, GitHub asks you to sign in. On a Mac, if Git asks for a password instead, run gh auth login first with the GitHub CLI. Do this in your own terminal rather than asking Claude to clone it: Git cannot open the GitHub sign-in from inside Claude Code.

06Put the kit in your project folder

Watch this step in the video: ▶ 18:25

Unzip the kit and copy SPEC-PART-1.md, SPEC-PART-2.md and the .claude folder into the folder you just cloned. The .claude folder lets Claude Code use its three connections without stopping to ask permission for every call. Then create a file called .env.local in the same folder, with one line: the email address you will sign in with.

.env.local
ADMIN_EMAIL=you@example.com

On Windows without a code editor, Notepad will do. Save with “Save as type” set to All files and name the file .env.local, otherwise it becomes .env.local.txt. The file never goes to GitHub; the spec makes sure of that.

Before you build

Your commit name must match your accounts

Vercel only deploys commits from people on your Vercel team. If your computer uses a different Git name, for example from a work account, set one for this repository only. The spec checks this and tells you when it does not match.
Only if the spec asks for it
git config user.name "<your GitHub name>"
git config user.email "<id>+<name>@users.noreply.github.com"

Part 1: let Claude Code build it

07Connect Claude Code to VoiceDock, Supabase and Vercel

Watch this step in the video: ▶ 21:11

In your project folder, add the three connections and start Claude Code:

Terminal, in your project folder
claude mcp add --transport http voicedock https://mcp.hmsovereign.com/mcp
claude mcp add --transport http supabase https://mcp.supabase.com/mcp
claude mcp add --transport http vercel https://mcp.vercel.com
claude

These are MCP servers: the way Claude Code works with a service on your behalf. With these three it can create tables in your database, follow your deployments and create the receptionist in VoiceDock. In Claude Code, type /mcp and sign in to each one in your browser. There are no API keys to copy; you sign in as you would in the dashboard. With Vercel, give access to the team that owns your project.

VoiceDock is the account you may not have yet. Create it at dashboard.voicedock.ai, skip the onboarding and leave the empty dashboard as it is, because Claude fills it in. To check the connections, ask Claude whether it can reach all three. On a fresh VoiceDock account it finds one organisation and no calls. What the VoiceDock connection can do is listed in the MCP server docs.

08Give Claude the spec

Watch this step in the video: ▶ 24:27

Prompt
Read SPEC-PART-1.md and execute it.

Claude checks everything first: your tools, the three connections, the environment variables on Vercel and your Git name. Then it builds the app, the database with its security rules, the webhook that receives the call reports and the receptionist, pushes to GitHub and waits for Vercel to deploy. This takes a while. Get a coffee, or read the next section.

What Claude is building while you wait

It pays to know what each part does, because from here on you will be asking Claude to change it. ▶ 25:35

VoiceDock is the voice layer. It connects a phone line or a web call to the voice model, runs the conversation and sends a report to your app when the call ends. Vercel serves the app, which is built in Next.js, and deploys it again on every push to GitHub. Supabase is the backend: the database for clients, calls and texts, and the login. Its row-level security is what keeps one client's calls out of another client's view, and Claude works well with it because it can read both the documentation and your schema through the connection. Telnyx, in part 2, supplies the phone number and sends the texts.

The point of the build is not the receptionist. It is that Claude Code ends up knowing every part and how they fit together, so the next feature is a sentence instead of a project.

When it is done

A README for you, a CLAUDE.md for Claude

When the light turns green, Claude has written a README that explains what was built and how to use it, and a CLAUDE.md for itself with how the platform fits together, how to add a client and how to extend it. Read the README once. ▶ 39:19

Step 9: read the light

Watch this step in the video: ▶ 39:44

The spec ends with a verification. Green means every check passed: no secrets in your repository, each client sees only their own calls, unsigned requests to your app are refused, and the receptionist is connected to your app. Red means something is missing. Claude names the check that failed, explains it in plain words and gives you the exact steps. Fix it, then type run verification again. Ask Claude to explain it more simply if the first explanation does not land.

In the video the first light was red. The Supabase database existed but was not connected to the Vercel project, so the environment variables were missing. The fix was in Vercel, under the Supabase integration: connect the database to the project for all environments, and ask Claude to check again. These are the red lights we ran into ourselves:

What you seeWhat to do
Git cannot reach your repository, or “terminal prompts disabled”Clone the repository in your own terminal (step 5), sign in there and start Claude in that folder.
Vercel blocks the deployment: commit author not on the teamSet a Git name and email for this repository only (step 6).
Vercel says “not authorized” for your teamType /mcp, sign in to Vercel again and give access to the team that owns the project.
Claude's calls to VoiceDock, Supabase or Vercel are refusedThe .claude folder is missing from your project folder. Copy it in and start Claude again.
The Supabase variables are missing on VercelConnect the Supabase integration to all environments (step 3).
The login link opens a localhost page or an errorSet the Site URL and Redirect URL in Supabase (step 4).
No login emailSupabase's built-in email sends only a few mails per hour. Wait, check your spam folder and request the link once.
The text does not arrive (US)Your number is not registered yet. Texts to US mobiles only go out after 10DLC or toll-free approval.

Steps 10 and 11: sign in and talk to your receptionist

10Sign in

Watch this step in the video: ▶ 41:30

Open your app's address followed by /login, enter the email address from your .env.local and click the link in your inbox. Request it once: the built-in email of Supabase only sends a few per hour, and every extra request uses one up. What you see is your starting dashboard, empty for now and yours to build on.

11Talk to your receptionist

Watch this step in the video: ▶ 42:38

In the VoiceDock dashboard, open Assistants. Claude has created “Bright Smile Dental — Receptionist”. Start a web call from there and talk to it the way a caller would: ask what the practice does, then ask to book a check-up. Hang up, refresh your own dashboard, and the call is there with a summary.

In part 1 the receptionist offers the booking link but cannot text it yet. That is what part 2 adds.

Add a second client

Watch this step in the video: ▶ 45:46

Prompt
Add client Northside Plumbing with booking page https://example.com/book

Claude adds a row for the client to your database and creates a second assistant in VoiceDock with its own greeting. That is the whole change: one row and one assistant, the same code. Call the new assistant, and both calls appear in your dashboard, each under its own client.

For a real client you give Claude more to work with, such as their opening hours, what they do and do not handle, or the transcript of your intake meeting, and Claude writes the receptionist's instructions from it. Then check those instructions: some rules in a voice prompt are decided by the platform rather than the model and never take effect, and the rules in your prompt that never run shows how to find them.

Part 2: a phone number and the text message

The receptionist offers to text the caller a booking link, and the text goes to the number that called. Nobody can make it text another number, whatever they say on the phone. This part takes about five minutes of your time, plus however long Telnyx takes to verify you. ▶ 47:53

Why a text message and not an integration

Watch this step in the video: ▶ 48:19

Most businesses already have a booking page, with their calendar, their time slots and their confirmation emails. Texting a link to that page means nothing breaks when their booking software changes, their own system keeps its own records, and there is nothing for you to maintain. Nearly every caller is on a mobile, a text costs them almost no effort, and it takes the same pressure off the phone line. For existing patients or customers who want to move an appointment, text the link to the business's login portal instead.

Default

Text the booking link

  • Works with whatever booking page the business already has
  • Nothing to maintain when their software changes
  • The business keeps its own records
  • Live for a new client in minutes
When it pays off

Connect the booking system

  • Books the slot during the call
  • A custom build per software package
  • Yours to fix when their API or setup changes
  • Worth it once several clients use the same software

A direct connection is possible, but it is a build you then maintain. What it takes to do one properly is in tool calls to business systems, and recognising a caller by their number before they say who they are is in knowing who is calling.

Telnyx: account and verification

Watch this step in the video: ▶ 50:40

Create a Telnyx account and complete the verification Telnyx asks for under Account Levels. In most countries outside North America that is quick, sometimes instant, sometimes a day or two. Texts to the US, Canada and Puerto Rico cannot come from a sender name; they come from a number. To text US mobiles from a US number, that number needs an approved 10DLC campaign, and Telnyx only accepts the registration once your account has passed its own verification. A verified toll-free number is the alternative, and it also reaches Canada. The Campaign Registry puts campaign review alone at one to four weeks, so start today and keep building in the meantime. ▶ 51:36 What that registration asks of you, and how to get it approved the first time, is in 10DLC registration for AI receptionists.

Telnyx: API key and messaging profile

Create an API key. Then go to Messaging, Programmable Messaging, and create a messaging profile. Allow only the countries you text to, tick “mobile numbers only”, and outside North America fill in a sender name. In the US, add your registered number to this profile. Set a daily spend limit on the profile while you are there; it is the cheapest insurance in this whole build.

A phone number in VoiceDock

For testing, request a test number in the VoiceDock dashboard under Numbers. For real callers, connect your client's own number over a SIP trunk; we help you set that up. In the video the number is Dutch, and yours may be American, Canadian or German. What matters is the trunk behind it, not the country. When a call does not arrive, the SIP logs tell you at which layer it failed.

Add four lines to .env.local

Watch this step in the video: ▶ 52:06

.env.local (add to the bottom)
TELNYX_API_KEY=...
TELNYX_MESSAGING_PROFILE_ID=...
TEST_PHONE_NUMBER=+...       # your own mobile, to receive the test text
TELNYX_FROM_NUMBER=+1...     # US only: your registered number

Fill them in and leave out the comments. The API key is a secret: it belongs in this file and in Vercel, and nowhere else.

Give Claude part 2

Prompt
Read SPEC-PART-2.md and execute it.

Claude adds the text-message tool to your app, updates the receptionist and connects the number, and it can do the same for every client you add later. During the verification you receive a real text on your own phone. That is your green light.

Call it

Watch this step in the video: ▶ 53:22

Call the number, ask for an appointment and watch the text arrive. In the video the caller first asks what makes the practice different, the receptionist answers and offers the link again, and the text arrives while the call is still going. The dashboard shows whether it was delivered.

Why GPT-Live-1 is the voice

There are three ways to give an agent a voice. The classic pipeline turns speech into text, sends the text to a language model and turns the answer back into speech. It gives you control over every step and is still widely used. Speech-to-speech models such as Gemini Live hear audio and answer in audio, with no text in between. GPT-Live-1 from OpenAI is a full-duplex model: it listens while it speaks, and decides for itself when to let itself be interrupted and when to take the turn. On a receptionist that shows in three ways. ▶ 29:24

  1. 01

    It back-channels

    It says “mm-hmm”, “right” and “that's right” while the caller talks, at natural moments, and you can prompt how much. A caller with a long story feels heard instead of talked over. ▶ 30:56
  2. 02

    It follows the caller, not the room

    Background voices are the most common reason a phone agent stops mid-sentence: a transcriber cannot tell the caller from a child shouting nearby, so it thinks it is being interrupted. GPT-Live-1 can be prompted to follow only the caller, and to say, when it hears other voices, that it has trouble hearing and ask whether the caller can find a quieter place. Why the other models struggle with this is in barge-in that actually works. ▶ 31:31
  3. 03

    Talking and working are split

    The voice model holds the conversation and hands long or complex tasks to a separate backend model, and keeps talking naturally while that work runs. Useful, and something to keep in mind as soon as it calls tools; the details are in GPT-Live-1 on a phone line. ▶ 33:00

The voice layer costs a flat $0.05 per minute at OpenAI, billed per second, with no tokens to count. The backend model is billed separately in tokens, and for a receptionist that mostly talks that part stays small. How those meters add up with telephony and a platform fee is in what a voice agent really costs per minute. One limit to know before you choose it for a client: OpenAI processes the audio outside the EU by default, so for calls that must stay in Europe another model is the better fit.

Four security rules for voice agents that text

Videos that hand you a quick setup tend to skip this part. These four come from running voice agents on real phone lines, and they apply to everything you build on top of this platform. ▶ 35:22

  1. 01

    Text only the caller

    The text goes to the number that is calling, never to a number someone says out loud. There are three reasons. Someone can try to make you text an expensive premium destination; a caller can say their own number wrong; and the model can hear it wrong, because it is not deterministic. Allow a spoken number only in a specific case you have thought through.
  2. 02

    Keep secrets secret

    The Supabase secret key and the Telnyx API key live in Vercel's environment variables and in your .env.local, and nowhere else: not in the browser, not in your repository, not in a screenshot you post in a help channel. Treat them like passwords, and ask Claude to show you where this platform uses them.
  3. 03

    Lock down where calls can go

    When you add call transfers, and especially when clients can enter a transfer number themselves, restrict the destinations at your carrier. Some international destinations cost several dollars a minute, and fraudsters route calls there because they are paid per minute. What else goes wrong with transfers is in when the transfer fails.
  4. 04

    Put a spending limit on everything that bills you

    Telnyx lets you set a daily limit on a messaging profile, and Vercel has spend management. Go through every account in this build that charges automatically and set a limit where you can. If everything else fails, that limit is your worst case.

The build itself already takes care of these:

Built inWhat it means
Signed requestsYour app refuses every request from VoiceDock without a valid signature, or older than five minutes.
Each client sees only their own callsThe database enforces it with row-level security, not just the app.
Secret keys stay on the serverNothing secret reaches the browser or your repository.
Texts go only to the callerThe model cannot choose the recipient or the message. One text per call.
Passwordless loginOnly your admin email can sign in, and only with access to that inbox.
Old calls are deletedCalls and texts are kept for 90 days by default. Agree the period with each client.

Before a real client goes live

CheckWhy
Their own number over a SIP trunkA test number is for testing. Callers should reach the number the business already has.
A registered text senderIn the US, 10DLC or toll-free approval (see 10DLC registration). Elsewhere a sender name, and in some countries a registration.
A spend limit on the messaging profileYour worst case, if everything else fails.
The retention periodAgree it with the client and set it per client. The default is 90 days.
Your own email sender in SupabaseThe built-in email is for testing, and only sends a few per hour. Set your own before clients log in.
The calls it gets wrongBackground noise, someone switching language, a caller who wants a human. Test those before your client's customers do.
The booking page on a phoneThat is where the link opens.
AI disclosure in the EUFrom 2 August 2026 a caller in the EU must be told they are talking to an AI. See EU AI Act Article 50.

What to build next

Claude already knows where each of these plugs in, because it is written in your CLAUDE.md together with the security rules and the check that proves it works. Start a new session in your project folder and ask, for example, “Read CLAUDE.md and add client logins.” ▶ 27:41

AddWhat it gives you
Client loginsInvite your client by email; they see only their own calls.
Stripe subscriptionsBill each client per month or per minute.
Branded emails with ResendA summary in your client's inbox after every call.
A calendar connectionGoogle or Outlook, so the receptionist sees free slots.
Call transferPut the caller through to a fixed number per client.
Call analysisWhat callers asked for, and a view of it in the dashboard.

If you build these receptionists for clients, two things decide your margin more than the build does: what a minute costs you, and how fast your stack answers. Both have their own article, on cost per minute and on the latency budget of a call, and how we work with agencies is on the agencies page.

Where to get help

A red light that you and Claude cannot solve goes in the help forum of the VoiceDock community on Discord. Leave your keys out of the post. The latest kit and runbook are always in the VoiceDock dashboard under Resources.

Sources Claude Code setup and connecting MCP servers; VoiceDock MCP server; Supabase on the Vercel Marketplace; Supabase on redirect URLs, row-level security and custom SMTP; Telnyx account levels; Vercel spend management.