By Sagar Shankaran, Founder of CallSphere
Convex's reactive queries auto-push every transcript update to every subscribed client. Real working code for actions, mutations, and OpenAI Realtime streaming.
Key takeaways
TL;DR — Convex queries are reactive subscriptions by default. A voice transcript stored in Convex updates every connected client in <100ms — no Redis, no Channels, no extra glue.
A Next.js + Convex voice app where every assistant token is mutated into the messages table, and every browser using useQuery instantly re-renders. The OpenAI Realtime call lives in a Convex action that streams via HTTP and writes deltas via mutations.
npx create-next-app@latest + npx convex dev to bootstrap.OPENAI_API_KEY set: npx convex env set OPENAI_API_KEY ....npm i convex @convex-dev/auth openai.flowchart LR
B[Browser useQuery] -- subscribe --> C[Convex DB]
B -- httpAction --> A[voice-stream action]
A -- WebSocket --> O[OpenAI Realtime]
A -- mutation --> C
convex/schema.ts:
```typescript import { defineSchema, defineTable } from "convex/server"; import { v } from "convex/values";
export default defineSchema({ calls: defineTable({ userId: v.string(), startedAt: v.number(), }), messages: defineTable({ callId: v.id("calls"), role: v.union(v.literal("user"), v.literal("assistant")), text: v.string(), }).index("by_call", ["callId"]), }); ```
convex/messages.ts:
```typescript import { v } from "convex/values"; import { mutation, query } from "./_generated/server";
export const append = mutation({ args: { callId: v.id("calls"), role: v.string(), text: v.string() }, handler: async (ctx, args) => { return await ctx.db.insert("messages", args as any); }, });
Hear it before you finish reading
Talk to a live CallSphere AI voice agent in your browser — 60 seconds, no signup.
export const list = query({ args: { callId: v.id("calls") }, handler: async (ctx, { callId }) => await ctx.db.query("messages") .withIndex("by_call", q => q.eq("callId", callId)) .collect(), }); ```
Convex actions can call external APIs (mutations cannot). httpAction exposes a fetch endpoint at <deployment>.convex.site/voice:
```typescript import { httpAction } from "./_generated/server"; import { api } from "./_generated/api"; import OpenAI from "openai";
export const voice = httpAction(async (ctx, req) => { const { callId, audioB64 } = await req.json(); const oai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
// Streaming text completion (simplified; for realtime audio see step 5) const stream = await oai.chat.completions.create({ model: "gpt-4o-mini", stream: true, messages: [ { role: "system", content: "You are CallSphere on Convex. Be brief." }, { role: "user", content: "[transcribed]: " + audioB64 }, ], });
let buffer = ""; for await (const chunk of stream) { const t = chunk.choices[0]?.delta?.content ?? ""; buffer += t; if (t.endsWith(" ") || t.endsWith(".")) { await ctx.runMutation(api.messages.append, { callId, role: "assistant", text: buffer, }); buffer = ""; } } return new Response("ok"); }); ```
convex/http.ts:
```typescript import { httpRouter } from "convex/server"; import { voice } from "./voice";
const http = httpRouter(); http.route({ path: "/voice", method: "POST", handler: voice }); export default http; ```
```tsx "use client"; import { useQuery, useMutation } from "convex/react"; import { api } from "../convex/_generated/api";
Still reading? Stop comparing — try CallSphere live.
CallSphere ships complete AI voice agents per industry — 14 tools for healthcare, 10 agents for real estate, 4 specialists for salons. See how it actually handles a call before you book a demo.
export default function CallView({ callId }: { callId: string }) { const messages = useQuery(api.messages.list, { callId: callId as any }) ?? [];
return (
useQuery keeps an open subscription. New rows from the action appear without polling.
```typescript async function send(callId: string, blob: Blob) { const audioB64 = btoa(String.fromCharCode(...new Uint8Array(await blob.arrayBuffer()))); await fetch(`${process.env.NEXT_PUBLIC_CONVEX_HTTP}/voice`, { method: "POST", body: JSON.stringify({ callId, audioB64 }), }); } ```
action/httpAction may.useQuery(list) over a 100k-row table without .withIndex will time out.CallSphere is on Postgres (115+ tables, 6 verticals) but we recommend Convex for solo founders building voice apps fast — the affiliate program at /affiliate tracks 22% commissions in real time using a similar reactive pattern. See /pricing for production-grade equivalents.
Is Convex SQL? No — document-style with strong typing and indexes. SQL adapter exists.
Realtime audio? This post uses HTTP streaming; for true Realtime audio, pair Convex with a Deno relay (see post #7).
Cost? Generous free tier; ~$25 covers 1M function calls.
Auth? Built-in @convex-dev/auth with Google/GitHub/email.
Self-host? OSS version available.
Written by
Sagar Shankaran· Founder, CallSphere
Sagar Shankaran is the founder of CallSphere, where he builds production AI voice and chat agents deployed across healthcare, hospitality, real estate, and home services. He writes about agentic AI, LLM engineering, and shipping voice agents that handle real calls in production.
See how AI voice agents work for your industry. Live demo available -- no signup required.
Haystack 2.7's Agent component plus an Ollama-served Llama 3.2 gives you tool-calling RAG with citations. Here's a complete pipeline against your own document store.
Run STT, LLM, and TTS entirely on Cloudflare's edge — no OpenAI, no ElevenLabs. Real working code with Whisper, Llama 3.3 70B, and Deepgram Aura.
Version your prompts in git, run a 50-case eval suite on every PR, block merges below threshold, and ship a new agent prompt with confidence — full GitHub Actions tutorial.
AI SDK 5 ships fully typed chat for React, Svelte, Vue, and Angular plus first-class agent loop primitives. Here are the patterns that matter for shipping in 2026.
Replace expensive outbound SDR tooling with a self-hosted dialer that runs OpenAI Realtime agents at 100 concurrent calls. Full architecture and code.
Mastra.ai is becoming the go-to TypeScript agent framework in 2026. Workflows, RAG, evals, and an honest comparison with Vercel AI SDK 5 for serious teams.
© 2026 CallSphere LLC. All rights reserved.
Watch how CallSphere handles real customer calls, schedules appointments, and processes payments — live.
Try Live DemoBook a DemoCalculate Your ROI