Base Path: /interview/v2/
New Features:
- ✅ MongoDB caching for faster responses
- ✅ Streaming support via Server-Sent Events
- ✅ Performance metrics and monitoring
- ✅ Async/concurrent operations
- ✅ 60-70% faster response times
Authentication: None (add as needed)
Content-Type:
application/jsonfor JSON endpointsmultipart/form-datafor file uploadstext/event-streamfor streaming endpoints
| Endpoint | Method | Purpose | Streaming |
|---|---|---|---|
/interview/v2/start |
POST | Start session (direct text) | No |
/interview/v2/start-with-ids |
POST | Start session (MongoDB IDs) | No |
/interview/v2/answer |
POST | Submit answer with audio/video | No |
/interview/v2/stream/{session_id} |
GET | Stream question generation | Yes (SSE) |
/interview/v2/state/{session_id} |
GET | Get session state | No |
/interview/v2/performance/{session_id} |
GET | Get session metrics | No |
/interview/v2/complete/{session_id} |
POST | Complete & evaluate | No |
/interview/v2/metrics/global |
GET | Global performance metrics | No |
/interview/v2/metrics/reset |
POST | Reset metrics (admin) | No |
Purpose: Start a new interview session with direct CV/JD text
Headers Required:
Content-Type: application/json
Request Body (JSON):
{
"user_id": "user_123",
"session_id": "sess_abc",
"role": "Senior Software Engineer",
"company": "TechCorp",
"cv_text": "John Doe\n5 years of experience in Python development...",
"jd_text": "We are seeking a Senior Software Engineer with expertise in Python..."
}All fields are required (string type):
user_id: Unique user identifiersession_id: Unique session identifierrole: Job role/position titlecompany: Company namecv_text: Complete CV/resume content as textjd_text: Complete job description as text
Response (200 OK - New Session):
{
"session_id": "sess_123",
"status": "active",
"question": "Hello! I'm excited to speak with you about the Senior Software Engineer role. To start, could you walk me through your experience with Python and FastAPI?",
"question_number": 1
}Response Fields:
session_id(string): Unique identifier for this interview sessionstatus(string): Session status - "active", "completed", or "restored"question(string): The first interview question generated based on CV/JD analysisquestion_number(integer): Current question number (starts at 1)
Response (200 OK - Cached/Restored Session):
{
"session_id": "sess_123",
"status": "restored",
"question": "Tell me about your experience with microservices architecture."
}Note: When a session is restored from cache, it returns the last question that was asked.
Error Response (500 - Server Error):
{
"detail": "Failed to analyze CV: Invalid text format"
}Error Response (400 - Bad Request - Missing Fields):
{
"detail": "Missing required field: cv_text"
}Error Response (400 - Validation Error):
{
"detail": [
{
"loc": ["body", "user_id"],
"msg": "field required",
"type": "value_error.missing"
},
{
"loc": ["body", "cv_text"],
"msg": "str type expected",
"type": "type_error.str"
}
]
}Common Error: "user_id must be a string, session_id must be a string..."
- Cause: Missing
Content-Type: application/jsonheader or sending form-data instead of JSON - Fix: Ensure you're sending JSON with proper header (see cURL example below)
Performance:
- First time (uncached): ~4-6 seconds
- With cached CV: ~2-3 seconds
- Restored session: ~0.5-1 second
Purpose: Start session using CV/JD MongoDB IDs, files, or direct text
Request (Form Data):
user_id: string (required)
session_id: string (required)
role: string (required)
company: string (required)
cv_id: string (optional)
jd_id: string (optional)
cv_file: file (optional, .pdf/.docx/.txt)
jd_file: file (optional, .pdf/.docx/.txt)
cv_text: string (optional)
jd_text: string (optional)
Note: Provide CV/JD in one of these ways (priority order):
- Files (
cv_file,jd_file) - Recommended, automatic text extraction - MongoDB IDs (
cv_id,jd_id) - Good for caching - Direct text (
cv_text,jd_text) - Fallback option
Response (200 OK - New Session):
{
"session_id": "sess_456",
"status": "active",
"question": "Thanks for joining us today. I'd like to start by understanding your background. Can you tell me about your experience with the technologies mentioned in the job description?",
"question_number": 1
}Response Fields:
session_id(string): Unique session identifier (echoes your request)status(string): "active" for new sessions, "restored" for cached sessionsquestion(string): Context-aware first question based on CV and JD analysisquestion_number(integer): Always 1 for new sessions
Response (200 OK - From File Upload):
{
"session_id": "sess_789",
"status": "active",
"question": "Hi there! I see you have extensive experience with microservices. Let's start by discussing your background - can you walk me through your most recent project involving distributed systems?",
"question_number": 1
}Note: File uploads are automatically processed:
- PDF: Text extracted using pypdf
- DOCX: Text extracted using python-docx
- TXT: Direct UTF-8 decoding
Error Response (404 - CV/JD Not Found):
{
"detail": "Resume 60d5ec49f1b2c8b1f8c4e5a1 not found"
}Error Response (400 - Missing Data):
{
"detail": "Both CV and JD content required"
}Error Response (400 - File Format Error):
{
"detail": "Unsupported CV file format: .exe"
}Error Response (400 - File Extraction Failed):
{
"detail": "Failed to extract text from PDF: Encrypted file"
}Performance:
- With file upload: ~3-5 seconds (includes text extraction)
- With cached CV (by ID): ~2-3 seconds
- Without cache: ~4-6 seconds
- Restored session: ~0.5-1 second
Purpose: Submit candidate answer with optional audio/video files
Request (Form Data):
session_id: string (required)
audio_file: file (optional, .wav/.mp3)
video_file: file (optional, .mp4/.webm)
Note: At least one file (audio or video) is required. If video is provided without audio, audio will be extracted from video.
Response (200 OK - Active Interview):
{
"session_id": "sess_456",
"status": "active",
"question": "That's impressive experience. Can you describe a challenging technical problem you solved recently?",
"question_number": 2,
"evaluation": {
"clarity": 8,
"relevance": 9,
"depth": 7,
"feedback": "Clear and relevant answer with good technical details"
}
}Response Fields:
session_id(string): Session identifierstatus(string): "active" if interview continues, "completed" if finishedquestion(string): Next interview question (only if status is "active")question_number(integer): Current question countevaluation(object): Evaluation of the previous answerclarity(integer, 1-10): How clearly the candidate expressed their answerrelevance(integer, 1-10): How relevant the answer was to the questiondepth(integer, 1-10): Technical or behavioral depth of the answerfeedback(string): Brief qualitative feedback on the answer
Response (200 OK - With Voice Metrics):
{
"session_id": "sess_456",
"status": "active",
"question": "Great insights! Now, could you explain how you would approach building a rate limiting system?",
"question_number": 3,
"evaluation": {
"clarity": 9,
"relevance": 8,
"depth": 8,
"feedback": "Excellent explanation with specific examples and metrics"
},
"voice_analysis": {
"fluency_score": 8.5,
"clarity_score": 9.0,
"confidence_score": 7.8,
"pace_score": 8.2,
"rate_wpm": 145,
"total_score": 8.4
}
}Note: Voice analysis is included when audio is successfully processed.
Response (200 OK - Interview Complete):
{
"session_id": "sess_456",
"status": "completed",
"message": "Interview completed",
"total_questions": 5
}Response Fields (Completed):
session_id(string): Session identifierstatus(string): "completed"message(string): Completion messagetotal_questions(integer): Total number of questions asked in the interview
Note: When interview is completed, call /interview/v2/complete/{session_id} to get full evaluation.
Error Response (404 - Session Not Found):
{
"detail": "Session not found"
}Error Response (400 - No Files):
{
"detail": {
"error": "Either audio or video file is required"
}
}Performance:
- Answer processing: ~2-4 seconds
- Includes transcription + evaluation + next question
Features:
- Automatic audio transcription (Gemini)
- Voice analysis (if available)
- Video analysis (if provided)
- Concurrent processing
Purpose: Stream next question generation in real-time (Server-Sent Events)
Parameters:
session_id(path): Session identifier
Response (200 OK - Event Stream):
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
data: {"chunk": "Tell me about"}
data: {"chunk": " your experience"}
data: {"chunk": " with Python..."}
data: {"done": true}
Error Response (Event Stream):
data: {"error": "Session not found"}
Client Example (JavaScript):
const eventSource = new EventSource('/interview/v2/stream/sess_456');
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.chunk) {
// Display chunk in real-time
document.getElementById('question').innerText += data.chunk;
}
if (data.done) {
eventSource.close();
}
if (data.error) {
console.error(data.error);
eventSource.close();
}
};Performance:
- First chunk: ~0.5-1 second
- Complete question: ~2-3 seconds
- Progressive display for better UX
Purpose: Get current session state and conversation history
Parameters:
session_id(path): Session identifier
Response (200 OK - Complete Session State):
{
"session_id": "sess_456",
"user_id": "user_123",
"role": "Senior Software Engineer",
"company": "TechCorp",
"question_count": 3,
"stage": "technical",
"completed": false,
"messages": [
{
"role": "interviewer",
"content": "Tell me about your experience with Python and backend development.",
"timestamp": 1706745600.123,
"metadata": {
"stage": "intro"
}
},
{
"role": "candidate",
"content": "I have 5 years of experience working with Python, primarily in backend development using FastAPI and Django. I've built several microservices that handle millions of requests daily.",
"timestamp": 1706745620.456,
"metadata": {
"evaluation": {
"clarity": 8,
"relevance": 9,
"depth": 7,
"feedback": "Good answer with specific technologies and scale mentioned"
},
"voice_metrics": {
"fluency_score": 8.5,
"clarity_score": 8.0,
"confidence_score": 7.5
}
}
},
{
"role": "interviewer",
"content": "That's impressive. Can you describe your experience with microservices architecture?",
"timestamp": 1706745640.789,
"metadata": {
"stage": "technical"
}
},
{
"role": "candidate",
"content": "I've designed and implemented a microservices architecture using Docker and Kubernetes. We split our monolith into 12 services, each with its own database...",
"timestamp": 1706745670.234,
"metadata": {
"evaluation": {
"clarity": 9,
"relevance": 9,
"depth": 8,
"feedback": "Excellent technical depth with concrete implementation details"
}
}
},
{
"role": "interviewer",
"content": "Excellent. Now, could you walk me through a challenging technical problem you recently solved?",
"timestamp": 1706745690.567,
"metadata": {
"stage": "technical"
}
}
],
"avg_response_time": 2.34
}Response Fields:
session_id(string): Unique session identifieruser_id(string): User identifierrole(string): Job role being interviewed forcompany(string): Company namequestion_count(integer): Total questions asked so farstage(string): Current interview stage ("intro", "technical", "behavioral", "closing")completed(boolean): Whether interview is finishedmessages(array): Complete conversation history- Each message contains:
role: "interviewer" or "candidate"content: Message texttimestamp: Unix timestampmetadata: Additional data (stage, evaluation, voice metrics)
- Each message contains:
avg_response_time(float): Average time to generate questions (seconds)
Error Response (404 - Not Found):
{
"detail": "Session not found"
}Error Response (500 - Server Error):
{
"detail": "Failed to retrieve session state: Database connection error"
}Use Cases:
- Resume interrupted session
- Review conversation history
- Check session progress
- Debug issues
Purpose: Get performance metrics for a specific session
Parameters:
session_id(path): Session identifier
Response (200 OK - Detailed Performance Metrics):
{
"session_id": "sess_456",
"total_questions": 5,
"response_times": {
"min": 1.23,
"max": 4.56,
"avg": 2.45,
"all": [4.56, 2.12, 2.34, 1.98, 1.23]
},
"cache_status": "active"
}Response Fields:
session_id(string): Session identifiertotal_questions(integer): Total questions generated in this sessionresponse_times(object): Performance timing datamin(float): Fastest question generation time (seconds)max(float): Slowest question generation time (seconds)avg(float): Average generation time (seconds)all(array): All response times in chronological order
cache_status(string): "active" if CV/JD are cached, "not_cached" otherwise
Performance Interpretation:
- min < 2s: Excellent performance, likely using cached context
- avg < 3s: Good performance, meeting target SLAs
- max > 5s: Some slow operations, check logs for bottlenecks
- cache_status = "active": CV analysis is cached, subsequent sessions will be faster
Error Response (404 - Not Found):
{
"detail": "Session not found"
}Error Response (500 - Server Error):
{
"detail": "Failed to retrieve performance metrics: Internal error"
}Metrics Explained:
min: Fastest question generation timemax: Slowest question generation timeavg: Average response timeall: All response times in ordercache_status: Whether CV/JD are cached
Use Cases:
- Monitor session performance
- Identify slow operations
- Validate caching effectiveness
- Performance debugging
Purpose: Complete interview and generate comprehensive evaluation
Parameters:
session_id(path): Session identifier
Response (200 OK - Complete Interview Evaluation):
{
"session_id": "sess_456",
"status": "completed",
"total_questions": 5,
"evaluation": {
"overall_score": 7.83,
"recommendation": "hire",
"clarity": 8.2,
"relevance": 8.4,
"depth": 6.9
},
"conversation": [
{
"question": "Tell me about your experience with Python and backend development.",
"answer": "I have 5 years of experience working with Python, primarily in backend development using FastAPI and Django. I've built several microservices that handle millions of requests daily.",
"evaluation": {
"clarity": 8,
"relevance": 9,
"depth": 7,
"feedback": "Good answer with specific technologies and scale mentioned"
}
},
{
"question": "Can you describe your experience with microservices architecture?",
"answer": "I've designed and implemented a microservices architecture using Docker and Kubernetes. We split our monolith into 12 services, each with its own database. We used RabbitMQ for async communication and implemented circuit breakers for resilience.",
"evaluation": {
"clarity": 9,
"relevance": 9,
"depth": 8,
"feedback": "Excellent technical depth with concrete implementation details"
}
},
{
"question": "Describe a challenging technical problem you recently solved.",
"answer": "I once optimized our database queries which were causing timeouts. I implemented query caching, added proper indexes, and restructured some N+1 queries. This reduced average response time from 3 seconds to 200ms.",
"evaluation": {
"clarity": 9,
"relevance": 8,
"depth": 8,
"feedback": "Excellent technical depth with measurable results"
}
},
{
"question": "Tell me about a time when you had to work with a difficult team member.",
"answer": "I worked with a senior engineer who was resistant to code reviews. I scheduled a one-on-one to understand their perspective, and we agreed on a lighter review process focusing on critical issues.",
"evaluation": {
"clarity": 8,
"relevance": 8,
"depth": 6,
"feedback": "Good behavioral answer showing conflict resolution"
}
},
{
"question": "Do you have any questions for me about the role or company?",
"answer": "Yes, I'm curious about the team structure and what technologies you're using for your microservices deployment.",
"evaluation": {
"clarity": 7,
"relevance": 8,
"depth": 6,
"feedback": "Relevant questions showing interest in technical details"
}
}
],
"performance_metrics": {
"avg_response_time": 2.45,
"total_response_times": [4.56, 2.12, 2.34, 1.98, 1.23]
}
}Response Fields:
session_id(string): Session identifierstatus(string): "completed"total_questions(integer): Total questions askedevaluation(object): Overall evaluation metricsoverall_score(float): Average of clarity, relevance, depth (1-10)recommendation(string): "hire", "maybe", or "no_hire"clarity(float): Average clarity score across all answersrelevance(float): Average relevance scoredepth(float): Average depth score
conversation(array): Complete Q&A history with evaluations- Each entry contains:
question(string): The question askedanswer(string): Candidate's responseevaluation(object): Individual answer evaluation
- Each entry contains:
performance_metrics(object): System performance dataavg_response_time(float): Average question generation timetotal_response_times(array): All response times
Recommendation Criteria:
- hire: overall_score >= 8.0 (Strong candidate)
- maybe: overall_score >= 6.0 and < 8.0 (Moderate candidate)
- no_hire: overall_score < 6.0 (Weak candidate)
Error Response (404 - Not Found):
{
"detail": "Session not found"
}Error Response (400 - Bad Request):
{
"detail": "Session is not completed yet. Current status: active"
}Error Response (500 - Server Error):
{
"detail": "Failed to generate evaluation: LLM API error"
}Evaluation Criteria:
- overall_score: Average of clarity, relevance, depth (1-10)
- recommendation:
hire(score >= 8)maybe(score >= 6)no_hire(score < 6)
- clarity: How clear the answers were
- relevance: How relevant to the questions
- depth: Technical/behavioral depth
Purpose: Get global performance metrics across all sessions
Response (200 OK - Complete Global Metrics):
{
"status": "success",
"metrics": {
"llm_calls": {
"total": 127,
"avg_duration": 2.34,
"min_duration": 0.89,
"max_duration": 5.67
},
"api_requests": {
"total": 89,
"avg_duration": 3.12,
"min_duration": 1.23,
"max_duration": 8.45
},
"cache": {
"hits": 54,
"misses": 35,
"hit_rate": 0.6067,
"hit_rate_percentage": "60.7%"
}
},
"timestamp": 1706745600.123
}Response Fields:
status(string): "success" if metrics retrieved successfullymetrics(object): Performance metrics across all sessionsllm_calls(object): Gemini API call statisticstotal(integer): Total number of LLM API calls madeavg_duration(float): Average call duration in secondsmin_duration(float): Fastest call durationmax_duration(float): Slowest call duration
api_requests(object): API endpoint statisticstotal(integer): Total API requests receivedavg_duration(float): Average request processing timemin_duration(float): Fastest requestmax_duration(float): Slowest request
cache(object): Caching effectiveness metricshits(integer): Number of successful cache retrievalsmisses(integer): Number of cache misseshit_rate(float): Cache hit rate (0.0 to 1.0)hit_rate_percentage(string): Formatted hit rate percentage
timestamp(float): Unix timestamp when metrics were retrieved
Performance Health Indicators:
LLM Calls:
- ✅ Healthy: avg_duration < 2.5s, max_duration < 5s
⚠️ Warning: avg_duration 2.5-4s, max_duration 5-8s- ❌ Critical: avg_duration > 4s, max_duration > 8s
API Requests:
- ✅ Healthy: avg_duration < 3s
⚠️ Warning: avg_duration 3-5s- ❌ Critical: avg_duration > 5s
Cache Performance:
- ✅ Excellent: hit_rate > 0.7 (70%)
- ✅ Good: hit_rate 0.5-0.7 (50-70%)
⚠️ Poor: hit_rate 0.3-0.5 (30-50%)- ❌ Critical: hit_rate < 0.3 (30%)
Error Response (500 - Server Error):
{
"detail": "Failed to retrieve metrics: Database connection error"
}Error Response (503 - Service Unavailable):
{
"detail": "Metrics service temporarily unavailable"
}Metrics Breakdown:
LLM Calls:
- All Gemini API calls (question generation, evaluation, analysis)
- Tracks duration to identify slow calls
- Alerts logged for calls > 5s
API Requests:
- All endpoint requests
- Measures end-to-end latency
- Alerts for requests > 3s
Cache Performance:
- Hit rate indicates caching effectiveness
- Target: > 60% hit rate
- Low hit rate suggests optimization needed
Use Cases:
- System health monitoring
- Performance optimization
- Cost analysis
- Capacity planning
Purpose: Reset all performance metrics (admin/testing only)
Response (200 OK):
{
"status": "success",
"message": "Metrics reset successfully"
}Error Response (500):
{
"detail": "Error message"
}Warning: This clears all performance data. Use only for:
- Testing
- Development
- After analyzing metrics
- Starting fresh monitoring
{
user_id: string; // Unique user identifier
session_id: string; // Unique session identifier
role: string; // Job role title
company: string; // Company name
cv_text: string; // Full CV/resume text
jd_text: string; // Full job description text
}{
user_id: string; // Required
session_id: string; // Required
role: string; // Required
company: string; // Required
cv_id?: string; // MongoDB ObjectId or string ID
jd_id?: string; // MongoDB ObjectId or string ID
cv_file?: File; // CV file (.pdf, .docx, .txt) - Recommended
jd_file?: File; // JD file (.pdf, .docx, .txt) - Recommended
cv_text?: string; // Alternative: direct text
jd_text?: string; // Alternative: direct text
}{
session_id: string; // Required
audio_file?: File; // .wav, .mp3, .m4a
video_file?: File; // .mp4, .webm, .avi
}{
session_id: string;
user_id: string;
role: string;
company: string;
question_count: number;
stage: "intro" | "technical" | "behavioral" | "closing";
completed: boolean;
messages: Array<{
role: "interviewer" | "candidate";
content: string;
timestamp: number;
metadata?: {
stage?: string;
evaluation?: Evaluation;
voice_metrics?: VoiceMetrics;
};
}>;
avg_response_time: number;
}{
clarity: number; // 1-10
relevance: number; // 1-10
depth: number; // 1-10
feedback: string; // Brief feedback
}{
session_id: string;
total_questions: number;
response_times: {
min: number;
max: number;
avg: number;
all: number[];
};
cache_status: "active" | "not_cached";
}{
status: "success";
metrics: {
llm_calls: {
total: number;
avg_duration: number;
min_duration: number;
max_duration: number;
};
api_requests: {
total: number;
avg_duration: number;
min_duration: number;
max_duration: number;
};
cache: {
hits: number;
misses: number;
hit_rate: number;
hit_rate_percentage: string;
};
};
timestamp: number;
}| V1 Endpoint | V2 Endpoint | Changes |
|---|---|---|
POST /v1/interview/start |
POST /interview/v2/start-with-ids |
✅ Added MongoDB ID support ✅ Added caching ✅ 60% faster |
POST /v1/interview/answer |
POST /interview/v2/answer |
✅ Added voice analysis ✅ Added video support ✅ Concurrent processing ✅ 50% faster |
GET /v1/interview/state/{id} |
GET /interview/v2/state/{id} |
✅ Enhanced response ✅ Added performance data |
| N/A | GET /interview/v2/stream/{id} |
✅ NEW: SSE streaming |
| N/A | GET /interview/v2/performance/{id} |
✅ NEW: Performance metrics |
| N/A | GET /interview/v2/metrics/global |
✅ NEW: Global analytics |
V1:
{
"session_id": "sess_123",
"user_id": "user_123",
"first_question": "Tell me about yourself.",
"state": { ... }
}V2:
{
"session_id": "sess_123",
"status": "active",
"question": "Tell me about yourself.",
"question_number": 1
}Changes:
- ✅ Simplified response
- ✅ Added
statusfield - ✅ Added
question_number - ✅ Removed redundant
stateobject - ✅ 60-70% faster
V1:
{
"evaluation": { ... },
"next_question": "...",
"state": { ... }
}V2:
{
"session_id": "sess_456",
"status": "active",
"question": "...",
"question_number": 2,
"evaluation": {
"clarity": 8,
"relevance": 9,
"depth": 7,
"feedback": "Good answer"
}
}Changes:
- ✅ Added
session_idfor clarity - ✅ Added
statusfor completion tracking - ✅ Added
question_number - ✅ Simplified evaluation structure
- ✅ Removed large
stateobject - ✅ 50-60% faster
-
MongoDB Caching
- CV analysis cached for 7 days
- Session state cached for 24 hours
- Automatic cache invalidation
-
Streaming Support
- Server-Sent Events for real-time questions
- Progressive display
- Better UX
-
Performance Monitoring
- Per-session metrics
- Global analytics
- Cache hit rate tracking
- Slow operation alerts
-
Async Operations
- Parallel CV + JD analysis
- Non-blocking LLM calls
- Concurrent processing
-
Enhanced Error Handling
- Better error messages
- Detailed validation
- Graceful degradation
# Option A: Start Interview with JSON (v2/start)
curl -X POST http://localhost:8000/interview/v2/start \
-H "Content-Type: application/json" \
-d '{
"user_id": "user_123",
"session_id": "sess_456",
"role": "Senior Software Engineer",
"company": "TechCorp",
"cv_text": "John Doe\\nSenior Software Engineer with 5 years of Python experience...",
"jd_text": "We are seeking a Senior Software Engineer with expertise in Python, FastAPI, and microservices..."
}'
# Response:
{
"session_id": "sess_456",
"status": "active",
"question": "Hi! Thanks for joining. Tell me about your Python experience.",
"question_number": 1
}
# Option B: Start Interview (with file uploads - recommended)
curl -X POST http://localhost:8000/interview/v2/start-with-ids \
-F "user_id=user_123" \
-F "session_id=sess_456" \
-F "role=Senior Software Engineer" \
-F "company=TechCorp" \
-F "cv_file=@resume.pdf" \
-F "jd_file=@job_description.pdf"
# Alternative: Using MongoDB IDs
curl -X POST http://localhost:8000/interview/v2/start-with-ids \
-F "user_id=user_123" \
-F "session_id=sess_456" \
-F "role=Senior Software Engineer" \
-F "company=TechCorp" \
-F "cv_id=60d5ec49f1b2c8b1f8c4e5a1" \
-F "jd_id=60d5ec49f1b2c8b1f8c4e5a2"
# Response:
{
"session_id": "sess_456",
"status": "active",
"question": "Hi! Thanks for joining. Tell me about your Python experience.",
"question_number": 1
}
# 2. Submit Answer (Audio)
curl -X POST http://localhost:8000/interview/v2/answer \
-F "session_id=sess_456" \
-F "audio_file=@answer1.wav"
# Response:
{
"session_id": "sess_456",
"status": "active",
"question": "That's great. Can you describe a challenging project?",
"question_number": 2,
"evaluation": {
"clarity": 8,
"relevance": 9,
"depth": 7,
"feedback": "Clear answer with good details"
}
}
# 3. Check Performance
curl http://localhost:8000/interview/v2/performance/sess_456
# Response:
{
"session_id": "sess_456",
"total_questions": 2,
"response_times": {
"min": 2.12,
"max": 4.56,
"avg": 3.34,
"all": [4.56, 2.12]
},
"cache_status": "active"
}
# 4. Complete Interview (after 5 questions)
curl -X POST http://localhost:8000/interview/v2/complete/sess_456
# Response:
{
"session_id": "sess_456",
"status": "completed",
"total_questions": 5,
"evaluation": {
"overall_score": 7.83,
"recommendation": "hire",
"clarity": 8.2,
"relevance": 8.4,
"depth": 6.9
},
"conversation": [ ... ],
"performance_metrics": {
"avg_response_time": 2.45
}
}// JavaScript client
const sessionId = 'sess_456';
const eventSource = new EventSource(
`http://localhost:8000/interview/v2/stream/${sessionId}`
);
let fullQuestion = '';
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.chunk) {
fullQuestion += data.chunk;
document.getElementById('question').innerText = fullQuestion;
}
if (data.done) {
console.log('Complete question:', fullQuestion);
eventSource.close();
}
if (data.error) {
console.error('Error:', data.error);
eventSource.close();
}
};
eventSource.onerror = (error) => {
console.error('EventSource error:', error);
eventSource.close();
};import requests
import json
BASE_URL = "http://localhost:8000"
# 1. Start session (with file uploads - recommended)
with open("resume.pdf", "rb") as cv, open("job_description.pdf", "rb") as jd:
files = {
"cv_file": cv,
"jd_file": jd
}
data = {
"user_id": "user_123",
"session_id": "sess_789",
"role": "Backend Engineer",
"company": "StartupCo"
}
response = requests.post(
f"{BASE_URL}/interview/v2/start-with-ids",
files=files,
data=data
)
print(f"First question: {response.json()['question']}")
# Alternative: Using direct text
response = requests.post(
f"{BASE_URL}/interview/v2/start",
json={
"user_id": "user_123",
"session_id": "sess_789",
"role": "Backend Engineer",
"company": "StartupCo",
"cv_text": "John Doe\n5 years Python...",
"jd_text": "Backend Engineer\nRequires Python..."
}
)
print(f"First question: {response.json()['question']}")
# 2. Submit audio answer
with open("answer.wav", "rb") as audio:
files = {"audio_file": audio}
data = {"session_id": "sess_789"}
response = requests.post(
f"{BASE_URL}/interview/v2/answer",
files=files,
data=data
)
result = response.json()
print(f"Evaluation: {result['evaluation']}")
print(f"Next question: {result['question']}")
# 3. Get session state
response = requests.get(f"{BASE_URL}/interview/v2/state/sess_789")
state = response.json()
print(f"Progress: {state['question_count']} questions asked")
print(f"Stage: {state['stage']}")
# 4. Monitor performance
response = requests.get(f"{BASE_URL}/interview/v2/performance/sess_789")
metrics = response.json()
print(f"Avg response time: {metrics['response_times']['avg']:.2f}s")import requests
import time
BASE_URL = "http://localhost:8000"
def monitor_system():
"""Monitor system performance"""
response = requests.get(f"{BASE_URL}/interview/v2/metrics/global")
metrics = response.json()["metrics"]
print("\n=== System Performance ===")
print(f"LLM Calls: {metrics['llm_calls']['total']}")
print(f"Avg LLM Duration: {metrics['llm_calls']['avg_duration']:.2f}s")
print(f"Cache Hit Rate: {metrics['cache']['hit_rate_percentage']}")
print(f"API Avg Duration: {metrics['api_requests']['avg_duration']:.2f}s")
# Check if performance is good
if metrics['llm_calls']['avg_duration'] > 3.0:
print("⚠️ Warning: LLM calls are slow!")
if metrics['cache']['hit_rate'] < 0.5:
print("⚠️ Warning: Low cache hit rate!")
if metrics['cache']['hit_rate'] > 0.7:
print("✅ Excellent cache performance!")
# Run every minute
while True:
monitor_system()
time.sleep(60)# Best - File uploads with automatic text extraction
curl -X POST /interview/v2/start-with-ids \
-F "cv_file=@resume.pdf" \
-F "jd_file=@job_description.pdf"
# Good - MongoDB IDs enable caching
curl -X POST /interview/v2/start-with-ids \
-F "cv_id=60d5ec49..." \
-F "jd_id=60d5ec50..."
# Avoid - Direct text, no caching benefits
curl -X POST /interview/v2/start \
-d '{"cv_text": "...", "jd_text": "..."}'# Check global metrics
curl /interview/v2/metrics/global
# Check specific session
curl /interview/v2/performance/{session_id}// Progressive display vs. waiting
const stream = new EventSource('/interview/v2/stream/...');fetch('/interview/v2/answer', { ... })
.then(res => res.json())
.then(data => {
if (data.status === 'completed') {
// Interview finished
showCompletionPage();
} else {
// Show next question
displayQuestion(data.question);
}
})
.catch(error => {
console.error('Error:', error);
showErrorMessage();
});| Metric | Target | Alert Threshold |
|---|---|---|
| First question (cached) | < 3s | > 5s |
| First question (uncached) | < 6s | > 10s |
| Subsequent questions | < 3s | > 5s |
| Cache hit rate | > 60% | < 40% |
| LLM avg duration | < 2.5s | > 4s |
- Update API base URL to
/interview/v2/ - Change request format for start endpoint
- Update response parsing (new structure)
- Implement streaming support (optional)
- Add performance monitoring
- Test error handling
- Update documentation
- Monitor cache hit rate
- Compare performance metrics
- Gradual rollout to production
1. Slow responses despite caching
- Check cache hit rate:
/interview/v2/metrics/global - Verify MongoDB connection
- Review logs for "SLOW LLM CALL" warnings
2. Session not found errors
- Check session expiry (24-hour TTL)
- Verify session_id is correct
- Check MongoDB connection
3. Low cache hit rate
- Ensure using MongoDB IDs, not raw text
- Check CV/JD ID consistency
- Verify cache TTL settings
4. Audio transcription failures
- Verify audio file format (wav, mp3, m4a)
- Check file size (< 10MB recommended)
- Ensure audio has actual content
5. CV/JD file upload failures
- Supported formats: PDF, DOCX, TXT
- Maximum file size: 10MB per file
- Ensure files are not corrupted
- Check file encoding (UTF-8 recommended for TXT)
- Verify files contain actual text content
6. Validation errors: "user_id must be a string"
- Problem: FastAPI Pydantic validation failing
- Cause: Missing
Content-Type: application/jsonheader - Solution: Add
-H "Content-Type: application/json"to your request - Wrong: Sending form-data to
/v2/startendpoint - Correct: Send JSON to
/v2/startOR form-data to/v2/start-with-ids
Example Fix:
# ❌ Wrong - Missing Content-Type header
curl -X POST http://localhost:8000/interview/v2/start -d '{...}'
# ✅ Correct - With proper header
curl -X POST http://localhost:8000/interview/v2/start \
-H "Content-Type: application/json" \
-d '{"user_id":"user_123", ...}'
# ✅ Alternative - Use start-with-ids for form-data
curl -X POST http://localhost:8000/interview/v2/start-with-ids \
-F "user_id=user_123" \
-F "session_id=sess_456" \
-F "role=Engineer" \
-F "company=TechCorp" \
-F "cv_text=..." \
-F "jd_text=..."# Check session state
GET /interview/v2/state/{session_id}
# Check performance
GET /interview/v2/performance/{session_id}
# Global metrics
GET /interview/v2/metrics/global
# Health check
GET /healthz- ✅ Initial V2 release
- ✅ MongoDB caching implementation
- ✅ LangGraph workflow integration
- ✅ Streaming support via SSE
- ✅ Performance monitoring system
- ✅ Async/concurrent operations
- ✅ 60-70% performance improvement
- ✅ Comprehensive documentation
Last Updated: February 1, 2026
API Version: 2.0
Base Path: /interview/v2/
Status: ✅ Production Ready