Paste a job description. Get a tailored resume, ATS match score, rewritten bullets, cold outreach email, interview prep, and a downloadable PDF — all in under 60 seconds.
Job Copilot is a full-stack AI application that eliminates the manual effort of tailoring your resume for every job application. You paste (or link) a job description and the system automatically:
- Parses the JD — extracts role, company, required skills, and tech stack via LLM
- Scores your profile — computes a match percentage against your candidate profile
- Rewrites resume bullets — tailors achievement-focused bullets to mirror JD language
- Generates cold outreach — writes a personalised recruiter email ready to send
- Prepares interview Q&A — generates technical + behavioural questions with STAR answers
- Builds a PDF resume — single-page ATS-optimised PDF with your rewritten content
- Persists everything — every analysis, PDF, and application stored in Supabase cloud
Real-time progress via Server-Sent Events across four phases: Parse → Score → Rewrite → Save. Paste raw text or provide a URL — the app auto-scrapes the job page.
Resume bullets are regenerated to mirror the JD's exact keywords and phrasing. An inline editor lets you accept, modify, or reject each bullet before finalising.
Every analysis produces a 0–100% ATS match score with a visual breakdown of matched vs. missing skills and an experience-fit label (Good / Stretch / Reach).
Produces a personalised recruiter email based on the target company and role — copy and send in one click.
Role-specific technical and behavioural questions with model STAR-format answers, all tailored to the specific JD.
Clean single-page PDF built from your profile and rewritten bullets. Uploaded to Supabase Storage and downloadable at any time from application history.
Searches the internet for relevant jobs automatically using your saved profile (role, skills, location). Powered by the Apify Google Search Scraper. Click any result to instantly analyse that JD.
- Kanban board — drag-and-drop across Applied / Interviewing / Offer / Rejected
- Sortable table — job URL, score, status, model, tokens consumed, applied date
- Inline status editing, full application detail panel, delete
Switch between Groq (free, fast), OpenAI, Anthropic Claude, Google Gemini, and local Ollama directly from the UI — no code changes needed. Per-model token usage is tracked and displayed.
Full YAML-backed candidate profile editable from the UI. Changes are picked up by the next analysis.
| Technology | |
|---|---|
| API Framework | FastAPI (Python 3.11+) |
| AI / LLM Orchestration | LangChain — Groq / OpenAI / Anthropic / Google / Ollama |
| Streaming | Server-Sent Events via FastAPI StreamingResponse |
| PDF Generation | xhtml2pdf (pure Python, zero system dependencies) |
| JD Scraping | httpx + BeautifulSoup4 |
| Job Discovery | Apify Google Search Scraper REST API |
| Caching | Redis (optional — gracefully skipped if unavailable) |
| Config | pydantic-settings + python-dotenv |
| Technology | |
|---|---|
| Database | Supabase (PostgreSQL) via supabase-py client |
| File Storage | Supabase Storage — resumes bucket, one PDF per application |
| Technology | |
|---|---|
| Framework | React 18 + TypeScript |
| Build | Vite |
| Styling | Tailwind CSS |
| Server State | TanStack Query (React Query v5) |
| Drag & Drop | dnd-kit (Kanban board) |
| HTTP | Axios |
┌──────────────────────────────────────────────────────────┐
│ React Frontend │
│ JDInput → Stream → BulletEditor → PDF Download │
│ FindJobs │ Dashboard (Kanban) │ ApplicationsTable │
└─────────────────────┬────────────────────────────────────┘
│ HTTP / SSE
┌─────────────────────▼────────────────────────────────────┐
│ FastAPI Backend │
│ │
│ POST /analyze/stream │
│ ├─ parse_jd() LLM: extract role + skills │
│ ├─ score_application() keyword match → score % │
│ ├─ asyncio.gather( │
│ │ rewrite_bullets() LLM: tailor resume bullets │
│ │ generate_outreach() LLM: cold email │
│ │ generate_interview()LLM: Q&A pairs │
│ │ ) │
│ ├─ build_pdf() HTML → PDF bytes │
│ └─ Supabase insert + Storage upload │
│ │
│ GET /jobs/discover → Apify Google Search API │
│ GET /history → Supabase query │
│ GET /resume/{id} → Supabase Storage download │
│ PUT /settings/llm → .env hot-reload │
└─────────────────────┬────────────────────────────────────┘
│
┌────────────┴─────────────┐
▼ ▼
┌──────────────┐ ┌──────────────────┐
│ Supabase DB │ │ Supabase Storage │
│ applications │ │ resumes bucket │
│ table │ │ *.pdf files │
└──────────────┘ └──────────────────┘
- Python 3.11+
- Node.js 18+
- A Supabase project (free tier works)
- At least one LLM API key — Groq is free and recommended
Run backend/supabase_schema.sql in your Supabase SQL Editor to create the applications table and resumes storage bucket.
cd backend
pip install -r requirements.txt
# copy and fill in your keys
cp .env.example .env
uvicorn app.main:app --host 0.0.0.0 --port 8000Required .env keys:
LLM_PROVIDER=groq
GROQ_API_KEY=your_groq_key
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_KEY=your_anon_key
# Optional
APIFY_API_KEY=your_key # for job discovery
REDIS_URL=redis://localhost:6379 # for analysis cachingcd frontend
npm install
npm run devOpen http://localhost:5173
Edit backend/candidate_profile.yml with your real experience, skills, education, and projects. This is the single source of truth the AI uses to score and tailor your resume.
| Method | Endpoint | Description |
|---|---|---|
POST |
/analyze/stream |
Streaming JD analysis (SSE) |
POST |
/analyze |
Standard JD analysis |
POST |
/scrape-jd |
Scrape job description from a URL |
GET |
/history |
Paginated application history |
GET |
/history/{id} |
Single application detail |
PATCH |
/history/{id}/status |
Update application status |
DELETE |
/history/{id} |
Delete application |
GET |
/resume/{id}/pdf |
Download PDF from Supabase Storage |
POST |
/resume/{id}/regenerate |
Regenerate PDF with edited bullets |
GET |
/jobs/discover |
Discover relevant jobs via Apify |
GET |
/profile |
Get candidate profile |
PUT |
/profile |
Update candidate profile |
GET |
/settings/llm |
Get current LLM provider + model |
PUT |
/settings/llm |
Switch LLM provider / model / key |
GET |
/settings/llm/usage |
Token usage per model |
GET |
/health |
Health check |
job-copilot/
├── backend/
│ ├── app/
│ │ ├── routers/
│ │ │ ├── analyze.py # Streaming + standard analysis
│ │ │ ├── history.py # Application CRUD
│ │ │ ├── resume.py # PDF via Supabase Storage
│ │ │ ├── settings.py # LLM config + token usage
│ │ │ ├── profile.py # Candidate profile CRUD
│ │ │ └── jobs.py # Job discovery (Apify)
│ │ ├── services/
│ │ │ ├── jd_parser.py # LLM JD extraction
│ │ │ ├── scorer.py # Skill match scoring
│ │ │ ├── bullet_rewriter.py # LangChain bullet tailoring
│ │ │ ├── outreach.py # Cold email generation
│ │ │ ├── interview.py # Interview Q&A generation
│ │ │ ├── pdf_generator.py # HTML → PDF (xhtml2pdf)
│ │ │ ├── scraper.py # JD URL scraper
│ │ │ └── llm_provider.py # Multi-provider LLM factory
│ │ ├── database.py # Supabase client singleton
│ │ ├── config.py # pydantic-settings
│ │ └── main.py # App entry point
│ ├── candidate_profile.yml # Your resume source of truth
│ ├── supabase_schema.sql # DB + Storage setup SQL
│ └── requirements.txt
├── frontend/
│ └── src/
│ ├── components/
│ │ ├── JDInput.tsx # URL/paste input + scraper
│ │ ├── MatchScoreBar.tsx # Score + tokens display
│ │ ├── SkillsBreakdown.tsx # Matched/missing skills
│ │ ├── BulletEditor.tsx # Inline bullet editing
│ │ ├── InterviewPrep.tsx # Q&A accordion
│ │ ├── OutreachCard.tsx # Cold email + copy
│ │ ├── Dashboard.tsx # Kanban board (dnd-kit)
│ │ ├── ApplicationsTable.tsx # Sortable data table
│ │ ├── FindJobs.tsx # Job discovery grid
│ │ ├── ProfileEditor.tsx # Profile UI
│ │ └── ModelSettings.tsx # LLM switcher + token stats
│ ├── hooks/useAnalyze.ts # All React Query hooks
│ └── App.tsx # Sidebar nav + routing
└── README.md
| Manual Pain | What Job Copilot Automates |
|---|---|
| Rewriting resume for every application | Rewrites all bullets to mirror JD keywords in seconds |
| Guessing which skills to highlight | Exact match % with missing/matched skill breakdown |
| Writing cold emails from scratch | Generates personalised recruiter email per role |
| Preparing for interviews blind | Targeted technical + behavioural Q&A per JD |
| Tracking applications in spreadsheets | Kanban + sortable table, all in one cloud-backed UI |
| Finding relevant jobs manually | Auto-discovers jobs from the web based on your profile |
| Locked into one expensive AI provider | Switch between 5 providers including free local Ollama |
MIT