Home Blog 🔍 n8n Job Search 💼 LinkedIn Automation 📄 AI Resume Tailor 📊 Make.com Tracker 🔔 Zapier Job Alerts 🤖 AI Agents Guide 🛠️ Best AI Tools 💬 ChatGPT Tips 📊 n8n Guide 🎯 Prompts 🔗 LangChain
n8n GPT-4 ATS Optimizer

AI Resume Tailor: Auto-Customize Your Resume for Any Job

Build an 8-step n8n workflow that analyzes any job description, rewrites your resume bullet points to match, and optimizes for ATS keyword scoring — all on demand in under 60 seconds.

👤 Akash 📅 February 20, 2025 ⏱ 12 min read 🔄 Updated 2025

Most job seekers send the same generic resume to every application. Recruiters can tell immediately — and so can ATS systems, which quietly reject resumes that don't match the job description's exact keyword patterns. The fix is tailoring your resume for each role, but who has time to rewrite bullet points for every application?

This n8n workflow automates the entire tailoring process. You paste in a job description (or send it via webhook), and within a minute you get back a GPT-4-rewritten version of your resume with matched keywords, rephrased bullet points that mirror the job's language, a gap analysis, and an ATS score estimate. No more manual rewriting — just review, approve, and apply.

⚡ What You'll Build

  • ✅ On-demand resume tailoring triggered by webhook or manual run
  • ✅ Automatic job description parsing and requirements extraction
  • ✅ GPT-4 gap analysis: what you have vs. what the job needs
  • ✅ Intelligent bullet point rewriter matching the job's language
  • ✅ ATS keyword injection and skills section optimization
  • ✅ Tailored resume saved to Google Drive + emailed to you

Prerequisites

You'll need these accounts before building. All have free tiers that are more than sufficient for personal use:

  • n8n account: Free cloud at n8n.io or self-hosted
  • OpenAI API key: From platform.openai.com (~$0.05 per resume tailoring run with GPT-4o)
  • Google Drive + Gmail: For storing your base resume and emailing results
  • Your resume as a PDF: Uploaded to Google Drive with text-based (not scanned) content

How the Workflow Works

The workflow is triggered on demand — either manually in n8n or via a webhook you can call from a browser bookmark or Zapier. Here's the 8-step pipeline:

  1. Webhook / Manual Trigger → receives the job description text
  2. Job Description Parser → extracts structured requirements from raw text
  3. Resume Download → fetches your base resume PDF from Google Drive
  4. PDF Text Extractor → converts PDF binary to plain text
  5. AI Gap Analyzer → GPT-4 identifies missing keywords and experience gaps
  6. AI Resume Rewriter → GPT-4 rewrites bullet points to match job language
  7. ATS Keyword Optimizer → injects missing keywords into skills/summary sections
  8. Save & Email → saves tailored resume to Drive and emails it to you

Step-by-Step Workflow Setup

Open your n8n workspace and create a new workflow named "AI Resume Tailor." Add each node below in sequence.

Step 1: Webhook Trigger

1

🔗 Webhook Node — Receive Job Description

Creates an HTTP endpoint you can call from anywhere — a browser extension, Zapier, or a simple curl command — to kick off the tailoring process with a job description payload.

Add a Webhook node and configure:

  • HTTP Method: POST
  • Path: tailor-resume
  • Response Mode: Last Node (returns the tailored output)
  • Authentication: Header Auth with a secret token (optional but recommended)

The webhook URL will be: https://your-n8n-instance.com/webhook/tailor-resume. You'll POST a JSON body like {"job_description": "We are looking for a Senior Python Engineer..."} to trigger the workflow. During development, use the Manual Trigger node instead and hardcode a sample job description in a Code node immediately after it.

Pro tip: Create a browser bookmarklet that captures selected text from a job posting page and POSTs it to your webhook URL. One click on any job listing instantly starts the tailoring process.

Step 2: Job Description Parser

2

🔧 Code Node — Parse Job Requirements

Cleans the raw job description text and prepares it for the AI nodes. Handles common formatting issues like extra whitespace, HTML artifacts, and emoji characters that could confuse the language model.

const rawJD = $input.first().json.body?.job_description
  || $input.first().json.job_description
  || '';

// Clean up the text
const cleaned = rawJD
  .replace(/&/g, '&')
  .replace(/</g, '<')
  .replace(/>/g, '>')
  .replace(/\s{3,}/g, '\n\n')
  .trim();

if (!cleaned || cleaned.length < 50) {
  throw new Error('Job description too short or missing. Please provide at least 50 characters.');
}

return [{ json: {
  job_description: cleaned,
  jd_length: cleaned.length,
  timestamp: new Date().toISOString()
}}];

Step 3: Resume Download from Google Drive

3

📥 Google Drive Node — Fetch Base Resume

Downloads your master resume PDF from Google Drive. Using Drive as the source means any manual updates you make to your resume are instantly picked up on the next run — no workflow changes needed.

Add a Google Drive node:

  • Operation: Download File
  • File ID: The ID from your resume's Google Drive URL
  • Credentials: OAuth2 (connect your Google account)

Keep a single "master resume" in Drive — your most complete, unedited version with all experience. This workflow always tailors a fresh copy of the master, so you never accidentally overwrite your original.

Step 4: PDF Text Extraction

4

📄 Extract from File Node — PDF to Text

Converts the binary PDF data into plain text that the AI can read and analyze. The quality of this extraction directly affects tailoring quality — a well-formatted PDF produces much better results.

Add an Extract from File node:

  • Operation: Extract Text from PDF
  • Binary Property: data

After extracting, the output JSON will have a text field with your full resume content. Verify the extraction preserves your formatting reasonably well — section headers, job titles, dates, and bullet points should all be readable. If your PDF was created from a scanned document, the text will be garbled; re-export from Word/Google Docs to create a proper text-based PDF.

Step 5: AI Gap Analysis

5

🤖 OpenAI Node — Gap Analyzer

The first AI pass. GPT-4 reads both your resume and the job description, then produces a structured gap analysis: which required skills you already demonstrate, which are missing, which experiences should be emphasized, and what the ATS keyword density looks like.

Add an OpenAI node:

  • Model: gpt-4o (faster and cheaper than gpt-4-turbo, same quality for this task)
  • Max Tokens: 1000
  • Temperature: 0.2 (analytical, consistent output)

System prompt:

You are an expert resume analyst and ATS optimization specialist. Your job is to analyze a candidate's resume against a job description and produce a detailed gap analysis. Return ONLY valid JSON in this exact format: { "match_score": 72, "present_keywords": ["Python", "REST APIs", "PostgreSQL", "Agile"], "missing_keywords": ["Kubernetes", "Terraform", "AWS Lambda", "CI/CD"], "weak_sections": ["Summary statement too generic", "Skills section missing cloud tools"], "strong_sections": ["4 years Python experience clearly shown", "Open source contributions listed"], "bullets_to_rewrite": [ { "original": "Worked on backend systems", "reason": "Too vague — job requires specific Python microservices experience" } ], "recommended_emphasis": ["FastAPI projects", "database performance work", "any AWS or GCP usage"], "ats_risk": "medium" }

User message:

RESUME: ={{ $('Extract from File').first().json.text }} JOB DESCRIPTION: ={{ $('Job Description Parser').first().json.job_description }} Analyze the match and return JSON only.

Step 6: AI Resume Rewriter

6

✍️ OpenAI Node — Resume Rewriter

The core transformation step. GPT-4 rewrites your resume using the gap analysis from Step 5 as instructions. It preserves all factual information while rephrasing bullet points to mirror the job description's language and emphasizing the most relevant experiences.

Add a Code node first to parse the gap analysis JSON, then another OpenAI node:

// Parse gap analysis from previous node
const raw = $input.first().json.message?.content || $input.first().json.choices?.[0]?.message?.content || '';
let gap;
try {
  gap = JSON.parse(raw);
} catch(e) {
  // If JSON parse fails, extract what we can
  gap = { missing_keywords: [], bullets_to_rewrite: [], recommended_emphasis: [] };
}
return [{ json: { gap_analysis: gap, raw_gap: raw } }];

Then add the Rewriter OpenAI node:

  • Model: gpt-4o
  • Max Tokens: 3000
  • Temperature: 0.4
You are an expert resume writer. Rewrite the provided resume to better match the job description. STRICT RULES: 1. Never fabricate experience, skills, or achievements — only rephrase and reframe what already exists 2. Mirror the exact terminology from the job description where your experience matches 3. Rewrite vague bullet points to be specific and quantified where possible 4. Move the most relevant experience to the top of each role's bullet list 5. Update the professional summary/objective to target this specific role 6. Keep the same overall structure (sections, companies, dates, roles) 7. Output the complete rewritten resume as plain text, ready to paste into a document GAP ANALYSIS (use this as your rewrite instructions): ={{ $json.gap_analysis }} ORIGINAL RESUME: ={{ $('Extract from File').first().json.text }} JOB DESCRIPTION: ={{ $('Job Description Parser').first().json.job_description }} Rewrite the full resume now. Output plain text only — no markdown, no commentary.

Step 7: ATS Keyword Optimizer

7

🎯 OpenAI Node — ATS Keyword Finalizer

A targeted final pass that focuses solely on the skills section and technical keywords. Ensures all missing high-priority keywords from the gap analysis are present in the resume — particularly in the skills section, which ATS systems parse with highest weight.

Review this rewritten resume and the list of missing keywords. Your ONLY task is to check the Skills/Technical Skills section and add any missing keywords that are genuinely applicable to the candidate based on their experience. REWRITTEN RESUME: ={{ $('Rewriter OpenAI').first().json.message.content }} MISSING KEYWORDS FROM GAP ANALYSIS: ={{ $('Parse Gap Analysis').first().json.gap_analysis.missing_keywords.join(', ') }} Rules: - Only add keywords the candidate could plausibly have given their experience level and field - Do NOT add keywords for tools or technologies not mentioned anywhere in their history - Add applicable keywords to the Skills section in logical groupings - Return the COMPLETE final resume with any keyword additions — no commentary, no headers, just the resume text

Step 8: Save to Drive & Email

8

📧 Gmail + Google Drive — Deliver Results

Saves the tailored resume text to a new Google Drive file and emails you both the tailored content and the gap analysis summary. You get everything you need to apply in your inbox within 60 seconds of triggering the workflow.

Add a Code node to build the email HTML, then a Gmail node:

const tailoredResume = $('ATS Optimizer').first().json.message.content;
const gap = $('Parse Gap Analysis').first().json.gap_analysis;
const jobDesc = $('Job Description Parser').first().json.job_description.slice(0, 200);

const html = `
<h2>Your Tailored Resume is Ready</h2>
<p><strong>Job Snippet:</strong> ${jobDesc}...</p>
<p><strong>Match Score:</strong> ${gap.match_score || 'N/A'}% → optimized with tailoring</p>
<p><strong>ATS Risk:</strong> ${gap.ats_risk || 'N/A'}</p>
<p><strong>Keywords Added:</strong> ${(gap.missing_keywords || []).slice(0,8).join(', ')}</p>
<hr>
<h3>Tailored Resume (plain text — paste into your template)</h3>
<pre style="white-space:pre-wrap;font-family:monospace;background:#f5f5f5;padding:20px;border-radius:8px;">
${tailoredResume.replace(/</g, '&lt;').replace(/>/g, '&gt;')}
</pre>
`;

return [{ json: { email_html: html, tailored_resume: tailoredResume } }];

Configure the Gmail node:

  • Operation: Send Email
  • To: your email address
  • Subject: 📄 Tailored Resume Ready — {{ new Date().toLocaleDateString() }}
  • Email Type: HTML
  • HTML Body: ={{ $json.email_html }}

Tips & Customizations

Use gpt-4o-mini to cut costs

If you're tailoring many resumes per week, swap gpt-4o for gpt-4o-mini on the gap analysis and ATS optimizer steps. Keep gpt-4o only for the rewriter step. This reduces per-run costs from ~$0.08 to ~$0.02 while maintaining most of the quality where it matters most.

Add a Google Docs output

Instead of (or in addition to) emailing plain text, use the Google Docs node to create a new document with the tailored resume content. This makes formatting and final touch-ups much easier than working with a plain text email.

Build a version history

Add a Google Sheets node that appends each tailoring run: date, company name (extracted from the JD with regex), match score before/after, and a Drive link to the tailored resume. Over time, this shows which roles you're targeting most and how your resume evolves.

Create a browser extension trigger

With n8n's webhook URL, you can build a simple browser extension that extracts the full text of any job posting page and sends it to your workflow in one click. The Chrome Extensions documentation has a minimal boilerplate for content scripts that can select and POST page text.

Frequently Asked Questions

Does this change the facts on my resume? +
No — the system prompt explicitly instructs GPT-4 to never fabricate experience, skills, or achievements. It only rephrases and reframes what already exists in your resume. The rewriter mirrors the job description's language while keeping all facts intact. We strongly recommend reviewing the output before submitting any application — treat it as a first draft, not a final product.
How much does it cost to run? +
Using gpt-4o, each tailoring run costs approximately $0.05–0.10 depending on resume and job description length. With gpt-4o-mini for the analysis steps (and gpt-4o only for rewriting), you can cut this to under $0.03 per run. Tailoring 20 resumes a month costs less than $2 in API fees — significantly cheaper than any premium resume service.
What if the PDF extraction produces garbled text? +
This happens with scanned PDFs or files with complex formatting. The fix is to open your resume in Google Docs (which does its own OCR) or re-export it from Microsoft Word as a standard PDF. Ensure your resume is saved as a text-based PDF, not a printed/scanned image. Alternatively, store your resume as a plain text (.txt) file in Drive and skip the PDF extraction step entirely.
Can I use this for cover letters too? +
Absolutely — add a 9th node after the ATS optimizer that generates a tailored cover letter using the same gap analysis and rewritten resume as context. Check out our n8n Job Search Automation guide for a complete cover letter generation prompt you can drop right in.
How do I trigger this from my phone? +
Use an iOS Shortcut or Android Tasker script that copies text to clipboard and POSTs it to your webhook URL. On iOS, the "Get Contents of URL" Shortcut action can send a POST request directly. Set up a Share Sheet shortcut so you can trigger resume tailoring from any job posting app by tapping "Share → Tailor Resume."