Resume-Aware Job Matcher avatar

Resume-Aware Job Matcher

Under maintenance

Pricing

from $0.30 / actor start

Go to Apify Store
Resume-Aware Job Matcher

Resume-Aware Job Matcher

Under maintenance

Rank raw job postings against your resume keywords. Takes a batch of job rows plus your core/secondary/bonus skill buckets and returns a scored, filtered and ranked shortlist with match reasons.

Pricing

from $0.30 / actor start

Rating

0.0

(0)

Developer

Sanjay Pv

Sanjay Pv

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

4 days ago

Last modified

Categories

Share

Rank a batch of raw job postings against your resume and get back a scored, filtered, ranked shortlist — with the reason every job was kept or dropped.

This actor is a thin, data-driven wrapper around the job-hunt matching engine (the same classifier that built a daily 9-month React/Software Engineer/MERN shortlist). It takes the matched + dropped decision logic in engine/ and exposes it over Apify's pay-per-result API, so you can plug it into any job pipeline (a scraper's dataset, a CSV export, a webhook, or a manual paste) without writing a single filter rule.

What it does

Given an array of raw job rows plus your skill buckets, the actor:

  1. Scores every job against your resume — weighted core / secondary / bonus buckets (60 / 30 / 10 by default).
  2. Rejects classes of junk using the production filters:
    • mis-extracted / garbage titles
    • excluded title keywords (QA, Android, iOS, DevOps, Java, Angular, …)
    • senior / lead / principal titles
    • JDs that declare a senior role
    • required foreign stack in the JD (with the title-trust escape: a title that names your target stack survives a python/angular/java/etc. JD requirement; a generic title does not)
    • wrong-stack titles
    • experience-band mismatch (internships, fresher-only, and above your band)
    • scam / engagement-farming / vendor-staffing patterns
    • posting-age window (optional)
  3. Labels each keeper: region, discipline, experience band.
  4. Ranks the survivors by match score with region / band / discipline tie-breaks, collapses duplicates, and caps the shortlist.
  5. Charges pay-per-result — you are billed per ranked job delivered, not per run.

Input

FieldTypeRequiredNotes
jobsarrayyesRaw postings. Aliases for common fields (title/role/position, description/body, applyUrl/url, company, location, postedDate, experience, workMode, salary, email, phone, source). Field matching is case-insensitive.
resumeCorearrayyesMust-have skills (e.g. React, JavaScript, TypeScript, HTML, CSS)
resumeSecondaryarraynoStrong signals (e.g. Redux, Node.js, Express, MongoDB)
resumeBonusarraynoNice-to-have (e.g. Next.js, Jest, Vite)
targetYearsnumbernoYour experience, used for band ranking (default 3)
minScoreintegernoDrop below this score (default 25)
maxResultsintegernoShortlist cap, 1–500 (default 50)
maxAgeHoursintegernoDrop jobs older than this when a date is present (0 = off)
allowedRegionsarraynoKeep only locations containing any of these
excludeTitleKeywordsarraynoOverrides the tuned title exclusions
seniorTitleWordsarraynoOverrides the seniority markers
jdStackRejectsarraynoOverrides JD-required foreign stacks
wrongStackarraynoOverrides wrong-stack words
excludeInternshipsbooleannoDrop internship/trainee/apprentice (default true)
acceptFreshersbooleannoKeep 0-experience roles (default false)
includeDroppedbooleannoEmit a per-job dropped report with reasons

All list fields ship with sensible tuned defaults, so sending only jobs + resumeCore gets you a working run.

Output

The dataset is populated with:

  • one ranked_job record per keeper — rank, matchScore, title, company, location, region, discipline, band, matched/missing skills, apply URL, salary, email, phone, notes, and a trimmed description;
  • one summary record — counts, minScore, maxResults, top result;
  • when includeDropped is true, one dropped_report record — counts by reason plus up to 200 per-job entries with their drop reason (great for tuning your input).

Pricing model

This actor charges per result: Actor.charge("ranked-jobs", count=kept). You pay only for jobs that make the shortlist, so a huge input with few matches is cheap and a dense input is priced per useful row. The Apify platform revenue share pays the developer (you, on the published actor's owner payouts). To tune price: pick a per-result event price in Pay per event & result under the actor's monetization settings, sized against the value of a matched opening (typical tier: $0.05–$0.20 per ranked result).

Note on the pay-per-event model: with rental-based revenue being retired (no new rentals after April 1, 2026), price via pay per event / pay per result — it is the long-lived revenue surface.

Local development

# 1. Create a venv and install deps
python -m venv .venv
.venv\Scripts\pip install -r requirements.txt # Windows
# or: python -m pip install -r requirements.txt (after venv activate)
# 2. Run against a sample input WITHOUT Apify (no push, no charge)
python -m src.main --input sample_input.json
# 3. Run under the Apify CLI (pulls your input, pushes to local storage)
apify login
apify run
# 4. Deploy
apify push

The engine side is self-contained in engine/ (filters, matcher, ranking, fingerprint, models). At runtime the actor re-synthesizes filters.yaml from the Apify input before importing the engine, so the exact production regex tables are rebuilt for your run — the vendored filters.yaml is the tuned baseline.

Publish checklist

  1. apify login and apify push from this directory.
  2. In Monetization → Pay per event & result, add event ranked-jobs with your per-result price and a reasonable run budget.
  3. Write a store listing describing the input shape and the pricing above.
  4. Add a sample dataset (e.g. from any public job scraper) so trial runs work out of the box.
  5. Monitor the store page's Cost of results and adjust the per-result price (≈14-day notice, ~once/month) against margin.

Layout

.actor/actor.json actor metadata + output schema
.actor/input_schema.json input form
engine/ vendored job-hunt engine (filters, matcher, ranking)
src/main.py actor entry: synthesize config -> score -> rank -> push+charge
sample_input.json local smoke-test input
Dockerfile apify/actor-python base
requirements.txt apify + yaml + pydantic-settings + rich