An r/hiringcafe post launched an AI Job Search Agent matching power-user filters on a job board. This tutorial walks the data layer: SERP for ATS pages, Reddit for hiring threads, extract for the full job description. Scavio has no extract or crawl endpoint - it returns structured search data (SERP rows, Reddit post bodies, YouTube transcripts), not arbitrary page HTML or markdown. This tutorial uses what the API really returns for a URL: the Google result row, with its title, link and snippet. Fetch the page yourself when you genuinely need the full body.
Prerequisites
- Python 3.10+
- Scavio API key
Walkthrough
Step 1: Take user resume + preferences
Inputs: skills, location, salary range, remote preference.
USER = {'skills': ['python', 'rust', 'mcp'], 'location': 'remote', 'min_salary': 150000}Step 2: Generate ATS-targeted queries
site: queries find Greenhouse, Lever, Ashby pages.
ATS_DOMAINS = ['greenhouse.io', 'lever.co', 'ashbyhq.com']
def queries(user):
return [f'site:{d} {" ".join(user["skills"])} {user["location"]}' for d in ATS_DOMAINS]Step 3: SERP across ATS domains
Scavio search per query.
import requests, os
API_KEY = os.environ['SCAVIO_API_KEY']
def ats_jobs(q):
r = requests.post('https://api.scavio.dev/api/v2/google',
headers={'Authorization': f'Bearer {API_KEY}'}, json={'query': q}).json()
return r.get('organic_results', [])[:20]Step 4: Reddit hiring threads as a parallel surface
r/cscareerquestions, r/jobs, niche subs surface unannounced openings.
def reddit_jobs(skills):
return requests.post('https://api.scavio.dev/api/v1/reddit/search',
headers={'Authorization': f'Bearer {API_KEY}'},
json={'query': f'{" ".join(skills)} hiring 2026'}).json().get('results', [])[:20]Step 5: Extract full job description
ATS pages render as clean markdown.
# Scavio returns structured search data, not page bodies: there is no extract
# or crawl endpoint. What you can get for a URL is the Google result row it
# already has - title, link and snippet. Fetch the page yourself when you need
# the full body.
def scavio_page_row(url, headers):
target = url.split("://")[-1].rstrip("/")
r = requests.post("https://api.scavio.dev/api/v2/google", headers=headers,
json={"query": "site:" + target}, timeout=30)
r.raise_for_status()
rows = r.json().get("organic_results", [])
return rows[0] if rows else {"title": "", "link": url, "snippet": ""}
def description(url):
r = scavio_page_row(url, {'Authorization': f'Bearer {API_KEY}'})
return r.get('snippet', '')Step 6: Score + rank with LLM
Match resume against full description.
import anthropic
client = anthropic.Anthropic()
def score(resume, jd):
msg = client.messages.create(model='claude-sonnet-4-6', max_tokens=200,
messages=[{'role':'user','content':f'Score this resume vs job description 0-100 with 1-line reason. RESUME: {resume}. JD: {jd}'}])
return msg.content[0].textPython Example
# Daily run: 3 ATS queries + 1 Reddit query + ~20 extracts = ~25 credits = $0.11.JavaScript Example
// Same pattern in TS via the Anthropic SDK.Expected Output
About 30-60 ranked jobs per day with full descriptions and 0-100 fit scores. Reddit thread surfacing catches unannounced roles 3-7 days earlier.