Job Application Automation Stack
Automate the most repetitive part of job hunting — tailoring your resume and cover letter for every posting — with a self-hosted n8n workflow and an LLM.
BUILD PROMPT
Paste into Claude, ChatGPT, or Cursor to start building.
Stack Components
| Tool / Service | Type | Role | Verdict |
|---|---|---|---|
| [HeadlessX](https://github.com/saifyxpro/HeadlessX) ★ 958 | Dev Tool | Scrapes job postings into clean markdown | [SOLID](https://repoverifier.dev/reviews/saifyxpro-headlessx) |
| [n8n](https://github.com/n8n-io/n8n) ★ 52.0k | Dev Tool | Orchestrates the entire pipeline end to end | [SOLID](https://repoverifier.dev/reviews/n8n-io-n8n) |
| pdfplumber | Service | Extracts text from your resume PDF | |
| OpenAI GPT-4o-mini | Service | Tailors resume and cover letter honestly per role | |
| weasyprint | Service | Renders tailored documents as PDFs | |
| Resend | Service | Delivers finished PDFs by email | |
*Established services are not reviewed under RepoVerifier Standard v1.0. Used and recommended based on personal experience.*
Proof it works
Built with this exact stack: [github.com/devopsballog25-pixel/apply-pilot](https://github.com/devopsballog25-pixel/apply-pilot)
AI-Executable Build Brief
You are helping a developer set up apply-pilot — an automated job application pipeline that takes a job posting URL and a resume PDF and delivers a tailored resume and cover letter by email. Follow this brief exactly.
What you are building
A self-hosted job application pipeline with:
- HeadlessX on your host machine — scrapes any job posting URL into clean markdown
- resume-parser Docker service — extracts text from your uploaded resume PDF using pdfplumber
- pdf-renderer Docker service — renders HTML documents to PDF using weasyprint
- n8n Docker service — orchestrates the full workflow: form → scrape → parse → LLM → render → email
- OpenAI GPT-4o-mini — rewrites your resume and generates a cover letter for the specific role, using only your real experience
- Resend — delivers both PDFs to your inbox
Prerequisites (install before starting)
1. Docker and Docker Compose
2. Node.js (for HeadlessX CLI)
3. OpenAI API key — get one at https://platform.openai.com/account/api-keys
4. Resend account with a verified sending domain — https://resend.com
Step 1 — Clone the repo
git clone https://github.com/devopsballog25-pixel/apply-pilot
cd apply-pilot
Step 2 — Install and start HeadlessX
HeadlessX runs on your host machine, not inside Docker. Open a dedicated terminal and keep it running throughout.
npm install -g headlessx
headlessx init
# Choose: self-host
# Start with Docker: Yes
headlessx start
# API server now running at http://127.0.0.1:38473
# Dashboard at http://localhost:34872
The API key lives at ~/.headlessx/repo/infra/docker/.env under DASHBOARD_INTERNAL_API_KEY — the CLI does not surface it directly.
Step 3 — Configure environment
cp .env.example .env
Edit .env and set:
OPENAI_API_KEY=your-key-here
Step 4 — Start Docker services
docker-compose up -d
This starts three services:
resume-parseron port 5001 — pdfplumber-based PDF text extractorpdf-rendereron port 5002 — weasyprint-based HTML to PDF renderern8non port 5678 — workflow orchestrator
Verify all three are running:
docker-compose ps
# All three should show status: Up
curl http://localhost:5001/health
curl http://localhost:5002/health
Step 5 — Import the n8n workflow
1. Open n8n at http://localhost:5678
2. Click Workflows → Import from File
3. Select n8n/workflows/apply-pilot-workflow.json
Step 6 — Edit your contact details
The imported workflow has placeholder credentials. You must update them before running:
1. Open the imported workflow in n8n
2. Find the Code node (the one that builds the OpenAI request body)
3. Locate these two lines:
const candidateEmail = "[email protected]";
const candidatePhone = "(555) 123-4567";
4. Replace with your real email and phone number
5. Click Save on the node
6. Click Save on the workflow (top right)
No restart needed — n8n applies changes immediately.
Step 7 — Configure Resend credential in n8n
1. In n8n, go to Settings → Credentials
2. Add a new SMTP credential:
- Host: smtp.resend.com
- Port: 465
- Username: resend
- Password: your Resend API key
3. In the Send Email node, set From to [email protected] (your verified Resend domain)
Step 8 — Run it
Open the apply-pilot form at http://localhost:5678, paste a job posting URL, upload your resume PDF, enter your email, and submit.
Check your inbox — you will receive two PDFs within ~60 seconds:
tailored_resume.pdf— your resume rewritten for that specific rolecover_letter.pdf— a cover letter tailored to that company and position
Verify it works
- [ ] Workflow imported without errors in the n8n UI
- [ ] Code node shows your real email and phone after editing
- [ ] All three Docker services show Up in
docker-compose ps - [ ] HeadlessX terminal shows activity when form is submitted
- [ ] Email received with both PDFs attached
Environment variables
OPENAI_API_KEY=your-openai-api-key
Architecture
Form (Job URL + Resume PDF + Email)
├── HeadlessX (host) — scrapes job posting → clean markdown
└── resume-parser (Docker :5001) — extracts resume text via pdfplumber
↓ (both merged in n8n)
GPT-4o-mini — tailors resume + cover letter (honest rewrite only)
↓
pdf-renderer (Docker :5002) — renders both documents as PDFs via weasyprint
↓
Resend — emails tailored_resume.pdf + cover_letter.pdf to candidate
Known gotchas
- HeadlessX must be running on the host before submitting the form — n8n reaches it via
http://host.docker.internal:38473, notlocalhost - The HeadlessX API key is at
~/.headlessx/repo/infra/docker/.envunderDASHBOARD_INTERNAL_API_KEY— the CLI does not surface it directly - pdfplumber may miss resume content in headers or sidebars — inject your real contact details directly into the Code node rather than relying on PDF extraction
- weasyprint must be pinned to version 52.0 — v60.0 has a pydyf incompatibility that breaks PDF rendering
- Do not re-export your live n8n workflow back to
n8n/workflows/apply-pilot-workflow.json— that file is the public template with placeholder credentials; keep your live workflow separate
Proof this works
apply-pilot was built and tested using exactly this stack. Full pipeline confirmed working end-to-end — job URL in, two tailored PDFs delivered by email within 60 seconds. Live at https://github.com/devopsballog25-pixel/apply-pilot
Architecture
Dev Tools
Infrastructure
- pdfplumber — Extracts text from uploaded resume PDF
- OpenAI GPT-4o-mini — Tailors resume and cover letter honestly per role
- weasyprint — Renders tailored documents as PDFs
- Resend — Delivers finished PDFs by email
Stack Components
| Tool / Service | Type | Role | Verdict |
|---|---|---|---|
| HeadlessX★ 958 | Dev Tool | Scrapes job postings into clean markdown | SOLID |
| n8n★ 52.0k | Dev Tool | Orchestrates the entire pipeline end to end | SOLID |
| pdfplumber★ 7.0k | Service | Extracts text from uploaded resume PDF | |
| OpenAI GPT-4o-mini | Service | Tailors resume and cover letter honestly per role | |
| weasyprint★ 7.0k | Service | Renders tailored documents as PDFs | |
| Resend | Service | Delivers finished PDFs by email |
Proof it works
Built with this exact stack: apply-pilot — built and tested end-to-end. Job URL in, two tailored PDFs by email in under 60 seconds.