You're building a voice-note feature in a SaaS product. Reps need to record 30-second field notes that automatically extract deal data (budget, timeline, decision-maker). You have three horses in the race: AssemblyAI, Deepgram, and Whisper (local). AssemblyAI wins on price per hour, polling simplicity, and AI extraction hooks. We use it in Velocity X.
Why AssemblyAI for Production
AssemblyAI costs $0.37 per hour of audio processed. Deepgram costs $0.59 per hour. For a 30-second clip, that's $0.0052 vs $0.0049 — negligible. But Deepgram's real pricing lives in the fine print: they charge per *streaming second*, not transcribed hour. Record 10 reps each sending 3 clips per day: you're pushing 2,880 streaming seconds per month. Deepgram's "cheaper" tier suddenly looks like $47 vs AssemblyAI's $0.60 for the same workload.
Deepgram is brilliant if you need sub-100ms latency (live transcription during a call). AssemblyAI's async API is brilliant if you need "fire and forget" — which is the case for voice notes. Upload → webhook callback → structured JSON. No polling loops, no connection babysitting. And AssemblyAI's LeMUR AI module lets you extract deal fields without a separate Claude call, though we chain it to Claude anyway for tighter control.
Whisper (OpenAI, $0.02 per minute if self-hosted, free if local) is faster for short clips (5–10 second latency). But running it on-premises costs GPU rental or your own hardware. For most SaaS shops, the simplicity of a third-party API beats the savings.
The Architecture
Client → Server: Rep records audio (Web Audio API). On stop, they get a preview. Tap send. Browser uploads the blob to AssemblyAI's endpoint (using a session token for auth). AssemblyAI queues the job and returns a transcript_id.
Server-side polling: A Netlify Function (or your server) polls the transcript endpoint every 5 seconds:
{`const response = await fetch(
\`https://api.assemblyai.com/v2/transcript/\${transcriptId}\`,
{ headers: { Authorization: ASSEMBLYAI_KEY } }
);
const { status, text } = await response.json();
if (status === 'completed') {
// Pass transcript to Claude for extraction
const extraction = await claudeExtract(text, dealContext);
await supabase
.from('deal_voice_notes')
.insert({ deal_id, transcript_text: text, extracted_fields: extraction });
}`}
For 30-second clips, this hits "completed" within 30–60 seconds. For longer recordings or heavy batch loads, AssemblyAI queues them and returns results in order. The callback webhook model is also available — if you want zero polling, set a webhook URL and AssemblyAI POSTs you the finished transcript.
Cost Math
Assume 50 reps, 5 voice notes per day, 45 seconds average per note (since they ramble). That's 50 × 5 × 0.75 min/day = 187.5 minutes per day = 5,625 minutes per month = $104.50 on AssemblyAI at $0.37/hour. Deepgram at streaming rate hits $150+. Google Speech-to-Text is $1.44 per 15-minute increments, so $432/month for the same workload. Scale to 200 reps and AssemblyAI stays sub-$500/month. Whisper local scales to $0 if you amortise GPU over other workloads, but you're now ops-responsible for uptime and model updates.
Extraction — AI on Top of Transcription
We chain AssemblyAI transcription + Claude extraction because Claude's structured output (JSON schema validation) is bulletproof. Once the transcript lands, we send it to Claude with the deal context:
{`System: "Extract deal updates from this sales voice note. Return valid JSON with keys: summary (string), budget (string?), timeline (string?), champion_name (string?), next_action (string?), confidence (0.0–1.0)."
User: "Transcript: ${transcript}\\n\\nDeal context: Company=Acme, Current_Budget=50k, Stage=Negotiation..."`}
Claude returns clean, schema-validated JSON. Confidence < 0.7? Flag for manual review. Confidence > 0.9? Auto-update the deal record. That's the extraction loop Velocity X uses.
Comparison to Whisper & Deepgram
Whisper (local): 5–10 second latency, zero cost per call (pay once for compute). Offline-capable. No API key exposure. Trade-off: you run it. Updates come quarterly. GPU exhaustion if you have spiky load.
Deepgram: Sub-100ms latency for streaming. Real-time transcription during a live call. Pricing transparency on paper, complexity in practice. Better speaker diarization (multi-speaker detection) than AssemblyAI on some accents.
AssemblyAI: 30–60 second latency, fine for async (voice notes). Simpler pricing model (per transcribed hour). Webhook + polling both available. LeMUR extraction hooks (though Claude is a better bet). Battery on large batches.
Google Speech-to-Text: Strongest model accuracy, especially for accented English. Most expensive. Best for mission-critical transcript accuracy where cost is secondary.
Frequently Asked Questions
How long does transcription actually take?
AssemblyAI returns "completed" status in 30–120 seconds depending on audio length and queue depth. A 30-second clip lands within 40 seconds. A 10-minute recording might take 90 seconds. This is slow enough that a 5-second polling interval is safe; no need to hammer the API.
What about accents and background noise?
AssemblyAI's model handles regional accents reasonably well (Australian, UK, Indian accents all work). Heavy background noise (car engine, wind, office chatter) degrades accuracy. Solution: apply Web Audio API BiquadFilterNode on the client before upload to reduce low-frequency rumble. Or filter server-side using FFmpeg if you're batch-processing old recordings.
Can you set minimum confidence thresholds?
AssemblyAI doesn't expose per-word confidence, only overall transcript confidence. If you need word-level confidence, Deepgram and Google Speech-to-Text expose it. For SaaS use (deal notes), overall transcript confidence > 0.8 is usually safe. Anything lower, flag for manual review.
Does it handle PII (personally identifiable info)?
AssemblyAI can redact PII using its redact_pii parameter. Enable it, and the API returns both the full transcript and a PII-redacted version. Salary, phone, home address, SSN — all masked. Paired with RLS (Postgres row-level security) on your notes table, you're compliant for most non-regulated industries. For HIPAA/finance, AssemblyAI has SOC2 and HIPAA add-ons.
What if you need real-time (live call transcription)?
AssemblyAI's async model is too slow. Use Deepgram or Google for streaming. Or run Whisper locally with WebRTC streaming from the browser. Velocity X doesn't do live call transcription, so AssemblyAI is perfect for us.
Can you export and re-process old voice notes?
Yes. If you migrate from another system (Otter.ai, Fireflies.io), export the audio files and queue them to AssemblyAI via a Netlify Function batch job. Supabase pg_cron or Inngest handles orchestration. Back-fill your notes table with transcripts and extracted fields. Takes a few hours depending on volume.
The Bottom Line
AssemblyAI is the Goldilocks transcription engine for SaaS voice-note features. Not too expensive (Deepgram), not too complex (Whisper local), not too slow (Deepgram streaming). Async polling is simple to implement. Webhook mode is even simpler if you don't mind a stateless architecture. Chain it to Claude for extraction and you're shipping a voice-powered deal capture system in a weekend. Velocity X uses it because it works, costs $100/month at scale, and requires zero babysitting. That's the win.