AI Job Search & Fit Scorer — 10 Sources + AI Matching
Pricing
$20.00 / 1,000 retained job fit results
AI Job Search & Fit Scorer — 10 Sources + AI Matching
Search 10 public developer-job sources or score your own job list against a résumé or profile. Get a ranked shortlist with a 0–100 fit score, a 0–5 delivery score after hard-requirement checks, evidence, skill gaps, and links to the postings. No model key needed.
Pricing
$20.00 / 1,000 retained job fit results
Rating
0.0
(0)
Developer
Job Atlas
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
21 hours ago
Last modified
Categories
Share
Give it one résumé or a short candidate profile. It searches up to 10 public developer-job sources, removes duplicates, reads each full posting, and returns a ranked shortlist with two scores per job: a raw 0–100 fit and a 0–5 delivery score that drops whenever a hard requirement is contradicted. Already have a job list? Skip the search and score your own jobs instead.
No model key is required. Each returned match costs $0.02. In default shortlist mode, jobs that miss the threshold, hard drops, holds, AI failures, and clean empty searches have no result charge. Audit mode charges retained non-failure rows.
Independent, unofficial integration. Not affiliated with or endorsed by LinkedIn or any source-site operator. Review source terms, privacy rules, and applicable law for your use case.
What a result looks like
One real row from a run on 2026-09-05 that scored the built-in example candidate, a generalist senior software engineer:
{"schemaVersion": "nomad-ai-job-fit-v1","jobKey": "linkedin:4436371317","title": "Senior Software Engineer, Java","company": "CLEAR","location": "New York, NY","postedAt": "2026-09-05","fitScore": 78,"deliveryScore": 4,"recommendation": "strong","evaluationStatus": "scored","blockingGates": [],"why": "Strong match for a senior full-stack software engineering role: eight years of backend/full-stack experience, React, TypeScript, AWS, Docker, Kubernetes, APIs, and CI/CD align well with the posting.","gapSummary": "The posting highlights Java, which is not listed in the candidate’s skills. Work arrangement, New York logistics, and work authorization are not specified.","url": "https://www.linkedin.com/jobs/view/senior-software-engineer-java-at-clear-4436371317"}
How to read it:
- fitScore (0–100) says how well the posting matches the candidate's skills and target roles.
- deliveryScore (0–5) is the number to act on. Hard gates such as work mode, location, language, work authorization, seniority, or role family lower it, so a great skills match with an impossible location never reaches the top.
- blockingGates lists any hard gate that failed. Empty means none did.
- why and gapSummary are the model's short evidence for and against the match.
The full row also carries the normalized job, every gate verdict, the deterministic pre-screen decision, the model and provider that produced the verdict, source provenance, and stable hashes. The complete example is public: fit-row.example.json.
Run it in one minute
Apify Console. Press Start. The form is prefilled with a bounded search:
all ten sources, software-engineer roles posted in the last seven days around
Madrid with intern and junior titles excluded, at most three jobs, the example
candidate, and a result-charge cap of $0.06. The log, the run status
message, and candidate.usedExampleProfile in the run summary all say the
results describe that example candidate, not you. Then replace the profile
with your own facts, or clear it and upload a résumé. Exactly one candidate
source may be set; a run that keeps the profile and adds a résumé is rejected
before any paid work starts.
API. This call selects latest, searches one source, and returns at most one
match for $0.02:
curl --request POST \--header "Authorization: Bearer $APIFY_TOKEN" \--header "Content-Type: application/json" \--data '{"mode": "search","search": {"sources": ["linkedin"],"keywords": ["platform engineer"],"location": "Madrid","postedWithinDays": 7,"maxItemsPerSource": 1},"candidateProfile": {"primaryRole": "Platform Engineer","targetTerms": ["Platform Engineer", "Backend Engineer"],"skills": ["Python", "PostgreSQL", "Docker"],"seniorityLevels": ["mid"],"remoteLocations": ["Spain", "European Union"],"hybridLocations": ["Madrid, Spain"],"onsiteLocations": [],"workArrangementPreferencesComplete": true},"maxItems": 1,"resultMode": "shortlist","minDeliveryScore": 2,"aiConcurrency": 1}' \"https://api.apify.com/v2/actors/job-atlas~ai-job-fit-scorer/runs?build=latest&waitForFinish=120&maxItems=1&maxTotalChargeUsd=0.02"
Build 0.1.22 produced the historical example above. Maintained callers select latest and record each returned run’s resolved immutable build ID and numeric build number. Keep the returned run ID, wait for that
run to reach SUCCEEDED with exit code 0, then read its default dataset and
its RUN-SUMMARY record. Storage counts can settle a moment after the run
finishes, so re-read the same run when they have not reconciled yet. A
ten-source version of this input is public:
search-input.json.
Two ways to use it
Search + score (default)
Set mode to search, give at least one search term, and pick sources. The
Actor never invents a query from a résumé, so search.keywords is required.
Only the search object narrows what is fetched: put the city or country in
search.location, ISO codes for Welcome to the Jungle in
search.countryCodes, and remote-only work in search.remoteOnly. A location
written in preferences or the candidate profile affects scoring only.
Score jobs you already have
Selecting sourceDatasetId grants this run read-only access to that dataset. For sourceActorRunId outside the Actor's limited access, supply sourceApifyToken with read access to the run and its dataset. The token is an encrypted input; it is never included in results or run summaries. Using the dataset ID avoids needing a separate token.
Set mode to score-jobs, provide one candidate source, and exactly one job
source:
jobs: inlinenomad-agent-job-v1records (up to 200);sourceDatasetId: an existing Apify dataset, read only;sourceActorRunId: one exact successful upstream Actor run. AddexpectedSourceBuildwhen the upstream build must match.
{"mode": "score-jobs","sourceDatasetId": "YOUR_DATASET_ID","candidateProfile": {"primaryRole": "Data Engineer","targetTerms": ["Data Engineer", "Analytics Engineer"],"skills": ["Python", "SQL", "dbt"],"remoteLocations": ["European Union"],"hybridLocations": [],"onsiteLocations": [],"workArrangementPreferencesComplete": true},"maxItems": 25,"resultMode": "shortlist","minDeliveryScore": 2}
A complete inline job record is public: inline-input.json.
Candidate input: choose exactly one
candidateProfile: structured facts and preferences. Fill only what the candidate actually stated and leave unknowns empty; the scorer treats an empty field as unknown, never as a contradiction.resume: a text-based PDF or TXT uploaded in the Apify Console.resumeText: plain text for API clients.
preferences can add explicit role, location, work-mode, language, or contract
constraints for scoring. It does not change which jobs are fetched.
Sources
| Key | Source |
|---|---|
linkedin | LinkedIn public job pages |
remote_boards | Remote job boards |
builtin | Built In |
justjoinit | Just Join IT |
nofluffjobs | No Fluff Jobs |
hackernews | Hacker News “Who is Hiring?” |
ycombinator_was | Y Combinator Work at a Startup |
wttj | Welcome to the Jungle |
infojobs | InfoJobs |
tecnoempleo | Tecnoempleo |
The default selects all ten listed sources. Results are merged fairly across sources and deduplicated before scoring, and every job needs its full description before it can be scored.
Filter support differs by source. Location is native on LinkedIn, Just Join IT,
InfoJobs, and Tecnoempleo. InfoJobs accepts recognized Spanish province names or
its own province IDs (for example, Madrid maps to 33); unrecognized locations
leave its nationwide search unfiltered. Built In and No Fluff Jobs use developer categories
instead of keyword search. A strict remoteOnly search keeps only jobs that
are explicitly fully remote, which excludes hybrid and unknown arrangements and
therefore most LinkedIn rows. RUN-SUMMARY records, per source, what was
fetched and which filters applied.
How scoring works
- A deterministic pre-screen reads each posting and sorts it into a hard
contradiction (dropped), uncertain evidence (held), or a plausible match
(forwarded to AI).
minRankToForwardsets the forwarding floor andrecoverHoldscan send holds to AI as well. - Each forwarded job gets one AI verdict: the raw
fitScore, a short rationale, gaps, and a pass/fail with evidence for every hard gate. - Any failed hard gate clamps the
deliveryScore. - Rows are ordered by delivery score first, then raw fit.
If the model call fails, the row is reported as ai_failed. It is never
silently turned into a zero.
Shortlist or audit
resultMode decides what reaches the dataset and what is charged:
shortlist(default) returns only rows withevaluationStatus: "scored"anddeliveryScore >= minDeliveryScore. The default threshold is2and equality counts. Everything else is neither returned nor charged.auditkeeps the complete evaluation trail: scored rows, static drops, holds, forward-cap holds, andai_failedrows. Every retained row exceptai_failedis charged.minDeliveryScoreis recorded but does not filter.
Output
Dataset rows follow nomad-ai-job-fit-v1
(schema).
Three keys matter for automation:
matchKeyidentifies one candidate plus one job. Use it as the upsert key.evaluationKeychanges with the exact candidate snapshot, job content, scoring contract, or evaluation time. Keep it as the receipt.jobKeyidentifies the posting only. Keying a destination on it alone lets one candidate's result overwrite another's.
RUN-SUMMARY in the default key-value store follows
nomad-ai-job-fit-run-summary-v4
(schema,
real example).
It records per-source outcomes, the result policy, warnings, candidate hashes
(never résumé text), provider and model usage, billing receipts, and the
terminal reason. Its counts block always includes staticDropped,
staticHeld, aiScored, aiFailed, resultFilteredOut, and outputRows,
so an empty shortlist is distinguishable from a run that did no work.
Reconcile the summary with the run and its dataset before writing results
anywhere.
Limits
| Limit | Value |
|---|---|
| Unique jobs evaluated per run | 200 |
| AI verdict concurrency | 1–8 |
| Source concurrency | 1–10 |
| Résumé upload | 5 MB, 50 pages, 8,000 readable characters |
| Job description evidence | 20,000 characters |
| Default run timeout | 15 minutes |
Pricing
| Result mode | job-fit-result is charged when | Price |
|---|---|---|
shortlist (default) | A scored row meets minDeliveryScore and is returned | $0.02 per returned match ($20 per 1,000) |
audit | A complete evaluation row is retained; ai_failed is never charged | $0.02 per retained non-failure row ($20 per 1,000) |
One charged row is $0.02, 25 are $0.50, 100 are $2.00. There is no
search, résumé, run-start, or model-key fee, and no paid child Actor runs: all
collectors run inside this Actor.
The model calls are paid by the Actor owner. That route is capped at $0.20/M
prompt tokens and $1.20/M completion tokens, with at most two provider attempts
per AI call and a fixed $0.25 circuit breaker per run. When the breaker trips,
later AI-dependent evaluations become unbilled ai_failed rows in audit
mode. Shortlist mode filters those failed rows out.
maxTotalChargeUsd on the run limits how many jobs can be evaluated before
their scores are known. A low cap can therefore stop evaluation early even
when some later jobs would have been filtered out and left uncharged.
Integrations and agents
The credential-free starters below select latest and verify each resolved immutable run. The accompanying
skill, guide, schemas, and examples describe that contract:
- Integration guide with the exact-run consumption contract
- Agent skill for Codex and Claude Code, with validators for rows and run summaries
- Hosted Apify MCP descriptor
- REST run-and-fetch client
- n8n → Google Sheets workflow
- Make → Google Sheets blueprint
- Zapier editor specification
- Example inputs and real outputs
The starters are inactive and contain no credentials. Local artifact validation checks the starter configuration. A successful Actor run proves the Actor path; it does not prove your n8n, Make, Zapier, or Google Sheets destination. Test a disposable destination before enabling a schedule.
Caveats
- Public sites change, rate-limit, block, or omit fields. One source can be partial while the others still return usable rows.
- A source teaser is not accepted as a full job description. Supplied jobs over the description limit fail validation; searched descriptions may be truncated and are marked when they are.
- A source that returns zero rows after a verified request is a clean empty result. Unverified empties, all-source failure, or only invalid records fail the run rather than pretending the search was clean.
- Search responses are cached for
cacheTtlSeconds. Set it to0when a check must hit the source fresh. - Duplicate source identities with conflicting supplied content fail closed.
- The Actor evaluates one candidate per run and does not learn from clicks or previous runs.
- Scores are decision support, not facts about a person, and never a substitute for reading the posting.
Privacy and responsible use
- Only public job pages are in scope. The Actor does not use cookies, borrowed accounts, login or paywall bypasses, or CAPTCHA evasion.
- Résumés are processed in memory. They are not written as a separate dataset or copied into every fit prompt. The original Actor input or upload remains subject to Apify retention controls.
- Extracted candidate evidence and fit prompts go through the configured OpenRouter/OpenAI route with provider data collection denied. No zero-data-retention claim is made.
- File URLs are restricted to Apify upload hosts; arbitrary URL fetching is rejected.
- Dataset and upstream-run inputs are read only. The Actor never applies to a job, changes source data, or makes an automated hiring decision.
Verify the source posting and keep a human responsible for application and hiring decisions.
Job Atlas
Explore the Job Atlas job-data and matching Actors. Use latest and retain the immutable build ID returned by each run.