AI-powered interview intelligence platform for hiring teams that want faster, fairer, and more evidence-backed decisions.
TruthHire runs a coordinated multi-agent pipeline over interview data to detect bluff patterns, surface resume contradictions, score job-fit, and generate actionable post-interview reports.
- Overview
- Core Capabilities
- Architecture
- Agent Pipeline
- Tech Stack
- Repository Structure
- Quick Start
- Environment Variables
- Database Setup and Migration
- Running the System
- API Reference
- Real-Time and Audio Flow
- Security and Privacy
- Deployment Guide
- Troubleshooting
- Development Workflow
- Roadmap
- License
TruthHire is built for HR teams and interview panels that need structured signal, not guesswork.
What the platform does:
- Parses and normalizes candidate resume claims
- Matches resume strength versus job description requirements
- Processes interview answers through specialized AI evaluators
- Flags likely bluffing and claim contradictions
- Scores communication confidence indicators
- Produces candidate-facing and HR-facing report outputs
What it does not do:
- It does not replace human decision-making
- It does not use demographic attributes for scoring
- It does not persist raw audio streams as stored interview artifacts
- Multi-agent interview analysis pipeline
- Resume-to-answer contradiction detection
- Bluff probability scoring with follow-up trap suggestions
- Voice and linguistic confidence analysis
- Dynamic interview continuation questions
- Team analytics endpoint for hiring trend visibility
- Tiered plan enforcement and webhook-driven billing state updates
TruthHire uses a split architecture:
- Frontend: Next.js 14 (App Router) for dashboard, interview setup, live flow, and reports
- Backend: Express + Socket.IO for API, orchestration, webhooks, and cron jobs
- Data: Supabase Postgres (plus Supabase Auth)
- Cache and rate limiting: Upstash Redis
- AI: Mistral models via centralized agent calling service
High-level runtime flow:
- HR creates an interview
- Resume is uploaded and parsed
- JD is uploaded and matched
- Interview starts
- Each candidate answer is processed by agent orchestration
- Finalize endpoint generates and stores reports
- Optional notifications are sent through Brevo
TruthHire includes seven specialized agents:
- ResumeParser: Extracts structured claims from resume text
- JDMatcher: Computes fit and interview focus areas versus JD
- InterviewerAgent: Produces contextual follow-up questions
- BluffDetector: Estimates bluff probability and bluff type
- ContradictionEngine: Finds inconsistencies versus resume claims
- VoiceAnalyzer: Scores linguistic and audio confidence indicators
- ReportGenerator: Builds final HR and candidate report content
Pipeline sequencing:
- Setup phase: ResumeParser -> JDMatcher
- Per-answer phase:
- Parallel: BluffDetector + ContradictionEngine + VoiceAnalyzer
- Then: InterviewerAgent
- Finalization phase: Contradiction full-pass -> ReportGenerator -> status/report persistence
- Next.js 14
- React 18
- Supabase JS client
- Node.js + Express
- Socket.IO
- Supabase JS client
- Mistral SDK
- Upstash Redis + rate limiter
- node-cron
- multer + pdf/doc parser utilities
- Brevo transactional email SDK
- Supabase (Auth + Postgres + optional storage)
- Upstash Redis
- Mistral API
- Lemon Squeezy and Razorpay webhooks
interview/
backend/
agents/
cron/
db/
middleware/
orchestrator/
routes/
services/
server.js
frontend/
app/
components/
lib/
.env.example
README.md
SETUP.md
package.json
- Node.js 18+
- npm 9+
- Supabase project
- Mistral API key
npm install
npm run install:allcp .env.example .envPopulate required keys in .env. Full variable reference is in the Environment Variables section below.
In Supabase SQL Editor:
- Run backend/db/schema.sql
- If you are upgrading an existing project, run backend/db/migration_fix_columns.sql
npm run devDefault local ports:
- Frontend: http://localhost:3000
- Backend: http://localhost:3001
Copy from .env.example and fill values. Do not commit real values.
- MISTRAL_API_KEY
- SUPABASE_URL
- SUPABASE_ANON_KEY
- SUPABASE_SERVICE_ROLE_KEY
- NEXT_PUBLIC_SUPABASE_URL
- NEXT_PUBLIC_SUPABASE_ANON_KEY
- NEXT_PUBLIC_APP_URL (for links in report emails, defaults should be explicit)
- UPSTASH_REDIS_REST_URL
- UPSTASH_REDIS_REST_TOKEN
- BREVO_API_KEY
- EMAIL_FROM
- EMAIL_FROM_NAME
- NEXT_PUBLIC_API_URL (frontend override, otherwise defaults to localhost backend)
- BACKEND_PORT (or PORT)
- LEMON_SQUEEZY_API_KEY
- LEMON_SQUEEZY_WEBHOOK_SECRET
- NEXT_PUBLIC_LEMON_SQUEEZY_STORE_ID
- RAZORPAY_KEY_ID
- RAZORPAY_KEY_SECRET
- RAZORPAY_WEBHOOK_SECRET
Use backend/db/schema.sql only.
Use backend/db/migration_fix_columns.sql after schema alignment to:
- Backfill/rename legacy columns
- Repair report and contradiction field naming
- Recreate increment_interviews_used function
- Repair auth signup profile trigger behavior
If signup failures occurred with "Database error creating new user", run the migration script to repair trigger/profile compatibility.
npm run dev# Terminal 1
cd backend
npm run dev
# Terminal 2
cd frontend
npm run devcd frontend
npm run buildBase URL (local):
- Backend API: http://localhost:3001
Authentication:
- All protected endpoints require Authorization: Bearer <supabase_access_token>
- Public endpoints:
- GET /api/health
- POST /api/webhook/*
- GET /api/health
- GET /api/auth/profile
- PUT /api/auth/profile
- POST /api/interviews
- GET /api/interviews
- GET /api/interviews/:id
- POST /api/interviews/:id/resume
- POST /api/interviews/:id/jd
- POST /api/interviews/:id/start
- POST /api/interviews/:id/answer
- POST /api/interviews/:id/complete
- GET /api/interviews/:id/turns
- DELETE /api/interviews/:id
- GET /api/reports/:interviewId
- GET /api/reports/analytics/team
- POST /api/webhook/lemon-squeezy
- POST /api/webhook/stripe (deprecated response)
- POST /api/webhook/razorpay
Backend Socket.IO handlers support:
- join_interview
- leave_interview
- audio_chunk
The backend processes finalized candidate utterances through the orchestrator and emits structured analysis events.
Current frontend flow is API-first and can be extended to consume more live socket events as needed.
- Row-level ownership checks enforced at route level with Supabase identity
- Rate limiting middleware with graceful fallback if Redis is unavailable
- Webhook signature verification for Lemon Squeezy and Razorpay
- .env files are ignored via .gitignore patterns
- No hardcoded credentials should exist in code or docs
- Audio streams are processed in-session and not persisted as raw streams
Deploy frontend Next.js app to Vercel or equivalent.
Deploy Express backend to Render, Railway, VPS, or container platform.
Production checklist:
- Set backend CORS origins to your frontend domain
- Set NEXT_PUBLIC_APP_URL to deployed frontend URL
- Configure webhook URLs to deployed backend
- Ensure Supabase keys and Mistral key are present in backend environment
- Confirm Redis credentials for rate limiting and cache
- Confirm frontend uses correct NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY
- Confirm bearer token is attached to API calls
- Confirm backend can validate token against same Supabase project
- Run backend/db/migration_fix_columns.sql in Supabase
- Ensure profiles table includes fields expected by trigger
- Verify MISTRAL_API_KEY is set in backend environment
- Check backend logs for agent-call validation errors
- Verify Upstash credentials
- If Redis unavailable, middleware falls back to permissive mode by design
- Set BREVO_API_KEY
- Without key, service degrades to console-only mode
- Create interview from dashboard
- Upload/paste resume
- Upload/paste JD
- Start interview
- Submit manual or captured answers
- Complete interview and inspect report endpoint
Root:
- npm run dev
- npm run install:all
Backend:
- npm run dev
- npm start
Frontend:
- npm run dev
- npm run build
- npm run start
- Rich real-time event visualizations in live interview UI
- Expanded analytics and cohort benchmarking
- Team workspaces and multi-role access controls
- Deeper observability and audit logging
- Additional language and domain-specific interview packs
MIT
PRs are welcome.
Recommended process:
- Fork and create a feature branch
- Keep changes scoped and tested
- Update docs for behavior/API changes
- Open a pull request with context and validation notes
If you are setting this up for the first time, start with SETUP.md and then return here for advanced architecture, API, and deployment details.