Marlowe
Your AI scam detective — a real-time coaching hotline that listens to your live phone call and tells you when something smells wrong.
Built for the Security Track at Tufts University 2026 JumboHack.
The Problem
AI-enabled scams are accelerating already massive fraud:
- The FBI’s IC3 reported 39,416 extortion victims with ~$54.3M in losses in 2022 (FBI IC3 Annual Report).
- 14,190 government-impersonation scam victims with $394M+ in losses in 2023 (FBI warning).
- Older adults are disproportionately harmed.
Scammers manufacture urgency, fear, and isolation to keep people from pausing to think.
The Solution
We built Marlowe, a live scam detective that works during the call itself, helping users pause before they send money, share credentials, or comply with threats.
Live iPhone call transcription
We orchestrate a Twilio-powered “silent monitor” call that bridges into the user’s active conversation. Twilio<Transcription>streams both sides of the call (track="both_tracks") as partial + final transcript events via webhooks.Near-real-time coaching pipeline
Each transcript chunk hits our webhook, is persisted to Supabase, and runs through a dual-layer analysis engine:- Heuristic scoring fires instantly using pattern-matched risk signals (gift cards, wire transfers, urgency language, credential harvesting, etc.)
- LLM analysis (Groq) runs on a rate-limit-aware schedule with exponential backoff, advice diffing, and score dampening to avoid whiplash
Live push to the client
Supabase Realtime streams transcript chunks, coaching updates, and risk scores to the UI as the call happens — no polling.Self-healing call loop
TwiML uses a<Pause>+<Redirect>loop to keep the transcription session alive indefinitely, re-upping every ~60 seconds without dropping the call.
Advice Stabilization Engine
Real-time risk scoring is useless if it jitters every second. Marlowe includes a score stabilization layer to keep the signal steady while still reacting fast to genuine threats:
- Confidence-weighted dampening: low-confidence updates move less (e.g., ±6), high-confidence updates can move more (e.g., ±11).
- Band-crossing acceleration: if evidence crosses a boundary (low→medium, medium→high), step limits temporarily increase so the UI reflects the transition quickly.
- Asymmetric movement: upward score changes can move faster than downward ones (safer to warn early than retract too fast).
- Dead-zone filtering: tiny deltas (≤3) are suppressed to prevent cosmetic flicker.
- Action queue continuity: “what to do now” maintains a deduplicated rolling history so users keep context even when advice updates.
Production-Grade Completeness
- End-to-end integration testing: a full mock flow provisions a tenant, saves a number, simulates Twilio webhook events, waits for risk ≥ 40, verifies call-ended propagation, and asserts the full loop (including valid Twilio HMAC-SHA1 signatures).
- Twilio webhook signature validation: HMAC-SHA1 verification with URL candidate generation for proxy/forwarding edge cases + constant-time comparison.
- Rate limiting & cooldowns: IP-based rate limits on call initiation + setup, plus per-tenant cooldowns to prevent abuse.
- LLM rate-limit resilience: exponential backoff on 429s, automatic fallback to heuristics during cooldown, configurable RPM-derived intervals.
- Row Level Security: Supabase RLS with explicit policies; server-side writes via service-role client.
- Input validation: E.164 normalization, slug validation, XML escaping in TwiML, Zod schemas for LLM output parsing.
- Database migrations: versioned SQL scripts for schema + Realtime publication + demo seeding.
- Linting: ESLint across the codebase.
Tech Stack
- Framework: Next.js 16 (App Router), React 19, TypeScript
- UI: Tailwind CSS v4, Radix UI, shadcn-style components
- Voice/Calling: Twilio Telephony Service and Deepgram Nova-3 (outbound calls + transcription webhooks)
- Coaching Engine: local heuristics + Groq Chat Completions
- Realtime Data: Supabase Postgres + Supabase Realtime +
@supabase/ssr - Deployment: Vercel + Vercel Analytics
Team
- Clark Ohlenbusch — Team Lead / Lead Developer: Twilio orchestration, transcription pipeline, realtime coaching engine
- Michael Marrero — Product Development / Engineer: deepfake simulation pipeline, positioning + adoption planning
- Julie Hohenberg — Data Science & Research: scam test cases, voice-validation inputs, user/market research
Getting Started
Prerequisites
- Node.js 20+
pnpm- A Supabase project
- A Twilio number with voice enabled
Install and run
pnpm install
pnpm dev
Open http://localhost:3000 (the app redirects / to /start).
Database setup
Run SQL migrations in your Supabase/Postgres database (in order):
psql "$POSTGRES_URL_NON_POOLING" -f scripts/001_create_tenants.sql
psql "$POSTGRES_URL_NON_POOLING" -f scripts/003_live_call_tables.sql
psql "$POSTGRES_URL_NON_POOLING" -f scripts/004_enable_realtime_live_tables.sql
Optional demo seed:
psql "$POSTGRES_URL_NON_POOLING" -f scripts/002_seed_demo_tenant.sql
Environment Variables
Create .env.local:
Required:
NEXT_PUBLIC_SUPABASE_URL=...
NEXT_PUBLIC_SUPABASE_ANON_KEY=...
SUPABASE_SERVICE_ROLE_KEY=...
TWILIO_ACCOUNT_SID=...
TWILIO_AUTH_TOKEN=...
TWILIO_PHONE_NUMBER=...
Optional:
GROQ_API_KEY=...
GROQ_MODEL=meta-llama/llama-4-scout-17b-16e-instruct
GROQ_RPM_LIMIT=30
GROQ_MIN_INTERVAL_MS=2800
TWILIO_WEBHOOK_SKIP_SIGNATURE_VALIDATION=1
PUBLIC_BASE_URL=https://your-domain.com
TENANT_ADMIN_OVERRIDE_TOKEN=...
BASE_URL=http://127.0.0.1:3000
Notes:
GROQ_API_KEYis optional. Without it, the app uses local heuristic advice only.- Keep Twilio signature validation enabled in production (
TWILIO_WEBHOOK_SKIP_SIGNATURE_VALIDATIONunset or0). - If
PUBLIC_BASE_URL/APP_BASE_URL/NEXT_PUBLIC_APP_URLare unset, webhook URLs fall back to forwarded host headers.
Testing
pnpm lint # ESLint
pnpm test:mock # End-to-end mock call/transcript sanity flow
pnpm test:mock expects the app running locally and exercises /start, /api/tenant/phone, /api/twilio/webhook, and /api/call/live.
Deployment
Configured for Vercel. Import the repo into Vercel, set the environment variables above, run the SQL migrations in Supabase, and verify Twilio can reach your deployed /api/twilio/webhook endpoint.
Reflection
Our main challenge was designing something people could realistically use during a high-stress scam call, so we focused on a simple, fast user flow. We also attended Lucas Maley’s PM workshop, which helped us think more clearly about product design and feature prioritization.
License
This project was created as a hackathon prototype and is provided for demonstration purposes only.
No license is granted at this time. You may not use, copy, modify, or distribute this code without permission from the authors. A production license may be added in the future.
Built With
- deepgram
- elevenlabs
- groq
- next.js
- radix
- react
- supabase
- tailwindcss
- twilio
- typescript
- vercel
Log in or sign up for Devpost to join the conversation.