DEV Community

Cover image for What an ATS Actually Does With Your CV (And How to Stay Visible)
Mo
Mo

Posted on

What an ATS Actually Does With Your CV (And How to Stay Visible)

TL;DR — An Applicant Tracking System does three things: it parses your CV into structured data, ranks it against the job description, and filters what a recruiter sees first. Most CVs lose points at the parsing stage, before anyone reads a word. Fix the structure, keep the facts, and you stay visible. This post explains each stage, then shows how we built CVSet around it.


Most job seekers picture the ATS as a robot with an opinion. It reads your CV, decides you are not good enough, and deletes you.

That is not what happens. The ATS is closer to a filing cabinet with a search bar. It takes your document, tries to turn it into database rows, and hands the recruiter a searchable list. The damage happens when it cannot read your file properly, because a field it cannot fill is a field nobody can search.

I have spent the last year building a CV scoring product, and this stage broke more CVs than any writing problem we saw.


Stage 1: Parsing — the machine reads your file first

Before anything is scored, your PDF or DOCX is converted into text, then split into fields.

A parser is trying to fill a shape like this:

{
  "name": "...",
  "email": "...",
  "phone": "...",
  "experience": [
    {
      "title": "...",
      "company": "...",
      "start_date": "...",
      "end_date": "...",
      "bullets": ["..."]
    }
  ],
  "education": [],
  "skills": []
}
Enter fullscreen mode Exit fullscreen mode

Every empty field is a search you will not appear in. If title is blank, you do not show up when a recruiter filters for "Product Designer".

Here is the part people miss. Text extraction follows the reading order stored in the file, not the visual order you see on screen. A two-column CV often comes out like this:

# What you see (two columns, side by side):
#   LEFT: Skills, Languages     RIGHT: Experience
#
# What the extractor returns:

Skills
Figma, Next.js, Azure
Languages
English, Persian
Experience
Senior Product Designer
CVSet · 2024 – Present
Enter fullscreen mode Exit fullscreen mode

Readable enough for a human. But the parser now has to guess where the sidebar ends and the job history begins. Tables, text boxes and headers make this worse, because their content is often stored in a separate layer of the document.

What actually breaks parsing:

  • Contact details inside the page header or footer
  • Job titles and dates inside table cells
  • Icons used instead of labels (a phone glyph is not the word "Phone")
  • Dates written as images, or as ranges the parser cannot pattern-match
  • Scanned or exported-as-image PDFs with no text layer at all
  • Creative section names like "My Journey" instead of "Experience"

None of these are writing problems. They are file problems.


Stage 2: Ranking — keyword matching, not judgement

Once the fields are filled, the system compares your CV to the job description. The logic is simpler than most people expect:

# Simplified version of what most matching logic does.
# No intelligence here — just presence, position and frequency.

jd_terms = ["react", "typescript", "accessibility", "design systems"]
cv_text  = extracted_cv.lower()

matched = [term for term in jd_terms if term in cv_text]
score   = len(matched) / len(jd_terms)

print(score)          # 0.5
print(set(jd_terms) - set(matched))   # {'accessibility', 'design systems'}
Enter fullscreen mode Exit fullscreen mode

Two things follow from this.

First: synonyms do not count. If the job description says "design systems" and your CV says "component library", you built the same thing and score zero on that term. The system is not reading for meaning.

Second: placement matters. A skill mentioned once in a list at the bottom carries less weight than the same skill inside a recent role, where it sits next to a company and a date.

So the fix is not to invent skills. The fix is to use the employer's vocabulary for work you have genuinely done, and to move it somewhere visible.


Stage 3: Filtering — a human still decides

This is where the myths come from. You may have read that a large percentage of CVs are "rejected by robots". I have never found a source for those numbers that holds up, so I do not quote them.

What is true is more boring. The recruiter opens a ranked list. They look at the top of it. Being on page four is not a rejection, it is an absence.

Staying visible means three things:

  1. Be parseable, so your fields are filled and searchable.
  2. Be relevant, so you rank against this specific job.
  3. Be readable, because a human opens the file straight after.

Optimising for the machine at the cost of the human is a trap. Keyword-stuffed white text still fails when someone actually reads it.


How we built CVSet around these three stages

I am the founder and product designer of CVSet. The product exists because of one rule we refused to break: same facts, better visibility. The AI never invents a skill, a job, or a number. It reorganises and highlights what is already in your CV.

Here is how the flow maps onto what an ATS does.

1. Analyse — score the CV before anything is changed

You upload a CV and get a score across nine dimensions, including ATS Keywords, Formatting, Readability and Metrics & Impact.

The same CV is also viewed through four perspectives: Hiring Manager, Recruiter, Human Eye and Algorithm. The Algorithm view is the parsing story above. The Human Eye view is the recruiter who opens the file afterwards. A CV can pass one and fail the other, and you need to see both.

The My CV Scores page, showing several scored CVs with their scores and previous scores.

Scores are shown with an honest ceiling. If a CV cannot reach 100 for a real reason, we do not pretend it can.

2. Optimise — fix the structural problems

The analysis produces suggestions you resolve one at a time. Formatting suggestions are the ones that protect parsing: single-column flow, contact details in the body, real text instead of images, standard section names.

One decision here took us a long time to get right. Early on, our formatting logic removed photos from CVs automatically, because photos are unusual on UK and US CVs and can confuse a parser. That was wrong. In Germany and several other markets, a photo is a normal expectation.

We had built a silent destructive action, which is the worst kind of bug: nothing errors, the user just loses something.

The fix was to separate two decisions that we had wrongly merged:

Format:  [ UK ▾ ]   → sets layout conventions only
Photo:   ( ) Keep photo   ( ) Remove photo   → you must choose
Enter fullscreen mode Exit fullscreen mode

The format dropdown never touches the photo. The photo decision is explicit and always per CV. Never let an automated fix quietly delete the user's content.

The Formatting dimension, showing the format dropdown and the separate photo decision row

3. Tailor — match one CV to one job description

This is Stage 2 handled properly. You paste a job description and CVSet evaluates the match across five dimensions:

Dimension Weight
Skills 30%
Keywords 25%
Language 20%
Quality 15%
Prioritisation 10%

The output tells you which required skills you already demonstrate and which are genuinely missing. Matching skills get the employer's wording and move up the page. Missing ones do not get invented. They go to your To-Learn List instead, which is the honest answer to a gap.

You can also skip tailoring entirely and use CVSet as a lightweight application tracker.

The tailoring view with the five dimension scores and the matched vs missing skills

4. Application Pack — everything after the CV

Once tailored, you can generate a tailored CV, a cover letter, likely interview questions, first-call prep questions and a follow-up email. It is credit-based, so you only generate what you need.

5. AI Report — patterns across applications

After five finalised tailored applications, CVSet aggregates what it has seen: which skills keep appearing in the jobs you target, where your CV consistently loses points, which roles you match best. Five is a real threshold, not a marketing number. Below that, the pattern is noise.

CVSet runs on a one-time credit purchase with no subscription and no auto-renewal, and data is deleted 30 days after purchase by design.


What I learned building this

  • Parsing failures look like writing failures. People rewrite their bullet points when the real problem is a table.
  • Two-column CVs are not banned, they are risky. If you use one, keep the reading order sane and keep contact details in the main flow.
  • Never guess on the user's behalf. Our photo bug taught us that a helpful automatic action is still destructive if the user did not choose it.
  • Honesty is a feature. Refusing to invent skills costs you a flashy demo and buys you a product people can actually send to an employer.
  • The machine and the human need the same document. Anything that helps one at the expense of the other is a bad trade.

Key Takeaways

  • An ATS parses, ranks and filters. It does not reject you with an opinion.
  • Parsing is the stage most CVs lose. Empty fields cannot be searched.
  • Keep contact details in the body, use standard section headings, and avoid tables, text boxes and image-only PDFs.
  • Keyword matching is literal. Use the employer's wording for work you have really done.
  • Skills carry more weight inside a recent role than in a list at the bottom.
  • Being unranked is absence, not rejection. Tailor per job to stay near the top.
  • Never let a tool add skills you do not have, or remove content you did not agree to lose.

Over to you

What is the strangest parsing failure you have hit? I am collecting real examples, and the sidebar-swallows-the-job-history one still wins in our team.

If this is useful, my next post will go deeper on one thing: why "demonstrated" has to be decided at tailoring time and stored, instead of being guessed again every time the page loads. It sounds like an implementation detail. It changes what the user is allowed to trust.

You can try the scoring at cvset.io.


Top comments (0)