Book an Appointment

AI Resume-to-Job Matching System (n8n Automation)

An end-to-end recruitment automation built entirely as an n8n workflow. A candidate's resume is uploaded through a webhook, parsed and understood by an LLM, matched against live remote job listings, scored for fit by a second LLM call, and - if the match clears a quality bar - logged straight into a shared Google Sheet for a recruiter to review. The workflow was built as an interview/demo automation to show a complete, low-code AI hiring pipeline.

AI Resume-to-Job Matching System (n8n Automation)

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.