Objective
- Remove manual resume screening by letting an LLM extract a structured candidate profile from raw resume text.
- Automatically pull currently open, relevant remote jobs for that candidate instead of relying on a static job database.
- Score how well each job fits the candidate using LLM reasoning, with a short human-readable justification.
- Only surface strong matches to recruiters, keeping the output sheet clean and actionable.
Tech Stack
- Orchestration : n8n (visual workflow automation)
- Trigger : Webhook (POST /resume-matcher)
- LLM Provider : Groq API - llama-3.3-70b-versatile
- Job Source : Remotive public remote-jobs API
- Data Transform : n8n Code nodes (JavaScript)
- Output : Google Sheets API (append rows)
Workflow - Step by Step
Webhook Trigger → PDF Text Extraction → Resume Parsing (LLM) → Fetch Matching Jobs → Attach Candidate Profile → Loop Over Jobs → Score Each Match (LLM) → Re-attach Job/Profile Data → Filter by Score → Log to Google Sheets
- Webhook – Receive Resume : A POST endpoint (`/resume-matcher`) accepts an uploaded resume file and triggers the entire workflow.
- Extract Text From PDF : Extracts raw text content from the uploaded resume PDF so it can be sent to the LLM as plain text.
- Groq – Parse Resume : Sends the resume text to Groq's llama-3.3-70b-versatile model with a strict system prompt instructing it to return only JSON matching a fixed schema: name, target_role, years_experience, skills, and domains. Temperature is set low (0.2) and the response is forced into JSON mode for consistent, parseable output.
- Parse Candidate Profile (Code node) : Parses the JSON string returned inside the LLM's response into a clean, usable object for the rest of the workflow.
- Fetch Jobs – Remotive API : Queries the public Remotive remote-jobs API using the candidate's target role to pull currently open, relevant listings.
- Prep Job List + Attach Profile (Code node) : Strips HTML tags from job descriptions, truncates them to a manageable length, takes a batch of listings, and pairs each job with the candidate's parsed profile so both travel together through the rest of the workflow.
- Loop Over Jobs (Split In Batches) : Iterates over the job list one item at a time so each job can be scored individually rather than in one large, unwieldy prompt.
- Groq – Score Match : For each job, sends the candidate profile and job description to Groq with a scoring prompt that returns a JSON object containing a 0–100 score and a reason of no more than 25 words. Temperature is set slightly higher (0.3) for more natural reasoning, still forced into JSON mode.
- Attach Score to Job (Code node) : n8n's HTTP node replaces an item's data with the raw API response, which would normally lose the original candidate/job context. This step re-attaches that original data alongside the parsed score and reason - a workaround for a common n8n data-loss gotcha.
- Filter – Score Threshold : Keeps only matches that clear the configured score cutoff, so only genuinely relevant matches move forward.
- Google Sheets – Log Match : Appends each qualifying match - candidate name, job title, company, score, reason, and application link - as a new row in a shared Google Sheet, then loops back to process the next job in the batch.
Key Design Points
- Two separate LLM calls with different temperatures - a low-temperature (0.2) call for structured resume parsing, and a slightly higher (0.3) call for job-fit scoring - both forced into strict JSON mode to keep the pipeline deterministic and machine-parsable.
- The batch loop scores jobs individually instead of in one large prompt, keeping each LLM call's context small and each score independently justified.
- A dedicated "rehydration" code step re-attaches original candidate/job context after each HTTP call, directly solving n8n's item-overwrite behavior.
- Filtering happens before logging, so the recruiter-facing sheet only ever contains matches worth reviewing.
Challenge
- Recruiters manually reading through resumes and cross-checking them against dozens of live remote-job boards is slow, inconsistent, and doesn't scale. There was no low-code way to combine LLM reasoning with live job-market data in a single automated, auditable pipeline that a non-engineer could still operate and modify.
- Complexity & Innovation
- Dual-temperature LLM design - a low-temperature (0.2) call forces deterministic structured resume parsing, while a separate, slightly higher-temperature (0.3) call produces more natural, human-readable match justifications.
- Per-job scoring loop instead of batch prompting - each job is scored independently against the candidate profile, avoiding context dilution and keeping every score individually explainable.
- Data-loss workaround - a dedicated 'rehydration' code node solves a common n8n gotcha where HTTP nodes silently overwrite upstream item data, re-attaching candidate and job context after every API call.
- Fully low-code orchestration - the entire multi-stage pipeline (parsing, live job retrieval, scoring, filtering, logging) runs inside n8n with no dedicated backend service to deploy or maintain.
Process
- Defined the webhook contract - a single POST endpoint accepting a resume file upload to trigger the workflow.
- Built PDF text extraction to normalize any uploaded resume into plain text for LLM consumption.
- Designed the resume-parsing prompt with a strict JSON schema and low temperature for reliability.
- Integrated the Remotive public API to pull live, relevant remote job listings by target role.
- Built the batch-loop scoring stage, sending one job + profile pair at a time to Groq for a 0-100 fit score and reason.
- Added the rehydration code step to fix n8n's item-context loss after HTTP calls.
- Applied a configurable score-threshold filter before logging.
- Connected Google Sheets as the final, recruiter-facing output layer.
Complexity & Innovation
- Dual-temperature LLM design - a low-temperature (0.2) call forces deterministic structured resume parsing, while a separate, slightly higher-temperature (0.3) call produces more natural, human-readable match justifications.
- Per-job scoring loop instead of batch prompting - each job is scored independently against the candidate profile, avoiding context dilution and keeping every score individually explainable.
- Data-loss workaround - a dedicated 'rehydration' code node solves a common n8n gotcha where HTTP nodes silently overwrite upstream item data, re-attaching candidate and job context after every API call.
- Fully low-code orchestration - the entire multi-stage pipeline (parsing, live job retrieval, scoring, filtering, logging) runs inside n8n with no dedicated backend service to deploy or maintain.
Feature Inventory
- Webhook-triggered resume upload
- PDF-to-text extraction
- LLM resume parsing to structured JSON (name, role, experience, skills, domains)
- Live remote job retrieval via Remotive API
- Per-job LLM fit scoring (0-100) with short justification
- Context-rehydration workaround for n8n HTTP data loss
- Configurable score-threshold filtering
- Automated logging to Google Sheets with job title, company, score, reason, and link
Outcome
A complete, low-code resume-screening pipeline - from raw resume upload to a scored, filtered shortlist of live job openings in a spreadsheet - built entirely on n8n, with LLM reasoning doing the two jobs a recruiter would otherwise do manually: understanding the resume, and judging the fit.