Complete API Reference for AI Resume Builder & Career Platform
Version: 1.0.0 | Base URL: http://localhost:5000/api
The AI Resume Builder API is a RESTful API that provides endpoints for resume management, AI enhancement, job searching, and community features. All endpoints (except health check) require authentication via Firebase JWT tokens.
| Environment | URL |
|---|---|
| Development | http://localhost:5000/api |
| Production | https://api.yourdomain.com/api |
GET /healthResponse:
{
"status": "OK",
"timestamp": "2026-01-08T10:30:00.000Z",
"environment": "development"
}All protected endpoints require a Firebase ID token in the Authorization header.
Authorization: Bearer <firebase_id_token>// Frontend: Get token from Firebase Auth
import { auth } from './config/firebase';
const token = await auth.currentUser.getIdToken();The backend verifies tokens using Firebase Admin SDK:
// Decoded user object available in req.user
{
uid: "firebase_user_id",
email: "user@example.com",
name: "John Doe",
picture: "https://..."
}{
"success": false,
"error": "Error message description"
}| Code | Description |
|---|---|
200 |
Success |
201 |
Created |
400 |
Bad Request - Invalid input |
401 |
Unauthorized - Missing/invalid token |
403 |
Forbidden - Access denied |
404 |
Not Found - Resource doesn't exist |
429 |
Too Many Requests - Rate limit exceeded |
500 |
Internal Server Error |
// 401 Unauthorized
{
"success": false,
"error": "No authorization token provided"
}
// 404 Not Found
{
"success": false,
"error": "Resume not found"
}
// 429 Rate Limited
{
"error": "Too many requests, please try again later."
}| Window | Max Requests | Scope |
|---|---|---|
| 15 minutes | 100 | Per IP address |
When rate limited, the API returns a 429 status with:
{
"error": "Too many requests, please try again later."
}Verifies the Firebase ID token and returns user information.
POST /api/auth/verifyHeaders:
Authorization: Bearer <token>Response:
{
"success": true,
"user": {
"uid": "firebase_uid",
"email": "user@example.com",
"name": "John Doe",
"picture": "https://..."
}
}Retrieves the authenticated user's profile.
GET /api/auth/profileHeaders:
Authorization: Bearer <token>Response:
{
"success": true,
"user": {
"uid": "firebase_uid",
"email": "user@example.com",
"name": "John Doe",
"picture": "https://..."
}
}Uploads a PDF file and extracts text content.
POST /api/uploadHeaders:
Authorization: Bearer <token>
Content-Type: multipart/form-dataBody:
file: <PDF file> (max 10MB)
Response:
{
"success": true,
"data": {
"resumeId": "uuid-v4-string",
"originalFilename": "resume.pdf",
"size": 125432,
"extractedText": "John Doe\nSoftware Engineer\n...",
"pageCount": 2,
"metadata": {
"info": { ... },
"uploadedAt": "2026-01-08T10:30:00.000Z"
}
}
}Errors:
400- No file uploaded400- Failed to parse PDF
Extracts text from a PDF without creating a resume record.
POST /api/upload/extract-textHeaders:
Authorization: Bearer <token>
Content-Type: multipart/form-dataBody:
file: <PDF file>
Response:
{
"success": true,
"data": {
"text": "Extracted text content...",
"pageCount": 2
}
}Retrieves all resumes for the authenticated user.
GET /api/resumesHeaders:
Authorization: Bearer <token>Response:
{
"success": true,
"data": {
"resumes": [
{
"id": "resume_id",
"userId": "firebase_uid",
"originalText": "...",
"enhancedText": "...",
"jobRole": "Software Engineer",
"preferences": {
"yearsOfExperience": 5,
"skills": ["React", "Node.js"],
"industry": "Technology"
},
"title": "Tech Resume",
"pdfUrl": null,
"createdAt": "2026-01-08T10:30:00.000Z",
"lastModified": "2026-01-08T10:30:00.000Z"
}
],
"count": 1
}
}Retrieves a specific resume by ID.
GET /api/resumes/:resumeIdParameters:
| Name | Type | Description |
|---|---|---|
resumeId |
string | MongoDB ObjectId |
Response:
{
"success": true,
"data": {
"id": "resume_id",
"userId": "firebase_uid",
"originalText": "...",
"enhancedText": "...",
"jobRole": "Software Engineer",
"preferences": { ... },
"title": "Tech Resume",
"createdAt": "2026-01-08T10:30:00.000Z",
"lastModified": "2026-01-08T10:30:00.000Z"
}
}Errors:
404- Resume not found403- Access denied
Creates a new resume record.
POST /api/resumesHeaders:
Authorization: Bearer <token>
Content-Type: application/jsonBody:
{
"originalText": "John Doe\nSoftware Engineer...",
"enhancedText": "# John Doe\n## Summary...",
"jobRole": "Software Engineer",
"preferences": {
"yearsOfExperience": 5,
"skills": ["React", "Node.js"],
"industry": "Technology",
"customInstructions": "Focus on leadership"
},
"title": "Tech Resume 2026"
}Required Fields:
originalText
Response:
{
"success": true,
"data": {
"id": "new_resume_id",
"userId": "firebase_uid",
"originalText": "...",
"enhancedText": "...",
"jobRole": "Software Engineer",
"preferences": { ... },
"title": "Tech Resume 2026",
"createdAt": "2026-01-08T10:30:00.000Z"
}
}Updates an existing resume.
PUT /api/resumes/:resumeIdParameters:
| Name | Type | Description |
|---|---|---|
resumeId |
string | MongoDB ObjectId |
Body:
{
"enhancedText": "Updated enhanced content...",
"title": "Updated Title",
"jobRole": "Senior Software Engineer"
}Allowed Fields:
originalTextenhancedTextjobRolepreferencestitlepdfUrl
Response:
{
"success": true,
"data": {
"id": "resume_id",
"userId": "firebase_uid",
"originalText": "...",
"enhancedText": "Updated enhanced content...",
"title": "Updated Title",
"lastModified": "2026-01-08T11:00:00.000Z"
}
}Deletes a resume.
DELETE /api/resumes/:resumeIdResponse:
{
"success": true,
"message": "Resume deleted successfully"
}Downloads the resume as a formatted PDF file.
GET /api/resumes/:resumeId/download?version=enhancedQuery Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
version |
string | enhanced |
enhanced or original |
Response:
- Content-Type:
application/pdf - Content-Disposition:
attachment; filename="resume.pdf"
Enhances a resume using Google Gemini AI.
POST /api/enhanceBody:
{
"resumeText": "John Doe\nSoftware Engineer at Google...",
"preferences": {
"jobRole": "Senior Software Engineer",
"yearsOfExperience": 5,
"skills": ["React", "Node.js", "Python"],
"industry": "Technology",
"customInstructions": "Emphasize leadership experience"
}
}Required Fields:
resumeTextpreferences.jobRole
Response:
{
"success": true,
"data": {
"enhancedResume": "# John Doe\n\n[email@domain.com](mailto:email@domain.com) | ...",
"tokensUsed": {
"prompt": 0,
"completion": 0,
"total": 0
},
"processedAt": "2026-01-08T10:30:00.000Z"
}
}Generates a professional summary for a resume.
POST /api/enhance/summaryBody:
{
"resumeText": "John Doe\nSoftware Engineer...",
"jobRole": "Senior Software Engineer"
}Response:
{
"success": true,
"data": {
"summary": "Results-driven Senior Software Engineer with 5+ years of experience..."
}
}Gets AI-generated suggestions for improving the resume.
POST /api/enhance/suggestionsBody:
{
"resumeText": "John Doe\nSoftware Engineer...",
"jobRole": "Senior Software Engineer"
}Response:
{
"success": true,
"data": {
"suggestions": "1. Add quantifiable achievements...\n2. Include relevant certifications..."
}
}Analyzes resume compatibility with Applicant Tracking Systems.
POST /api/enhance/ats-analysisBody:
{
"resumeText": "John Doe\nSoftware Engineer...",
"jobRole": "Senior Software Engineer"
}Response:
{
"success": true,
"data": {
"score": 85,
"strengths": ["Good keyword usage", "Clear formatting"],
"improvements": ["Add more metrics", "Include certifications"],
"keywords": {
"found": ["JavaScript", "React", "Node.js"],
"missing": ["TypeScript", "AWS"]
}
}
}Searches for jobs using RapidAPI JSearch.
GET /api/fetchjobs?query=software+engineer&location=New+York&page=1Query Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
query |
string | required | Search keywords |
location |
string | optional | Job location |
page |
number | 1 |
Page number |
employment_types |
string | optional | FULLTIME,PARTTIME,CONTRACTOR,INTERN |
remote_jobs_only |
boolean | false |
Remote jobs filter |
Response:
{
"success": true,
"data": {
"jobs": [
{
"job_id": "unique_job_id",
"job_title": "Software Engineer",
"employer_name": "Google",
"employer_logo": "https://...",
"job_city": "New York",
"job_state": "NY",
"job_country": "US",
"job_employment_type": "FULLTIME",
"job_salary_min": 100000,
"job_salary_max": 150000,
"job_description": "...",
"job_apply_link": "https://...",
"job_posted_at_datetime_utc": "2026-01-08T10:30:00.000Z"
}
],
"count": 10,
"page": 1
}
}Gets all job alerts for the user.
GET /api/job-alertsResponse:
{
"success": true,
"count": 2,
"alerts": [
{
"_id": "alert_id",
"userId": "firebase_uid",
"userEmail": "user@example.com",
"title": "React Developer Jobs",
"keywords": ["React", "Frontend"],
"location": "New York",
"remoteOnly": false,
"salaryMin": 80000,
"salaryMax": 150000,
"employmentType": ["full-time"],
"isActive": true,
"lastCheckedAt": "2026-01-08T10:30:00.000Z",
"totalJobsFound": 45,
"totalEmailsSent": 12,
"position": 1
}
]
}Gets summary statistics for user's alerts.
GET /api/job-alerts/stats/summaryResponse:
{
"success": true,
"stats": {
"totalAlerts": 3,
"activeAlerts": 2,
"totalJobsFound": 150,
"totalEmailsSent": 45,
"queueStatus": {
"available": true,
"waiting": 5,
"active": 1,
"completed": 100
}
}
}Gets a specific alert with notification history.
GET /api/job-alerts/:idResponse:
{
"success": true,
"alert": {
"_id": "alert_id",
"title": "React Developer Jobs",
"keywords": ["React"],
"location": "New York",
"isActive": true,
...
},
"notificationHistory": [
{
"_id": "notification_id",
"type": "email",
"status": "sent",
"sentAt": "2026-01-08T10:30:00.000Z",
"jobListingId": {
"title": "React Developer",
"company": "StartupXYZ",
"location": "New York"
},
"position": 1
}
]
}Creates a new job alert.
POST /api/job-alertsBody:
{
"title": "Python Backend Jobs",
"keywords": ["Python", "Django", "FastAPI"],
"location": "San Francisco",
"remoteOnly": true,
"salaryMin": 100000,
"salaryMax": 200000,
"employmentType": ["full-time", "contract"]
}Required Fields:
title
Response:
{
"success": true,
"message": "Job alert created successfully",
"alert": {
"_id": "new_alert_id",
"title": "Python Backend Jobs",
"isActive": true,
...
}
}Updates an existing alert.
PUT /api/job-alerts/:idBody:
{
"title": "Updated Title",
"keywords": ["Updated", "Keywords"],
"isActive": false
}Response:
{
"success": true,
"message": "Job alert updated successfully",
"alert": { ... }
}Deletes a job alert.
DELETE /api/job-alerts/:idResponse:
{
"success": true,
"message": "Job alert deleted successfully"
}Gets all tracked jobs for the user.
GET /api/job-trackerResponse:
{
"success": true,
"trackedJobs": [
{
"id": "tracked_job_id",
"userId": "firebase_uid",
"jobId": "external_job_id",
"title": "Software Engineer",
"company": "Google",
"location": "Mountain View, CA",
"jobType": "Full-time",
"salary": "$150,000 - $200,000",
"applyLink": "https://careers.google.com/...",
"status": "applied",
"notes": [
{
"text": "Applied via website",
"createdAt": "2026-01-08T10:30:00.000Z"
}
],
"createdAt": "2026-01-08T10:30:00.000Z"
}
],
"count": 1
}Gets application statistics.
GET /api/job-tracker/statsResponse:
{
"success": true,
"stats": {
"total": 25,
"saved": 10,
"applied": 8,
"interviewing": 4,
"offered": 2,
"rejected": 1
}
}Adds a job to the tracker.
POST /api/job-trackerBody:
{
"jobId": "external_job_id",
"title": "Software Engineer",
"company": "Google",
"location": "Mountain View, CA",
"jobType": "Full-time",
"salary": "$150,000 - $200,000",
"applyLink": "https://careers.google.com/...",
"description": "Job description...",
"status": "saved"
}Required Fields:
titlecompany
Response:
{
"success": true,
"message": "Job tracked successfully",
"data": {
"id": "new_tracked_job_id",
...
}
}Updates status or adds notes to a tracked job.
PUT /api/job-tracker/:trackerIdBody:
{
"status": "interviewing",
"notes": "Phone screen scheduled for Monday"
}Valid Status Values:
savedappliedinterviewingofferedrejected
Response:
{
"success": true,
"message": "Job updated successfully",
"data": { ... }
}Removes a job from the tracker.
DELETE /api/job-tracker/:trackerIdResponse:
{
"success": true,
"message": "Tracked job deleted successfully"
}GET /api/community/channelsResponse:
{
"success": true,
"channels": [
{
"id": "channel_id",
"name": "general",
"description": "General discussions",
"memberCount": 150,
"isDefault": true,
"lastMessage": {
"content": "Hello everyone!",
"senderName": "John",
"timestamp": "2026-01-08T10:30:00.000Z"
}
}
]
}POST /api/community/channelsBody:
{
"name": "react-developers",
"description": "Discussions about React.js"
}GET /api/community/channels/:channelId/messages?limit=50Query Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
limit |
number | 50 |
Messages to retrieve |
before |
string | optional | Cursor for pagination |
POST /api/community/channels/:channelId/joinPOST /api/community/channels/:channelId/leaveGET /api/community/posts?page=1&limit=20Query Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
page |
number | 1 |
Page number |
limit |
number | 20 |
Posts per page |
tag |
string | optional | Filter by tag |
POST /api/community/postsBody:
{
"title": "Tips for Technical Interviews",
"content": "Here are my top tips for acing technical interviews...",
"tags": ["interviews", "tips", "career"]
}GET /api/community/posts/:postIdPUT /api/community/posts/:postIdDELETE /api/community/posts/:postIdPOST /api/community/posts/:postId/likeGET /api/community/posts/:postId/commentsPOST /api/community/posts/:postId/commentsBody:
{
"content": "Great post! Very helpful."
}POST /api/community/comments/:commentId/likeGET /api/community/conversationsGET /api/community/conversations/:conversationId/messagesGET /api/community/online-usersResponse:
{
"success": true,
"users": [
{
"uid": "user_id",
"name": "John Doe",
"photoURL": "https://...",
"lastSeen": "2026-01-08T10:30:00.000Z"
}
]
}Syncs MongoDB data to Firebase Firestore.
POST /api/admin/sync-to-firebaseResponse:
{
"success": true,
"message": "Data synced to Firebase successfully",
"timestamp": "2026-01-08T10:30:00.000Z"
}Saves user profile to Firebase.
POST /api/admin/save-my-profileBody:
{
"bio": "Software Engineer",
"location": "San Francisco",
"website": "https://johndoe.com"
}Gets system-wide statistics.
GET /api/admin/statsResponse:
{
"success": true,
"stats": {
"totalAlerts": 500,
"activeAlerts": 350,
"totalNotifications": 10000,
"totalJobs": 25000,
"timestamp": "2026-01-08T10:30:00.000Z"
}
}import { io } from 'socket.io-client';
const socket = io('http://localhost:5000', {
auth: { token: 'firebase_id_token' }
});| Event | Payload | Description |
|---|---|---|
join_channel |
{ channelId } |
Join a channel room |
leave_channel |
{ channelId } |
Leave a channel room |
send_message |
{ channelId, content } |
Send channel message |
send_dm |
{ recipientId, content } |
Send direct message |
typing_start |
{ channelId } |
User started typing |
typing_stop |
{ channelId } |
User stopped typing |
add_reaction |
{ messageId, emoji } |
Add reaction to message |
remove_reaction |
{ messageId, emoji } |
Remove reaction |
| Event | Payload | Description |
|---|---|---|
new_message |
{ message, channelId } |
New channel message |
new_dm |
{ message, senderId } |
New direct message |
user_online |
{ uid, name } |
User came online |
user_offline |
{ uid, name } |
User went offline |
typing |
{ userId, channelId } |
Someone is typing |
reaction_added |
{ messageId, emoji, user } |
Reaction added |
reaction_removed |
{ messageId, emoji, userId } |
Reaction removed |
job_alert_processing |
{ alertId, alertTitle } |
Alert being processed |
new_jobs_found |
{ alertId, jobs } |
New jobs matched alert |
email_sent |
{ alertId, jobCount } |
Alert email sent |
// Join channel
socket.emit('join_channel', { channelId: 'general' });
// Send message
socket.emit('send_message', {
channelId: 'general',
content: 'Hello everyone!'
});
// Listen for messages
socket.on('new_message', (data) => {
console.log('New message:', data.message);
});
// Listen for job alerts
socket.on('new_jobs_found', (data) => {
console.log(`${data.jobs.length} new jobs found for alert ${data.alertId}`);
});interface Resume {
id: string;
userId: string;
originalText: string;
enhancedText: string | null;
jobRole: string | null;
preferences: {
yearsOfExperience: number;
skills: string[];
industry: string;
customInstructions: string;
};
title: string;
pdfUrl: string | null;
createdAt: Date;
lastModified: Date;
}interface JobAlert {
_id: string;
userId: string;
userEmail: string;
userName: string;
title: string;
keywords: string[];
location: string;
remoteOnly: boolean;
salaryMin: number | null;
salaryMax: number | null;
employmentType: ('full-time' | 'part-time' | 'contract' | 'internship')[];
isActive: boolean;
lastCheckedAt: Date | null;
totalJobsFound: number;
totalEmailsSent: number;
createdAt: Date;
updatedAt: Date;
}interface TrackedJob {
id: string;
userId: string;
jobId: string;
title: string;
company: string;
location: string;
jobType: string;
salary: string | null;
applyLink: string | null;
description: string | null;
status: 'saved' | 'applied' | 'interviewing' | 'offered' | 'rejected';
notes: Array<{
text: string;
createdAt: Date;
}>;
createdAt: Date;
updatedAt: Date;
}// api.js
const API_BASE = 'http://localhost:5000/api';
export const api = {
async request(endpoint, options = {}) {
const token = await getAuthToken();
const response = await fetch(`${API_BASE}${endpoint}`, {
...options,
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`,
...options.headers,
},
});
if (!response.ok) {
throw new Error(await response.text());
}
return response.json();
},
resumes: {
getAll: () => api.request('/resumes'),
get: (id) => api.request(`/resumes/${id}`),
create: (data) => api.request('/resumes', {
method: 'POST',
body: JSON.stringify(data),
}),
update: (id, data) => api.request(`/resumes/${id}`, {
method: 'PUT',
body: JSON.stringify(data),
}),
delete: (id) => api.request(`/resumes/${id}`, { method: 'DELETE' }),
},
enhance: {
full: (resumeText, preferences) => api.request('/enhance', {
method: 'POST',
body: JSON.stringify({ resumeText, preferences }),
}),
summary: (resumeText, jobRole) => api.request('/enhance/summary', {
method: 'POST',
body: JSON.stringify({ resumeText, jobRole }),
}),
},
};