What Is ATS Verification in the AI Job Search Framework?

ATS verification in the AI Job Search Framework is a built-in quality-check step within the /apply workflow that extracts and validates the machine-readable text layer of generated PDF résumés to ensure compatibility with Applicant Tracking Systems.

The AI Job Search Framework by MadsLorentzen automates the creation of tailored job applications through an intelligent /apply command. ATS verification serves as a critical safeguard within this workflow that mimics how real employer parsing software reads documents, preventing your résumé from being rejected before it reaches human review.

How ATS Verification Works in the /apply Workflow

When you execute /apply, the framework processes your generated CV through three distinct validation stages to ensure parser compatibility.

  1. Extracting the PDF text layer. The system runs tools/verify_pdf.py to obtain the raw character content that ATS parsers would see. It first attempts extraction using pdftotext (from the Poppler utilities), falling back to the pypdf library if Poppler is unavailable, as documented in README.md.

  2. Validating machine-readable content. The extracted text undergoes validation against three concrete criteria defined in .claude/skills/job-application-assistant/05-cv-templates.md:

    • Contact details as literal text – Email addresses and phone numbers must appear as plain characters, not hidden behind icons or hyperlinks that parsers cannot read.
    • No garbled output – The extraction must be free of artifact strings like "(cid:…)" or random symbols that indicate missing Unicode font mappings.
    • Correct reading order – The linear sequence of text lines must match the visual layout. Single-column designs pass reliably, while multi-column layouts risk scrambling the parsed order.
  3. Matching keywords against job postings. The framework performs literal string matching between terms from the job posting and the extracted PDF text. According to CLAUDE.md, the system prefers exact matches because most ATS software performs basic string searches rather than semantic analysis. The verification reports keyword gaps but never injects unsupported terms into your profile.

If verification fails—such as contact info hidden behind an icon or scrambled reading order—the framework identifies the specific template element requiring correction and re-runs the compilation loop until the PDF passes both visual and ATS checks.

Running ATS Verification Manually

While integrated into the /apply workflow, you can execute the verification standalone using the command-line tool to inspect specific PDF outputs.

To verify a compiled CV and dump the extracted text for manual inspection:

python tools/verify_pdf.py \
    cv/main_CompanyName_Role.pdf \
    --dump-text cv/main_CompanyName_Role.txt

To trigger the complete automated flow including automatic verification:

/apply https://jobindex.dk/job/1234567

This command compiles the tailored CV, automatically calls tools/verify_pdf.py, and reports any parsing failures or keyword mismatches back to the conversation.

Implementation Files and Architecture

The verification logic spans several documentation and implementation files within the MadsLorentzen/ai-job-search repository:

  • tools/verify_pdf.py – Core implementation that handles PDF text extraction via pdftotext or pypdf, and performs contact detail detection, garble filtering, and reading order analysis.
  • README.md (section ATS verification on the PDF text layer) – Documents the extraction strategy and fallback mechanisms between Poppler and pypdf.
  • CLAUDE.md (section ATS & keyword verification (CV)) – User-facing documentation explaining the verification criteria and failure modes.
  • .claude/skills/job-application-assistant/05-cv-templates.md – Defines specific ATS-parseability requirements including contact literal mandates and multi-column layout warnings.

Summary

  • ATS verification ensures PDF résumés are machine-readable before submission through the /apply workflow.
  • The process validates contact information visibility, eliminates garbled Unicode artifacts, and confirms logical reading order.
  • Verification uses pdftotext with pypdf fallback to simulate real employer parser behavior.
  • Keyword matching identifies coverage gaps without fabricating qualifications.
  • Failures trigger iterative template corrections until the document passes both visual and ATS checks.

Frequently Asked Questions

What triggers ATS verification in the AI Job Search Framework?

ATS verification runs automatically whenever you execute the /apply command followed by a job posting URL. The framework compiles your tailored CV and immediately passes the PDF to tools/verify_pdf.py before presenting the final document for submission.

How does the framework handle PDF extraction failures?

If the primary pdftotext tool is unavailable, the system falls back to the pypdf library as documented in README.md. If both extraction methods fail or produce unreadable output, the workflow halts and reports specific template elements that need revision to achieve parseable text.

Why does ATS verification require literal text for contact details?

Most ATS parsers cannot interpret graphical icons or hyperlink metadata embedded in PDFs. The framework requires email and phone numbers to appear as plain text characters to ensure recruiters can contact you after automated screening. Hidden contact information behind vector graphics causes immediate rejection in many systems.

Can I disable ATS verification when generating a résumé?

No, ATS verification is a mandatory quality gate within the /apply workflow. The framework enforces this check to prevent submission of résumés that would fail automated screening, ensuring only parser-compatible documents reach employers.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →