Searches ATS job boards directly using Boolean queries, scores new postings with Claude AI, and sends Slack alerts for strong matches. Runs on GitHub Actions 3x/day and deduplicates results so you only see genuinely new postings.
The core idea: Greenhouse, Lever, Workday, and ICIMS are public websites. Boolean search via Tavily hits them directly — no scraping, no job board subscriptions, no email digests to parse.
Boolean queries → Tavily Search API → deduplicate (.job_history.txt)
↓
Claude Haiku scores each posting
↓
Daily report + Slack alert
Four queries run per cycle (Greenhouse/Lever, Workday, ICIMS, plus one keyword variant). Each query costs 1 Tavily credit. At 3 runs/day: ~360 credits/month — well within the free tier of 1,000/month.
You don't need to write any code. Everything runs on GitHub's servers — no local setup required. Here's the full process from scratch:
Step 1: Create a free GitHub account
Go to github.com and sign up. It's free.
Step 2: Fork this repo
On this page, click the Fork button (top right). This copies the repo to your own GitHub account so you can customize it.
Step 3: Get your API keys
You need two (Slack is optional):
- Tavily — go to app.tavily.com, sign up for free, and copy your API key. Free tier gives you 1,000 searches/month, which is more than enough.
- Anthropic — go to console.anthropic.com, sign up, add a credit card (you'll spend under $1/month), and copy your API key.
- Slack (optional) — if you want alerts in Slack, follow these instructions to create an incoming webhook URL.
Step 4: Add your API keys to GitHub
In your forked repo, go to Settings → Secrets and variables → Actions → New repository secret.
Add each key with the exact name shown:
- Name:
ANTHROPIC_API_KEY/ Value: your Anthropic key - Name:
BOOLEAN_TAVILY_API_KEY/ Value: your Tavily key - Name:
SLACK_WEBHOOK_URL/ Value: your Slack webhook (optional)
A "secret" is just a password field — GitHub keeps it hidden and injects it when the workflow runs.
Step 5: Edit your profile and queries
In your forked repo, click my-profile.md, then click the pencil icon to edit it. Replace the placeholder text with your actual target roles, experience, compensation floor, and red flags. The more specific you are, the better the scoring.
Then do the same for boolean-search-config.json. Replace the placeholder query strings with real ones — see references/boolean-search-patterns.md for copy-paste queries by role type.
Step 6: Enable the workflow and run it
Go to the Actions tab in your repo. If prompted, click "I understand my workflows, go ahead and enable them." Then click Daily Job Check → Run workflow to trigger your first run manually.
Step 7: Check your results
Once the run finishes, click into it and look for the Artifacts section at the bottom. Download job-reports to see the scored report for your first run.
After that, the workflow runs automatically at 8 AM, 2 PM, and 8 PM EST every day. If you set up Slack, high-scoring jobs will ping you directly.
- Python 3.10+
- Tavily API key — free tier, 1,000 credits/month
- Anthropic API key
- Slack incoming webhook URL (optional, for alerts)
- GitHub account (for scheduled runs)
git clone https://github.com/your-username/job-search-automation.git
cd job-search-automationpython3 -m venv venv
source venv/bin/activate
pip install -r requirements.txtcp .env.example .env
# Edit .env with your API keysEdit my-profile.md to describe the roles you're targeting. This is what Claude reads to score job postings. See the Writing Your Profile section below.
Edit boolean-search-config.json with queries targeting your role. See references/boolean-search-patterns.md for ready-to-use query strings by role type.
# Dry run — prints queries without hitting the API
source venv/bin/activate
python scripts/boolean_search.py --dry-run
# Full local run
source .env && ./scripts/daily-job-check.sh- Push your repo to GitHub
- Go to Settings → Secrets and variables → Actions and add:
ANTHROPIC_API_KEYBOOLEAN_TAVILY_API_KEYSLACK_WEBHOOK_URL(optional)
- Go to the Actions tab and enable workflows
- Trigger a manual run to verify
The workflow runs at 8 AM, 2 PM, and 8 PM EST by default. Edit the cron schedule in .github/workflows/daily-job-check.yml to change timing.
Controls everything without touching code:
{
"settings": {
"results_per_query": 5,
"delay_between_queries_seconds": 2,
"days_back": 7
},
"queries": [
{
"name": "My Role - Greenhouse + Lever",
"enabled": true,
"string": "(site:greenhouse.io OR site:lever.co) (\"senior product marketing manager\") (\"remote\")"
}
]
}results_per_query— Tavily results per query, max 20. Start at 5.days_back— how far back to search. 7 days balances coverage with overlap.delay_between_queries_seconds— pause between queries. Keep at 2.- Set
enabled: falseon any query to pause it without deleting it.
See references/boolean-search-patterns.md for copy-paste query strings by role type.
Each posting is scored in two steps:
Step 1: Talent pool ranking. Claude estimates where you'd sit in the likely applicant pool for this specific role. If the ranking falls below the top 20%, the posting is deprioritized — better to focus where you have real differentiation.
Step 2: Weighted score across six dimensions:
| Dimension | Weight |
|---|---|
| Role Fit | 30% |
| Company Fit | 25% |
| Compensation | 20% |
| Growth Potential | 10% |
| Location/Remote | 10% |
| Timeline | 5% |
Priority tiers:
| Score | Tier | What to do |
|---|---|---|
| 8.0–10.0 | HOT | Customize everything, reach out directly |
| 6.0–7.9 | WARM | Tailored materials, standard outreach |
| 4.0–5.9 | COOL | Light customization, direct application |
| < 4.0 | PASS | Skip unless pipeline is thin |
Slack alerts fire for jobs scoring 6.5 or above. Adjust this threshold in scripts/daily-job-check.sh.
my-profile.md is what Claude reads to score postings. Write it once, keep it updated. The more specific you are, the more accurate the scoring.
What to include:
- Target roles — specific titles (e.g., "Senior Product Marketing Manager", not just "marketing roles")
- Experience summary — years total, years in target function, notable companies, key achievements with numbers
- Preferred industries — ranked. Industry match often matters more than title match for how competitive you'll be.
- Location — remote only? Open to hybrid? Specific cities?
- Compensation floor — your actual minimum. This filters out roles not worth your time.
- Must-haves — things that would make you decline an offer even if everything else looks good
- Red flags — automatic disqualifiers (toxic culture signals, specific company types, etc.)
- Key strengths — what makes you a strong candidate. Claude uses this for talent pool ranking.
- Gaps to be aware of — where you're weaker than other applicants. Honest profiles score more accurately.
See my-profile.md in this repo for a template with examples.
Each run produces:
daily-reports/report-YYYY-MM-DD.md— all scored jobs ranked by score, with qualifications and reasoninglogs/job-check-YYYY-MM-DD.log— execution log.job_history.txt— tracks seen URLs for deduplication (persisted via GitHub Actions cache)- Slack alert — fires for jobs scoring ≥ 6.5 (if webhook is configured)
| Service | Usage | Cost |
|---|---|---|
| Tavily | 4 queries × 3 runs/day × 30 days = 360 credits | Free (limit: 1,000/month) |
| Claude Haiku | ~10-15 jobs scored per run | < $0.50/month |
| GitHub Actions | ~3 min/run × 90 runs/month = 270 min | Free (limit: 2,000 min/month) |
No jobs found: Check that your Boolean strings are valid. Run python scripts/boolean_search.py --dry-run to print queries without hitting the API. Test a query string in Google manually first.
401 error from Tavily: Your BOOLEAN_TAVILY_API_KEY is wrong or not set. Check .env and GitHub Secrets.
All results are duplicates: Expected after the first run. Delete .job_history.txt to reset deduplication history.
Slack not alerting: Either the webhook URL is wrong, or scored jobs are below the 6.5 threshold. Check daily-reports/ to confirm jobs are being found and scored.
Boolean search skipped in GitHub Actions: Ensure BOOLEAN_TAVILY_API_KEY is added to repository secrets.
job-search-automation/
├── README.md
├── boolean-search-config.json # Query configuration (edit this)
├── my-profile.md # Your search criteria (edit this)
├── .env.example # Credential template
├── requirements.txt
├── scripts/
│ ├── boolean_search.py # Tavily search + deduplication
│ └── daily-job-check.sh # Main orchestration script
├── references/
│ └── boolean-search-patterns.md # Ready-to-use Boolean query strings
└── .github/
└── workflows/
└── daily-job-check.yml # GitHub Actions workflow
MIT