A Living Memoir. A Safer Home.
AI companion for seniors that captures life stories and keeps families connected through regular voice calls, mood insights, and beautiful weekly story excerpts.
1 in 4 seniors experience chronic loneliness. 70% of family histories are never recorded. Most families live too far away to call every day — and even when they do, the conversations stay in their heads and disappear.
Everly fixes both.
- In-browser (current demo): When you click Start call on the dashboard or elders list, the call runs in your browser (mic + speakers). No phone number is called. You're talking to the AI directly on your device. The elder's
phonein the database is not used. If you see a call in the VAPI dashboard with ~30 seconds, that is this web call (browser session), not an outbound call to any number. - Outbound phone calls (optional): The backend has an API route
POST /api/callthat uses VAPI's phone product. Only if you trigger that (e.g.curl -X POST .../api/call -d '{"elderId":"..."}'or a "Call their phone" button), then:- VAPI calls the elder's phone number (
elder.phonefrom Supabase). - The call is placed from the VAPI phone number linked to
VAPI_PHONE_NUMBER_IDto the elder's number. So for real phone calls, the number that gets called is the elder's number stored in the database. In the VAPI dashboard, an outbound phone call will show a destination number; a web call will not.
- VAPI calls the elder's phone number (
If you click Start call and the VAPI dashboard shows time passing but you hear/see nothing in the browser:
- No number is called — This is a web call. The 30 seconds in VAPI is the browser session, not an outbound call to a phone number.
- Open the browser console (F12 → Console). You should see
[VAPI] call-startwhen the call actually starts. If you never see it, the SDK may still be connecting. - Check audio:
- Allow microphone when the browser prompts.
- Ensure the tab is not muted (no mute icon on the tab).
- Try headphones or a different speaker in case output is going to another device.
- Check the assistant in VAPI Dashboard:
- Assistant has a first message (e.g. "Hello {{elder_name}}! How are you today?") so the AI speaks first.
- Voice is set (e.g. ElevenLabs) and the voice ID is valid.
- VAPI Dashboard → Calls: Open the call that shows ~30s. Check if it's Web or Phone. For Web, there is no "number called"; for Phone, the destination number is the elder's
phonefrom your database.
- Node.js 20+
- Accounts: Supabase, VAPI, Anthropic, ElevenLabs (for voice)
git clone <your-repo-url>
cd genesis-genai/frontend
npm installCopy the example env and fill in your values:
cp .env.example .env.localRequired for the app:
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_SUPABASE_URL |
Supabase project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
Supabase anon (public) key |
SUPABASE_SERVICE_ROLE_KEY |
Supabase service role key (server-only) |
NEXT_PUBLIC_VAPI_PUBLIC_KEY |
VAPI public key (for in-browser calls) |
NEXT_PUBLIC_VAPI_ASSISTANT_ID |
VAPI assistant ID (same as in dashboard) |
Optional (for outbound phone calls via /api/call):
VAPI_API_KEY— VAPI API key (server)VAPI_PHONE_NUMBER_ID— VAPI phone number to call from
In the Supabase SQL Editor, run the schema that creates elders, call_logs, and memories (see hackathon checklist or docs/ if you have it). Then add at least one elder (or use "Add elder" in the app).
npm run devOpen http://localhost:3000. You'll see the elders list; use Start call for an in-browser demo call (grant mic when prompted).
The Problem: VAPI sends call data (transcripts, summaries, memories) via webhooks to your server. But during local development, your localhost isn't accessible from the internet, so VAPI can't deliver the webhook.
The Solution: Use ngrok to create a public URL that tunnels to your local server.
-
Install ngrok:
# macOS brew install ngrok # Or download from https://ngrok.com/download
-
Create a free ngrok account at ngrok.com and get your authtoken
-
Configure ngrok:
ngrok config add-authtoken YOUR_AUTHTOKEN
-
Start your Next.js dev server:
npm run dev # Should run on port 3001 -
In a new terminal, start ngrok:
ngrok http 3001
-
Copy the forwarding URL (looks like
https://abc123.ngrok.io) -
Set up VAPI Dashboard:
- Go to VAPI Dashboard
- Click on your Organization name (top left, next to the VAPI logo)
- Select Settings from the dropdown
- Under Webhook URL, enter:
https://YOUR_NGROK_URL/api/webhook/vapi - Save changes
Note: The webhook is configured at the organization level, not per assistant. This means all calls from any assistant in your organization will send webhooks to this URL.
-
Test it:
- Make a call from your dashboard
- Check your terminal running the Next.js server - you should see
[VAPI Webhook]logs - The call data will now be saved to Supabase!
If ngrok feels cumbersome, you can deploy to Vercel and test there:
# Install Vercel CLI
npm i -g vercel
# Deploy
vercelThen set your production URL (e.g., https://your-app.vercel.app/api/webhook/vapi) in the VAPI Dashboard webhook settings.
genesis-genai/
├── frontend/ # Next.js app
│ ├── app/
│ │ ├── api/ # API routes (call, webhook, elders)
│ │ ├── lib/ # Supabase & VAPI helpers
│ │ ├── types/
│ │ └── page.tsx
│ ├── components/
│ │ ├── vapi-call-provider.tsx # VAPI Web SDK (in-browser calls)
│ │ ├── elders-list.tsx
│ │ ├── dashboard.tsx
│ │ └── registration-flow.tsx
│ └── .env.example
└── README.md
- Elders list — Loads elders from Supabase via
GET /api/elders; Start call uses the VAPI Web SDK (no phone number). - Dashboard — Single-elder view with Start call (same in-browser flow) and Back to list.
- Registration — "Add elder" flow; saves to Supabase via
POST /api/elders.
- Create an assistant in VAPI Dashboard with system prompt using variables like
{{elder_name}},{{elder_age}},{{biography}},{{medications}}. - For in-browser demo: add your public key and assistant ID to
NEXT_PUBLIC_VAPI_*in.env.local. - For phone calls: add a phone number in VAPI, set
VAPI_PHONE_NUMBER_ID, and callPOST /api/callwith{ elderId }; VAPI will call the elder's phone number.
To get the most out of Everly, configure your VAPI assistant with these settings:
System Prompt Template:
You are Everly, a warm and patient AI companion calling {{elder_name}}.
They are {{elder_age}} years old. Here's what you should know about them:
{{biography}}
Their hobbies include: {{hobbies}}
Family members: {{family_members}}
Medications to check on: {{medications}}
Personality notes: {{personality_notes}}
Be gentle, speak slowly, and ask about their day. Check if they've taken their
medications naturally in conversation. Encourage them to share a memory or story.
Always be respectful and warm.
Structured Output (for memory capture): Configure structured outputs in VAPI Dashboard to capture:
mood(string: happy, content, sad, lonely, anxious, tired, nostalgic)mood_notes(string: brief explanation)meds_taken(boolean)has_story(boolean: did they share a memory?)chapter_title(string: title of the story)chapter_content(string: the full story they shared)
- Check webhook URL is set in VAPI Dashboard
- Check ngrok is running and URL hasn't changed (ngrok free URLs change each session)
- Check server logs for
[VAPI Webhook]entries - Verify call is being registered - when you start a call, check if
POST /api/call/registeris called - Check Supabase - look at the
call_logstable to see if entries are being created/updated
- Check structured outputs are configured in VAPI Dashboard
- Check the assistant is actually having conversations (not just hanging up immediately)
- Look at the full payload in logs to see what's being sent
- Verify your Supabase keys have write permissions
Your friends can't access localhost:3001 on your computer. To share Everly with others, you need to deploy it to the internet.
-
Install Vercel CLI:
npm i -g vercel
-
Login to Vercel:
vercel login
-
Deploy from the frontend folder:
cd frontend vercel -
Follow the prompts:
- Set up and deploy? Yes
- Link to existing project? No (first time)
- What's your project name? everly (or any name)
-
Add environment variables in Vercel Dashboard:
- Go to vercel.com/dashboard
- Find your project → Settings → Environment Variables
- Add all variables from your
.env.local:NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEYSUPABASE_SERVICE_ROLE_KEYNEXT_PUBLIC_VAPI_PUBLIC_KEYNEXT_PUBLIC_VAPI_ASSISTANT_IDVAPI_API_KEYVAPI_PHONE_NUMBER_IDVAPI_ASSISTANT_ID
-
Redeploy:
vercel --prod
-
Update VAPI Webhook URL:
- In VAPI Dashboard → Organization Settings
- Change webhook URL to:
https://your-app.vercel.app/api/webhook/vapi
-
Share the URL! Your friends can now visit
https://your-app.vercel.app
-
Install Netlify CLI:
npm i -g netlify-cli
-
Deploy:
cd frontend netlify deploy --prod -
Add environment variables in Netlify Dashboard
"Build failed" errors:
- Make sure all environment variables are set in Vercel/Netlify dashboard
- Check that your Supabase tables are created
"Webhook not working" after deploy:
- Update the webhook URL in VAPI Dashboard to your production URL
- Don't use ngrok anymore - use your actual domain
Images not loading:
- Images from Unsplash should work automatically
- If using other image sources, add them to
next.config.mjsin theimages.remotePatternsarray
"Everly helps families care for aging loved ones through AI phone conversations. Caregivers set up a profile with medications, routines, and life stories. Our AI calls the elder at scheduled times — reminding about medications, providing companionship, and capturing memories. After each call, caregivers get a summary: mood, medication adherence, and any concerns. Over time we build a living memory archive. We're not just reducing loneliness; we're preserving a person before time erases the details."
Add any hackathon awards or recognition here
MIT.