217 Applicants, $2.84, 6h/Week Back — n8n Beats monday

Abstract tech illustration: 217 Applicants, $2.84, 6h/Week Back — n8n Beats monday

Eighty applicants land in your careers inbox in 48 hours. Six of them are worth talking to, and they're buried on page three of Gmail. You either hire a coordinator you can't afford or pay $39/user/month for an HR platform that makes your recruiter learn a new tool, migrate a pipeline, and log in somewhere new every morning. Both options are bad. The recruiter still does the reading — you just added a subscription and a login.

Here's the four-node n8n build that replaced that entire "source, screen, schedule" workflow for a client. Real numbers from 30 days of production traffic: 217 applicants processed end-to-end, $2.84 in OpenAI spend, 6.2 hours/week saved. One Gmail account. Zero new SaaS logins for the human.

The real numbers before the build

Thirty days on a live client account, single open role, mid-market SaaS hiring a senior engineer. Traffic came from LinkedIn, Indeed, and a careers page form that forwards to Gmail.

Metric Value
Applicants processed 217
Auto-rejected (C-tier, <50) 141
B-tier (50–69, human review) 61
A-tier (≥70, auto-booked) 15
A-tier → booked calls 11
Booked → second round 4
Hired 1
OpenAI spend, total $2.84
Cost per applicant $0.013
Recruiter hours/month 6.8 (vs ~32 prior)
New SaaS logins for the human 0

Compare that to monday.com Work Management at $39/user/month for the tier that unlocks the automation and integration recipes you'd actually need — for a 3-person hiring pod, that's ~$117/month, plus the recruiter learning a new UI. The n8n stack: self-hosted on a home server, Google Sheets free, Cal.com free, OpenAI usage-based. Total burn under three bucks.

The point isn't that monday is bad software. It's that a founder or two-person ops team doesn't need a platform. They need plumbing.

Node 1: Gmail trigger with a label router (this is 90% of the value)

The single most important node in the workflow doesn't touch AI. It's a Gmail trigger pointed at careers@yourdomain.com with an immediate switch node that sorts inbound mail before a token gets spent.

Three branches:

  • Sender matches a job board (LinkedIn, Indeed, Wellfound, Otta) → label inbound-jobboard
  • Has a PDF/DOCX attachment → label inbound-resume, continue to Node 2
  • Reply to an existing thread → label candidate-reply, short-circuit (do not re-score)

That short-circuit on replies is what stops you from re-processing the same person every time they send a follow-up. In production it killed about a third of the traffic before Node 2 ever ran.

The switch conditions in n8n look like this:

// Branch: is reply
{{ $json.threadId && $json.headers['in-reply-to'] !== undefined }}

// Branch: is job board
{{ /noreply@(linkedin|indeed|wellfound|otta)\.com/i.test($json.from.value[0].address) }}

// Branch: has resume attachment
{{ $json.attachments && $json.attachments.some(a => /\.(pdf|docx)$/i.test(a.filename)) }}

If you skip this node and pipe every inbound email into GPT-4o-mini, your bill triples and your workflow spends most of its time re-scoring the same five candidates who keep replying about scheduling.

Node 2: PDF → text → structured JSON extraction

Node 2 does one job: turn a messy email + resume PDF into clean, typed JSON. This is not where you judge anyone. This is where you normalize.

The pipeline inside the node:

  1. Binary → PDF-to-text (n8n has a built-in Extract from File node; for scanned PDFs, use an OCR fallback)
  2. Concatenate email body + extracted resume text
  3. Send to gpt-4o-mini with a structured extraction prompt and response_format: json_object

The prompt (trimmed):

You extract structured data from job applications.
Return ONLY valid JSON matching this schema:
{
  "name": string,
  "email": string,
  "role_applied_for": string | null,
  "years_experience": number | null,
  "current_title": string | null,
  "location": string | null,
  "key_skills": string[],   // exactly 3
  "red_flags": string[]     // e.g. "no portfolio", "wrong role", "no cover letter"
}
Do not judge the candidate. Do not score. Extract only.

Why gpt-4o-mini? Structured extraction from ~2–4k tokens of resume text is exactly what it's tuned for. Average cost per applicant on this account: $0.013. A gpt-4o upgrade added zero measurable accuracy on extraction and 8x-ed the bill in a side-by-side test on 50 resumes.

The red_flags array is the one field that pays for itself. It's not scoring, it's evidence. "No portfolio link" or "applied to wrong role" surfaces context the scorer in Node 3 uses without hallucinating.

What to watch when this node breaks

  • Scanned PDF resumes (design/creative candidates especially) — Extract from File returns empty text. Route to an OCR node (Tesseract or a cheap Vision call) as fallback.
  • Non-English resumes — extraction is fine but rubric matching in Node 3 needs the rubric written in the same language, or a translate step.
  • Model returns invalid JSON on ~1 in 400 requests — wrap the node in a retry with temperature: 0 and a stricter system prompt.

Node 3: Rubric-based scoring from a Google Sheet

Node 3 is where a human still owns the judgment — they just do it once, in a spreadsheet, per role. One tab per open role. Columns:

Column Example
role_id senior-backend-eng
must_have_skills Python, Postgres, distributed systems
nice_to_have Go, Kafka, k8s
min_years 5
location_constraint US timezones (±3 EST)
disqualifiers No production experience; contract-only
weight_must 60
weight_nice 20
weight_experience 20

The n8n node reads the row matching role_applied_for, hands both the rubric and the extracted JSON to the model, and asks for a score 0–100 plus a two-sentence rationale.

Score this candidate 0-100 against the rubric.
Apply disqualifiers first — if any hit, score = 0.
Otherwise: must_have match × 0.6 + nice_to_have × 0.2 + experience_fit × 0.2.
Return JSON: { "score": number, "rationale": string, "tier": "A"|"B"|"C" }
Tier A: >=70, B: 50-69, C: <50.

Then a simple IF branch labels the Gmail thread:

  • A-tier (≥70) → label A-tier, continue to Node 4
  • B-tier (50–69) → label B-tier, stop (weekly human review)
  • C-tier (<50) → label reject, stop (batch review once a week)

The batch reject review is not optional in weeks 1–2. That's where you catch false negatives and tune the rubric. After roughly 40 rejected candidates reviewed by the recruiter, the rubric stabilized and the reject folder became reliably correct. Ship it, then tune it. Don't try to write a perfect rubric on day one.

Node 4: Parallel handoff — Cal.com, Telegram, tracking sheet

For every A-tier candidate, Node 4 fans out three actions in parallel:

  1. Templated Gmail reply from the recruiter's own address with a Cal.com booking link for a 15-minute intro. The candidate books themselves.
  2. Telegram message to the hiring manager with name, role, score, rationale, and a direct link to the Gmail thread.
  3. Append a row to a tracking Google Sheet — timestamp, candidate, role, score, rationale, thread URL. Audit trail without a CRM.

The Telegram payload is where the hiring manager lives:

🎯 New A-tier candidate — Senior Backend Eng
Sarah Chen · Score 84
Rationale: 7yr Python/Postgres, ex-Stripe infra, 
built payment processing at 12k RPS. No red flags.
📎 Open thread: https://mail.google.com/mail/u/0/#inbox/...
📅 Booking link sent · awaiting confirmation

The recruiter's Gmail address stays on the outbound reply so the candidate experience feels human — because it is. A human wrote the template. AI decided who gets it. That distinction matters for candidate trust and for compliance in jurisdictions where fully automated hiring decisions have disclosure requirements. The EEOC has published guidance on algorithmic hiring tools — worth reading before you ship any scoring system, and worth keeping a human in the loop on final decisions regardless.

What monday (and the rest of the HR SaaS market) won't tell you

Two things.

First, 90% of the value is in Node 1 — the label router, not the AI. Cutting noise before you spend a token is what makes this fast and cheap. A workflow that sends every inbound message straight to GPT-4o would cost 3–4x more and produce identical output. The HR platforms bury this obvious optimization because "rules-based email routing" doesn't sell subscriptions.

Second, the recruiter never learns a new tool. They live in Gmail. A-tier is already handled, B-tier sits in a labeled folder for a Friday afternoon read, C-tier is out of sight. That is the entire UX. No dashboard, no pipeline view, no drag-and-drop kanban. The tool your recruiter already opens 200 times a day is the interface.

Sibling builds worth looking at once this is running: reference-call agents, offer-letter automation, and sentiment-drift monitoring on active candidate threads — all bolt onto the same n8n instance and the same Gmail account.

Where bizflowai.io fits in

bizflowai.io already runs this exact pattern for hiring pods at small SaaS companies and agencies — Gmail-triggered n8n workflows that source, screen, and schedule candidates without introducing a new tool for the human operator. The build above is the shape of what ships: label routing first, cheap structured extraction second, rubric-based scoring third, native-channel handoff fourth. If you'd rather have the plumbing installed on your own n8n instance than assemble it yourself, that's the work.


Want more like this?

I publish practical AI automation, GenAI engineering, and faceless content workflows on YouTube every week.

Subscribe to bizflowai.io on YouTube — never miss a new tutorial.

Planning an AI automation project or need a second opinion on your architecture?

Connect with me on LinkedIn — Lazar Milicevic, GenAI Engineer & bizflowai.io Founder.

Visit bizflowai.io for our services, case studies, and AI consulting.

Frequently asked questions

What is an AI recruiting workflow in n8n?

It's a self-hosted automation that replicates the source, screen, and schedule workflow of major HR platforms using four n8n nodes: a Gmail trigger with label routing, a GPT-4o-mini extraction step, a rubric-based scorer pulling from Google Sheets, and a handoff node that emails candidates, pings hiring managers on Telegram, and logs results. It runs inside Gmail with no new SaaS logins.

How much does an n8n recruiting automation cost to run?

On a live client account processing 217 applicants over 30 days, total OpenAI spend was $2.84, averaging roughly 1.3 cents per applicant. The workflow uses GPT-4o-mini, which is cheap and fast for structured JSON extraction. There are no per-user SaaS fees since it runs on a self-hosted n8n instance and reuses existing Gmail and Telegram accounts.

How do I screen job applicants automatically with GPT-4o-mini?

Pipe the email body and any PDF resume through a PDF-to-text step, then send it to GPT-4o-mini with a structured extraction prompt that returns JSON containing name, email, role, years of experience, current title, location, three key skills, and a red flags array. Then pass that JSON plus a rubric from Google Sheets back to the model for a 0-100 score with a two-sentence rationale.

Why does Gmail label routing matter for applicant tracking?

A label router inside the Gmail trigger tags inbound emails as job-board, resume, or candidate-reply before AI touches them. Replies on existing threads short-circuit the pipeline so already-screened candidates aren't re-scored. This routing alone eliminates about a third of noise, reduces token spend, and prevents duplicate processing—keeping the recruiter's inbox clean without any AI cost.

When should I use a self-hosted n8n workflow vs a paid HR platform?

Choose self-hosted n8n when your team already lives in Gmail and Telegram, you can't justify $39 per user per month, and you want to avoid forcing recruiters to learn a new tool or migrate pipelines. Choose a paid HR platform when you need built-in compliance features, multi-recruiter collaboration UI, or lack the technical capacity to maintain an n8n instance and tune rubrics over time.