// Automation · Python · AI

AI-Powered Job Finder

A fully automated daily job search pipeline. Queries two live job board APIs, scores every result against a resume using Claude AI, and delivers only the strongest matches as a formatted email digest — every morning, hands-free.

Python Claude AI API REST APIs SMTP Email python-dotenv Automation NLP Scoring
2
Job Board APIs
8/10
Min Match Score
~400
Listings Scored Daily
Daily
Automated Cadence
// The Problem

Job searching is a full-time job.

Manually checking multiple job boards every day, reading through dozens of descriptions, and deciding which roles are actually worth applying to is slow, inconsistent, and exhausting — especially while enrolled in school full-time and targeting a specific geographic area and skill match.

The goal was to eliminate the daily search entirely. Pull the listings automatically. Score them against your actual resume. Only surface the ones that matter.


// How It Works

Five-stage automated pipeline.

Stage 1
Fetch Jobs
Stage 2
Deduplicate
Stage 3
AI Scoring
Stage 4
Filter & Sort
Stage 5
Email Digest
Stage 1 — Fetch Jobs
Queries Adzuna across 8 targeted search terms (data analyst, operations analyst, inventory analyst, etc.) within a 25-mile radius of Chandler, AZ. Also pulls Arbeitnow for remote and US-based roles — no API key required.
Stage 2 — Deduplicate
Results from both sources are merged into a single dictionary keyed by job ID. This ensures the same listing surfaced under multiple search terms is only scored once, keeping the Claude API cost minimal.
Stage 3 — AI Scoring
Each unique job is sent to Claude Haiku alongside the full resume text. Claude returns a structured JSON score (1–10) and a one-sentence rationale explaining the match quality.
Stages 4 & 5 — Deliver
Jobs scoring 8 or higher are sorted by score, formatted as a styled HTML email, and delivered via Gmail SMTP. The digest includes job title, company, location, salary (when available), score, and a direct apply link.

// Under the Hood

Key implementation details.

The AI scoring prompt is intentionally structured — Claude is given a defined output format and instructed to respond with only valid JSON, making the response safe to parse directly without brittle string manipulation.

Python score_job() — Claude AI scoring
def score_job(client, job):
    prompt = f"""You are a career advisor. Score how well this job
matches the candidate's resume on a scale of 1-10.
Only return a JSON object with these fields:
  score (integer 1-10),
  reason (1-2 sentences explaining the match).

RESUME:
{RESUME}

JOB:
Title: {title}
Company: {company}
Location: {location}
Description: {description}

Respond with only valid JSON:
{{"score": 7, "reason": "Strong SQL match."}}"""

    message = client.messages.create(
        model="claude-haiku-4-5-20251001",
        max_tokens=150,
        messages=[{"role": "user", "content": prompt}]
    )
    result = json.loads(message.content[0].text.strip())
    return result["score"], result["reason"]

Deduplication is handled by building a dictionary keyed on job ID before scoring, so the same listing pulled under multiple search terms is never scored twice — keeping API calls and cost to a minimum.

Python main() — deduplication and scoring loop
# Merge both sources, deduplicate by job ID
all_jobs = {}
for job in adzuna_jobs + arbeitnow_jobs:
    all_jobs[job["id"]] = job          # same ID = overwrite, not duplicate

# Score every unique listing
scored = []
for job in all_jobs.values():
    score, reason = score_job(client, job)
    if score >= 8:
        scored.append((job, score, reason))

# Sort highest match first
scored.sort(key=lambda x: x[1], reverse=True)

// Output

What the daily digest looks like.

The pipeline ends with a formatted HTML email delivered each morning. Each card shows the role, company, location, salary if available, AI match score, and a direct link to apply.

📊 Your Daily Job Matches

Jobs near Chandler, AZ (+ remote) scored 8/10 or higher against your resume.

Powered by Adzuna + Arbeitnow + Claude AI


// Reflections

What this project demonstrated.

View the full source code
github.com/Scan93/S.MurtyPortfolio → job_finder.py