Updated April 30, 2026 ยท 18 min read
You apply to a job, the system shows the recruiter a number next to your name, and that number decides whether they ever click your resume. What's inside the number?
The answer changed in the last two years. The old generation of applicant tracking systems counted keywords. The new generation runs fine-tuned LLMs over your resume, encodes both sides as embeddings, and grades you in named bands. Greenhouse, Workday HiredScore, Lever, and Eightfold all moved through this transition at different speeds and now sit on roughly the same architecture: extract structured signals โ match against a calibrated requirements object โ output a graded result with per-skill explainability for the recruiter.
You - the candidate - never see any of it.
Job Agent's scorer was built to replicate that newer architecture on your side. Not to invent something better; just to give you the same kind of grading the receiving ATS will give you, before you apply, with the breakdown visible. This post walks through what changed in ATS scoring, what the published research actually says, and what it took to build the same thing as a candidate-facing tool.
The two generations of ATS scoring
v1 - keyword density and TF-IDF (the old way)
For most of the 2010s, ATS scoring was a Boolean keyword match. Pull tokens from the job description, scan the resume for the same tokens, count overlap, output a percentage. The slightly fancier version weighted rare tokens with TF-IDF - Term Frequency ร Inverse Document Frequency, the same statistic Google uses to weigh keyword importance in a document corpus (STAT Search Analytics). Academic resume-screening prototypes published as recently as 2023โ2024 still build on TF-IDF + cosine similarity (JETIR 2023, IRJMETS 2024) - meaning v1 is still in production at the long tail of smaller ATS vendors and homegrown systems.
job_tokens = ["Python", "AWS", "Kubernetes", "Django", "PostgreSQL"]
resume_tokens = ["Python", "AWS", "Docker", "FastAPI", "MySQL"]
overlap = 2
score = 2 / 5 = 40%
The unit of meaning was the string. That worked when JD authors and candidates happened to use the same vocabulary, which turned out to be most of the time except when it wasn't. v1 broke whenever:
- Synonyms diverged. Postgres โ PostgreSQL. K8s โ Kubernetes. JS โ JavaScript.
- Equivalent tools were named differently. A JD requires Airflow; the candidate has Prefect. Same job, different vendor.
- Generics didn't connect to specifics. A JD asks for "container orchestration"; the candidate has Kubernetes.
- Adjacent skills got zero credit. The JD asks for Spark; the candidate has Scala and worked on streaming pipelines. Strong related signal, no credit.
It also got gamed easily - hidden white text at the bottom of a PDF pasted with the JD verbatim could juice the score. Most of the "ATS rejection" anxiety online traces back to this era - a candidate who's qualified but uses different vocabulary than the JD looks like a poor match to a token counter.
v2 - structured extraction, semantic matching, graded categories (today)
Starting around 2023 the major ATS vendors rebuilt their scoring layer. The architecture across all of them now looks roughly the same:
- Structured extraction. A model - often a fine-tuned LLM - reads the resume and pulls structured fields: skills, job titles, years of experience per role, employment dates, company names. The same model (or a sibling) does it on the job description. A September 2025 paper benchmarked a fine-tuned LLaMA 3.1 8B at 82.05% Exact Match on resume field extraction - a 10.5-point lift over the base model (arXiv 2509.06196).
- Semantic matching. Both sides get matched through a skill ontology or embedding space. "Software engineer" matches "web developer." "Postgres" matches "PostgreSQL." Synonyms and substitutes get credited.
- Graded output. Candidates land in named buckets - Strong / Good / Partial / Limited Match, letter grades, or 1โ5 stars - rather than a single percentage.
- Per-skill explainability for the recruiter. They see which terms matched, which were missing, and a short justification.
- Assistive, not autonomous. No auto-reject by default. The score ranks; humans still decide.
What each major platform actually publishes about its architecture:
| Platform | Architecture (verifiable) | Output |
|---|---|---|
| Greenhouse Talent Matching | "A series of fine-tuned LLM models, each one trained for a specific extraction task" plus third-party models such as OpenAI; embedding-based semantic match; monthly bias audits by WardenAI (Greenhouse Data Processing FAQ) | Strong Match / Good Match / Partial Match / Limited Match / Needs manual review |
| Workday HiredScore | "Unbiased, AI-driven candidate grading" against the requisition; bias auditing; per a July 2025 federal court order, Workday confirmed HiredScore is a "wholly separate technology platform" from Workday's older Candidate Skills Match (HR Dive) | "Candidate grading" - Workday's datasheet calls it grading without specifying the scale; users on G2 report A/B/C/D bands (Workday HiredScore datasheet) |
| Lever | AI-powered matching engine that "instantly ranks candidates against your job requirements... with transparent scoring and explanations" (Lever blog, June 2025) | Match score + ranked shortlist |
| Eightfold | Deep-learning Talent Intelligence Platform trained on a claimed 1.6B+ career profiles and 1.6M+ skills | Match score + projected fit / "learnability" |
A few things worth noticing about all four:
- None auto-reject by default. The "ATS rejected my resume" framing is largely a holdover from v1. Modern systems rank, then a recruiter decides.
- All four score your unmodified resume against the recruiter's calibrated requirements. You don't write the rubric, and you don't see what got extracted from your file. If the parser missed your skills section, the score is wrong and there's no recourse.
- The candidate never sees the breakdown. Greenhouse states explicitly that the recruiter sees "a visual representation of the candidate's resume wherein matched terms are highlighted (either as an exact match or a semantically similar match)" plus matched skills, missing skills, and a justification - and that "AI categorization is only used during the initial application review stage and is not visible later in the process to prevent biasing interviewers" (Greenhouse FAQ). The applicant sees nothing.
That last gap is the whole reason we built our own.
Raw data: what's actually true about ATS
Before we get into our scorer, here's the verifiable research on ATS hiring outcomes - separated cleanly from vendor marketing.
The hiring funnel (CareerPlug 2025 Recruiting Metrics Report, n=60,000+ companies, 10M+ applications)
| Metric | 2024 value |
|---|---|
| Applicants per hire | 180 |
| Click-to-apply conversion | 6% |
| Applicant-to-interview rate | 3% |
| Interview-to-hire conversion | 27% |
| Share of applications from job boards | 60% |
Source: CareerPlug 2025 Recruiting Metrics Report, covering 2024 hiring data.
The applicant-to-interview rate has fallen from roughly 15% in 2016 to about 3% in 2024 as easy-apply, AI-generated resumes, and broader ATS adoption flooded every opening (CoverSentry 2025 ATS statistics roundup).
Average funnel per job (CareerPlug 2024 data)
Average per-role hiring funnel, 2024 data
CareerPlug 2025 Recruiting Metrics Report (n=60K+ companies, 10M+ applications)
ATS adoption (Jobscan 5th Edition ATS Usage Report)
| Year | Fortune 500 with detectable ATS |
|---|---|
| 2023 | 97.4% |
| 2024 | 98.4% |
| 2025 | 97.8% (489 of 500) |
Source: Jobscan 2025 Fortune 500 ATS Usage Report. The figure has held in a 97.4โ98.8% band every year since at least 2018.
Fortune 500 ATS adoption - share with a detectable system
Jobscan 5th Edition ATS Usage Report
Recruiter behavior (Enhancv 2025 in-depth interviews, n=25 US recruiters across 11 ATS platforms, SeptโOct 2025)
| Behavior | Share of recruiters |
|---|---|
| ATS does not auto-reject on resume content/format | 23 / 25 (92%) |
| ATS auto-rejects (Bullhorn, BambooHR threshold setups) | 2 / 25 (8%) |
| Use knockout questions (work auth, license, location) when present | 100% |
| ATS exposes an AI/fit score to them | 44% |
| Use AI score as a guide, double-check manually | 36% |
| Use AI score definitively (rare; one Phenom, one Workday case) | 8% |
| Ignore the AI score or don't have it | 56% |
| Say applying early improves chances | 52% |
Source: Enhancv recruiter survey - small sample, structured interviews, qualitative depth across companies of 100 to 50,000+ employees. ATS platforms covered include Workday, iCIMS, Greenhouse, Bullhorn, BambooHR, SuccessFactors, Teamtailor, Phenom, Lever, Beeline, and LinkedIn Recruiter.
Recruiter use of ATS auto-reject and AI score
Enhancv 2025 recruiter survey, n=25 US recruiters across 11 ATS platforms (SeptโOct 2025)
A separate larger-sample Jobscan 2025 recruiter survey, n=384 found 99.7% of recruiters use their ATS to filter candidates - confirming filtering is universal even though hard auto-reject is rare.
The "75% of resumes are auto-rejected" claim is fake
The widely cited "75% of resumes are rejected by an ATS before a human sees them" stat traces back to a 2012 sales pitch by Preptel, a resume-optimization company that shut down in 2013 with no published methodology. There is no peer-reviewed or industry research backing it (Davron 2025, Interview Guys 2025). 68% of recruiters in the Enhancv survey said they first heard the myth from job seekers on LinkedIn or TikTok (Enhancv).
What this all means for queue placement
A recruiter screening 180 applications is rarely reading past the top 20 ranked candidates. To get reviewed at all, you need to rank in roughly the top 11% of submitted resumes. The match score isn't deciding callbacks directly - it's deciding placement in the queue, and queue placement decides whether anyone clicks your file.
A simpler version of the truth, derived from the funnel above and recruiter filter behavior:
- <70% match: below the median, recruiter probably never opens you.
- 70โ84% match: in the slate the recruiter actually reviews.
- 85%+ match: at the top of the slate where the first calls go out.
There is no peer-reviewed callback-rate-by-score curve. Per-band callback percentages floating around career-coach blogs ("70% = 15% callback, 85%+ = 45% callback") trace to vendor estimates, not academic research. Treat them as marketing. What's solid: the funnel and the queue.
Why a candidate-side scorer matters
The shift from v1 to v2 was a real upgrade. A modern ATS scorer credits Postgres for PostgreSQL, gives partial credit for Prefect when the JD says Airflow, surfaces adjacent skills, and explains itself to the recruiter.
But the explanation goes to the recruiter, not to you. Two consequences:
- You can't tell whether you're worth applying to. Spending time tailoring a resume for a role you'd score 30% on is a waste; spending no time on a role you'd score 85% is a waste too. Without seeing the score before submitting, you guess.
- You can't tell what you're missing. When the receiving ATS scores you "Partial Match" because three of the JD's required skills weren't found, you don't see which three. So you can't fix it.
Job Agent's scorer was built to close that gap. It runs the same kind of v2 scoring the receiving ATS will run - structured extraction from the JD, skill graph matching with synonyms and substitutes, graded output - but it runs it on your side, before you apply, with the breakdown visible.
The pitch isn't that we invented a better scorer. It's that we replicated the architecture the major ATSes already use, and exposed the math.
How our scorer works under the hood
Same shape as a v2 ATS scorer. Three pieces.
1. Structured JD extraction
Every job description goes through an extraction pass before scoring. We pull out:
- Must-have skills (required, knockouts)
- Preferred skills (nice-to-have)
- Required title family ("data engineer," not the title string)
- Years of experience required
- Education requirement (if any)
- Salary range (if disclosed)
- Work mode (remote / hybrid / on-site)
- Location requirement (US-only, specific country, "anywhere")
If the JD has no extractable structured requirements, it doesn't get a fake score - it gets parked for re-extraction. We'd rather skip a row than guess against an empty rubric.
2. Skill graph matching
Skill comparison runs against a graph built from three sources:
- ESCO - the European Commission's Skills, Competences, Qualifications and Occupations classification. ESCO v1.2.1 contains 13,939 skill concepts and 3,039 occupations, with hierarchical relationships and skill-skill edges, published as Linked Open Data in 28 languages (ESCO official). We currently pull from the tabiya-tech open dataset, which mirrors and reformats ESCO (last verified at v1.1.1 - we'll catch up to v1.2.1 on the next graph rebuild).
- O*NET - the US Department of Labor's occupational data. The v29.1 Technology Skills file alone has 58,014 rows; the older v23.2 had 27,661 rows (O*NET v29.1 Data Dictionary, O*NET v23.2). Released under CC BY 4.0.
- A curated tech layer - a hand-maintained set of nodes for the modern data, AI, cloud, and DevOps stack that ESCO and O*NET undercount. This is where "Airflow โ Prefect โ Dagster" lives, the kind of equivalence a labor taxonomy doesn't track because the tools didn't exist when the schema was set.
The graph rebuilds on a slow cadence (every 1โ3 months). At score time it lives as a SQLite file the matcher reads directly.
For each JD skill, the matcher walks the graph in priority order and returns the first hit:
| Match type | Example | Confidence |
|---|---|---|
| Exact | python โ python | 1.00 |
| Alias | k8s โ kubernetes | 1.00 |
| Substitute | airflow โ prefect | 0.85 |
| ESCO related | data analysis โ data visualization | 0.70 |
| Adjacent | airflow โ python | 0.50 |
| ESCO hierarchy | relational databases โ postgresql | 0.50 |
| Substring fallback | word-boundary match in resume body | 0.60 |
Match type confidence credits
Job Agent skill-graph match types and per-type credit weight
The confidence isn't decorative - it's the credit you earn for that JD requirement. A perfect string match gives full credit; an adjacent skill gives half. Required skills get tighter caps than preferred ones, because a JD that says "Databricks required" should not be satisfied at 65% by a candidate who only has Snowflake.
If a JD skill isn't in your structured skills list, the matcher does one last pass against the prose in your resume and work-experience descriptions. Credit is capped lower (appearing in prose is weaker evidence than in a curated skills section) but you still get something for it.
3. Graded output with the breakdown
Every match writes a score breakdown JSON onto the row, recording for each JD requirement:
- Whether it matched
- What it matched against in your profile
- The match type (exact / alias / substitute / adjacent / etc.)
- The confidence credit
The candidate UI renders that breakdown as colored chips. Every credit is visible. Click any matched skill to see why it counted - exact match? Alias? Substitute through Prefect? Resume prose? You can argue with any number.
A worked example
A real-ish JD pulled from a Greenhouse posting:
Senior Data Engineer. Required: Postgres, Airflow, container orchestration, Python. Preferred: Snowflake, dbt, AWS.
A candidate profile:
Skills: PostgreSQL, Prefect, Kubernetes, Python, Snowflake, dbt, AWS, Terraform.
How v1 keyword scoring grades this
| JD requirement | Match? | Credit |
|---|---|---|
| Postgres (req) | No (PostgreSQL โ Postgres) | 0.00 |
| Airflow (req) | No | 0.00 |
| Container orchestration (req) | No | 0.00 |
| Python (req) | Yes | 1.00 |
| Snowflake / dbt / AWS (pref) | Yes | full |
| Required score | 1 / 4 = 25% |
The candidate is qualified, but a v1 scorer ranks them low. They likely never get reviewed.
How a v2 ATS scorer (and Job Agent) grades this
| JD requirement | Matched via | Type | Credit |
|---|---|---|---|
| Postgres (req) | postgresql | substitute/alias | 0.85 |
| Airflow (req) | prefect | substitute (capped) | 0.50 |
| Container orchestration (req) | kubernetes | substitute (capped) | 0.50 |
| Python (req) | python | exact | 1.00 |
| Snowflake (pref) | snowflake | exact | 1.00 |
| dbt (pref) | dbt | exact | 1.00 |
| AWS (pref) | aws | exact | 1.00 |
| Required score | (0.85+0.50+0.50+1.00) / 4 = 0.71 | ||
| Preferred bonus | 100% pref coverage | +0.20 | |
| Final skills score | ~0.95 |
Same candidate, same JD - v1 keyword vs v2 semantic scoring
Job Agent worked example: senior data engineer JD scored under both architectures
Same candidate, same JD. v2 scoring acknowledges that PostgreSQL is Postgres, that Prefect does what Airflow does, that Kubernetes is container orchestration. The required cap on substitute matches still rewards the candidate who has the exact tool more than the one who has an equivalent - but doesn't punish the equivalent down to zero.
This is the kind of score the receiving ATS will give. Job Agent shows it to you before you apply.
What's different about seeing it on your side
Three concrete things you can do once the score is on your screen instead of the recruiter's:
- Decide whether to apply. A 30% match isn't worth a tailored resume; an 85% is. The numeric ranking gives you triage.
- See exactly which skills cost you the score. The breakdown lists the missing must-haves and shows what would have credited. If a skill you actually have isn't surfacing, you can add it to your bank with proof of years and have it credit on every future match.
- Watch the bot apply in score order. Once we know the math, we can rank the apply queue by match score descending - the bot tries your strongest matches first, with an AI-tailored resume that surfaces the JD-relevant skills the scorer used to grade the job in the first place.
None of that's possible if the only thing you ever see is a number you can't audit.
TL;DR
- ATS scoring evolved from v1 (Boolean + TF-IDF keyword counting, the era that produced the "ATS rejection" anxiety) to v2 (structured extraction + semantic skill matching + graded output). Greenhouse, Workday HiredScore, Lever, and Eightfold are all on the v2 architecture now.
- v2 scorers don't auto-reject by default - they rank. Per the Enhancv 2025 recruiter survey (n=25), 92% don't configure threshold-based rejection. The score determines queue placement; queue placement determines whether the recruiter clicks your file.
- The funnel: ~180 applicants per hire, 3% applicant-to-interview, 27% interview-to-hire (CareerPlug 2024 data). To get reviewed at all you need to rank in the top ~11%.
- 97.8% of Fortune 500 companies use a detectable ATS in 2025 (Jobscan). 99.7% of recruiters use their ATS to filter (Jobscan 2025 recruiter survey, n=384).
- The "75% of resumes auto-rejected by ATS" stat is fake. It traces to a defunct 2012 vendor pitch (Preptel) with no methodology and no academic backing.
- The shared limitation across all v2 ATS platforms: the candidate never sees the breakdown. You optimize blind.
- Job Agent's scorer mimics the v2 architecture (structured JD extraction โ skill graph matching โ graded output with a breakdown) but runs on your side, before you apply.
- The skill graph is built from ESCO v1.2.1 (13,939 skills, 3,039 occupations) + O*NET v29.1 (58,014-row Technology Skills file) + a curated tech-stack layer. Six match types with calibrated confidence: exact 1.00, alias 1.00, substitute 0.85, ESCO related 0.70, adjacent 0.50, ESCO hierarchy 0.50.
- Every credit is auditable. You see which JD skills matched, how, and what's missing.
If "your resume scored 78%" never told you what to fix, that's why we built this. The bot also applies for you, in match-score order, with the AI-tailored resume the scorer used to rank the job in the first place. Try Job Agent โ
