How I screen job applicants automatically with n8n

The short version

To screen applicants automatically with n8n, POST each application to a webhook, load your job criteria in a Set node, and have a scoring step rate the resume against those must-haves. Every candidate gets logged to a sheet for a human, and a daily schedule sends HR the top three on Slack. Nobody is auto-rejected.

I built this because screening the first pass of a hiring pipeline by hand is slow and uneven, and I did not want a bot quietly turning people away. This is a real template I run. Here is the whole thing: why it matters, the usual ways teams do it, how mine works, and how to point it at your own role and tools.

The problem

The first pass of hiring is the slowest, and it is the one most people do by reading every resume by hand.

A single open role can pull in dozens of applications a day. Someone has to open each one, decide if it clears the bar, and remember why. By the tenth resume the standard has already drifted, and the last few rarely get the same attention as the first. It eats hours you do not have, two people score the same person differently, and good candidates slip through on a tired afternoon. What you want is a fast, even first read that still leaves the real decision to a person.

The volume is the real problem. In a 2024 ResumeGo survey of 418 hiring pros, 47 percent said they spend just 30 to 60 seconds on a resume, so strong applicants slip through when the pile grows.

How most teams deal with it today

There are three common ways to screen the first pass. Each has a catch.

Read every resume by hand

The most common way, and it feels the fairest. But it is slow, and the bar drifts as you tire. Two reviewers score the same person differently, and the resumes at the bottom of the pile never get the read the top ones did.

Keyword filters in an ATS

Your applicant tracking system can flag resumes that contain certain words. It is fast, but it matches words and not meaning, so a strong person who phrased things differently gets dropped, and anyone who stuffs the right keywords floats to the top.

A paid screening tool

Dedicated screeners will rank applicants for you. They work, but they bill every month, the scoring often happens in a box you cannot see into, and some of them auto-reject, which is the exact thing you wanted a human to keep control of.

The fix

You own it, it costs almost nothing to run, and it keeps a person on every final call.

A single n8n flow does the first read for you. The moment an application arrives it scores the resume against your criteria, writes the score and the reasoning to a sheet, and moves on. Once a day it hands HR the three strongest from that day on Slack. Nobody is thrown out. Here is what it does, in three parts.

Scores every application on arrival

A webhook takes the application, a Set node holds the job criteria, and the scoring step rates the resume against those must-haves. It returns a score, a recommendation, strengths, gaps and a plain summary, so the reasoning is on the record and not hidden in a box.

Logs everyone, rejects nobody

Every candidate is appended to a Google Sheets tab with their score and rationale. The workflow never rejects anyone. It only ranks and explains, which keeps a human in the loop and gives you a full record of who applied and how they scored.

Sends HR a daily Top 3

On weekday mornings a schedule reads the day's scored candidates, sorts by score, and posts the top three to HR on Slack with each name, score and summary. Everyone below the cut stays in the sheet for review rather than disappearing.

Loading workflow…
Free download

Want this running for you?

Take the file and set it up yourself, or book a free call and we wire it into your form, your sheet and your Slack for you.

Get your free audit

Build it step by step

Every real node, in the order the data flows. There are two branches: the per-application branch off the webhook, and the daily digest branch off the schedule.

  1. 1
    Application In · Webhook

    Takes each new application as it arrives.

    Set it up: Add a Webhook node set to POST on the path /application, with response mode set to respond from a later node. It expects name, email and resumeText in the body.

  2. 2
    Job Criteria · Set

    Holds what the role needs, so the score has something to judge against.

    Set it up: Add a Set node with two fields: jobTitle, and a criteria string listing must-haves and nice-to-haves in plain text. This one node is what you edit to re-tune the whole screen to a new role.

  3. 3
    Claude: Screen · HTTP Request

    Reads the resume against the criteria and scores it.

    Set it up: Add an HTTP Request to the Anthropic messages API. Pass your ANTHROPIC_API_KEY in the x-api-key header, and send the job title, criteria and resume in the body. Ask it back for a fixed shape: a score, a recommendation of advance or review, strengths, gaps and a summary. It is told to rank and explain, never to reject.

  4. 4
    Shape Row · Code

    Turns the scoring output into one flat row.

    Set it up: Add a Code node. Read the scored JSON, pull the name and email from the original application, and return one object with date, name, email, score, recommendation, strengths, gaps and summary. Join the strengths and gaps lists into readable text.

  5. 5
    Log Candidate (everyone) · Google Sheets (append)

    Writes every applicant to the sheet, no exceptions.

    Set it up: Add a Google Sheets node set to Append, pointed at your document and a tab called Candidates. Let it auto-map the row from the last step. This runs for everyone, which is what keeps the full record.

  6. 6
    ACK · Respond to Webhook

    Answers whatever posted the application.

    Set it up: Add a Respond to Webhook node that returns ok, the score and the recommendation as JSON. That closes the request the form or ATS opened.

  7. 7
    Weekdays 8am · Schedule Trigger

    Starts the daily digest branch on a timer.

    Set it up: Add a Schedule Trigger set to the cron 0 8 * * 1-5, so it fires at 8am Monday through Friday. This is the second entry point, separate from the webhook.

  8. 8
    Read Candidates · Google Sheets (read)

    Reads back everyone logged in the sheet.

    Set it up: Add a Google Sheets node set to read, pointed at the same document and Candidates tab as the log node. It pulls every row so the next step can pick out today's.

  9. 9
    Rank Top 3 · Code

    Picks today's three highest scorers and writes the message.

    Set it up: Add a Code node. Keep only rows where the date is today, sort by score high to low, and take the top three. Build a Slack message with each name, score and summary. Return nothing when there were no applicants today, so quiet days send nothing.

  10. 10
    Slack: Top 3 to HR · HTTP Request

    Posts the digest to HR.

    Set it up: Add an HTTP Request set to POST to your SLACK_WEBHOOK_URL environment variable, sending the formatted message as the text field. That drops the shortlist into your HR channel.

What made it tricky?

Three decisions shaped how this behaves. If you rebuild it, these are the places to get right first.

Never auto-rejecting

The whole design keeps a human in the loop. The scoring step is told it is a first-pass screen that ranks and explains but never rejects, and Log Candidate writes everyone to the sheet before any ranking happens. The Top 3 is a convenience for HR, not a gate that throws the rest away.

One clean row per candidate

The scoring step returns structured fields, and the Shape Row Code node flattens them into a single row with strengths and gaps joined into readable text. That is what makes the sheet sortable and the daily ranking simple. Get the shape wrong here and the digest and the record both fall apart.

Today-only ranking

The digest reads the whole sheet, so Rank Top 3 filters to today's date before sorting, otherwise yesterday's strong candidates would keep resurfacing. It sorts by score high to low, takes the top three, and returns nothing when there were no applicants today, so HR only gets a message when there is something to see.

How do I adapt it to my own setup?

Almost everything you change lives in three places. The node graph itself stays exactly as it is.

What you changeWhereWhy
Job title and criteriaJob Criteria (Set) nodeRe-tunes the whole screen to your role. Everything downstream scores against this text.
Sheet document and tabLog Candidate and Read Candidates (Google Sheets) nodesPoints the log and the digest at your own Candidates sheet. Set the same document id on both.
Slack destinationSLACK_WEBHOOK_URL environment variableSends the daily Top 3 to whichever HR channel you want, without editing the node.
Application fieldsPOST body to the webhookThe webhook expects name, email and resumeText. Map your form or ATS to those keys.

Set the ANTHROPIC_API_KEY and SLACK_WEBHOOK_URL environment variables, connect the Google Sheets credential, edit the Job Criteria node, and start POSTing applications at the webhook. Change the Schedule Trigger cron if you want the digest at a different time. If you would rather not touch the API auth yourself, this is exactly the kind of build you can hire an n8n expert to finish. It pairs well with my match candidates to open roles and my auto-match and rank jobs.

Wondering what that costs? See what an n8n expert costs in 2026.

Recruitment screening questions, straight answers.

How do I automatically screen job applicants with n8n?

POST each application to an n8n webhook, hold your role's must-haves in a Set node, and pass the resume to a scoring step that rates it against those criteria and returns a short rationale. A Code node shapes that into a row, logs every candidate to Google Sheets, then a daily schedule posts HR the top three on Slack.

Does this workflow auto-reject anyone?

No, and that is on purpose. The screener only scores and ranks, it never rejects. Every applicant is written to the Candidates sheet with their score, strengths, gaps and a summary, so a human always makes the call. The daily digest surfaces the top three, but everyone else stays visible for review.

What does the screening step actually score against?

The Job Criteria Set node holds the job title and a plain-text criteria string with must-haves and nice-to-haves. The scoring step reads only that, rates the resume evidence against it, and returns a score, a recommendation, strengths, gaps and a summary. Edit the criteria text and the whole screen re-tunes to a new role.

Where do the screened candidates get stored?

Every candidate lands in a Google Sheets tab called Candidates, one row each: date, name, email, score, recommendation, strengths, gaps and summary. The Shape Row Code node builds that row from the scoring output. Because everyone is logged, the sheet is your full record of every applicant, wider than the shortlist HR sees.

How does the daily Top 3 digest work?

A Schedule Trigger runs weekdays at 8am, reads the Candidates sheet, and a Code node keeps only today's rows, sorts them by score, and takes the top three. It formats a Slack message with each name, score and summary, then posts it to HR through a Slack webhook. No candidate today means nothing sends.

Can I use Slack, or does it have to be email?

The template posts to a Slack incoming webhook URL held in an environment variable, so any channel works. To switch to email, swap the final HTTP Request node for an email node and reuse the same formatted message from the Rank Top 3 Code node. The ranking and formatting logic does not change at all.

How do I adapt it to a different role?

Edit the Job Criteria node with the new title and must-haves, point both Google Sheets nodes at your document and tab, and set the ANTHROPIC_API_KEY and SLACK_WEBHOOK_URL environment variables. That is the whole setup. If you would rather not touch the API auth yourself, you can hire an n8n expert to wire it up.

Want this running on your pipeline?

30 minutes, free. Bring your role and your applicant form. You leave with a plan to score every applicant fairly, keep a human in the loop, and hand HR a daily shortlist, whether you build it or we do.

Rather have it built for you?

Skip the build. A free 30-minute call and we set this up in your stack, live in a week or two.