Job Search
Query four job boards in parallel and return a single normalized listing feed. Free tier — Adzuna requires a free key, the rest don't.
Why this exists
There's no single source of truth for job listings. Each board has its own format, search semantics, and coverage. This tool fans out across the four most useful free sources, normalizes their schemas, dedupes overlapping postings, and gives you one JSON array your job-hunt pipeline can score against a skills profile.
Sources
| Source | Coverage | Auth | Notes |
|---|---|---|---|
| Remotive | ~2,000 remote tech jobs | None | Free JSON API. Good for software/design/marketing remote roles. |
| Adzuna | Indeed, LinkedIn, Glassdoor, ZipRecruiter aggregated | Free API key (signup at developer.adzuna.com) | 100 calls/day on free tier. Best general coverage including non-remote. Skipped silently if no key. |
| We Work Remotely | Premium remote-only board | None | RSS feed. Higher signal, lower volume. |
| HN Who is hiring | Senior / startup-heavy | None | Monthly thread items via hnrss.org. High salary-band, mostly engineering. |
Inputs
| Property | Required | Default | Description |
|---|---|---|---|
keywords |
✓ | — | Comma-separated search terms. Adzuna AND-joins; the others use them for client-side filtering. |
location |
— | — | Geo filter (Adzuna only). Ignored elsewhere. |
remoteOnly |
— | false |
If true, drops listings flagged as on-site. |
sources |
— | remotive,adzuna,wwr,hn |
Subset to query. |
country |
— | us |
Adzuna country code: us, gb, ca, au, de, fr, in, etc. |
maxPerSource |
— | 50 |
Per-source listing cap before dedup. |
adzunaAppId |
— | — | Adzuna app_id. Adzuna skipped if blank. |
adzunaAppKey |
— | — | Adzuna app_key. Adzuna skipped if blank. |
outputFile |
— | — | If set, writes the normalized JSON listing array here. |
Published outputs
| Name | Description |
|---|---|
listings |
JSON-encoded array of normalized listings (see schema below). |
count |
Total after dedup as a string. |
bySource |
JSON object {remotive: N, adzuna: N, wwr: N, hn: N} of per-source raw counts. |
errors |
Newline-separated per-source errors. Partial results are still returned. |
Listing schema
Every listing is normalized to this shape regardless of source:
{
"source": "remotive|adzuna|wwr|hn",
"id": "<source>:<unique-id>",
"url": "https://...",
"title": "Senior Backend Engineer",
"company": "Acme Corp",
"location": "Remote (US)",
"salary": "$120,000-$180,000",
"description": "...",
"tags": ["python", "aws"],
"posted": "2026-05-12",
"remote": true
}
Empty fields stay as empty strings — never null or missing — so
downstream prompts can safely interpolate without null checks.
Adzuna setup (recommended)
- Sign up free at https://developer.adzuna.com/signup
- Activate an application — you'll get an
app_idandapp_keyimmediately. - Pass them as
adzunaAppId/adzunaAppKeyin the task properties.
The free tier is 100 queries/day. A typical daily job-hunt run uses 1.
Chaining pattern (typical job-hunt pipeline)
- name: search
tool: job-search
properties:
keywords: "python,senior,backend"
location: "United States"
remoteOnly: "true"
adzunaAppId: "{{env.ADZUNA_APP_ID}}"
adzunaAppKey: "{{env.ADZUNA_APP_KEY}}"
outputFile: "/tmp/jobs.json"
- name: score
tool: ollama
credential: ollama-local
properties:
systemPrompt: |
Score each job listing 0-10 against the candidate profile. Return JSON.
prompt: |
Profile: {{file:/home/me/jobhunt/profile.json}}
Listings: {{search.listings}}
outputFile: "/tmp/scored.json"
Why client-side keyword filtering for WWR and HN
We Work Remotely's RSS has no search parameter. hnrss.org's q is
exact-phrase, not boolean AND. Both endpoints return the full feed and
the script filters client-side by keyword presence in title + description.
This works fine for small feeds (~50-200 items) and avoids surprising
zero-result cases when callers expect "matches any keyword".