Job Posting Parser — seniority, salary and remote regions avatar

Job Posting Parser — seniority, salary and remote regions

Pricing

from $2.00 / 1,000 posting parseds

Go to Apify Store
Job Posting Parser — seniority, salary and remote regions

Job Posting Parser — seniority, salary and remote regions

Turn job postings into structured data: seniority, job function, remote/hybrid/onsite with allowed countries, annualized salary, skills and visa sponsorship flags, with a reason for every label. Rules-based, no LLM. $0.002 per posting.

Pricing

from $2.00 / 1,000 posting parseds

Rating

0.0

(0)

Developer

Lai Keith

Lai Keith

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

21 hours ago

Last modified

Categories

Share

Job Posting Parser: seniority, remote regions, salary and skills from job ads

Job Posting Parser is an Apify Actor that turns a list of job postings into structured data, one dataset row per posting: seniority, job function, remote/hybrid/onsite with the countries and regions a remote candidate may live in, salary with an annualized range, employment type, years of experience, skills and flags such as visa sponsorship. It is rules-based with no LLM, so the same posting always gives the same result, every label comes with a reason, and you pay only for postings parsed ($0.002 each, or $2 per 1,000).

What does Job Posting Parser do?

You give it a JSON list of job postings (the ad text as plain text or HTML, plus an optional title, location and company). For each posting it returns:

  • normalized_title: gender tags (m/w/d), requisition IDs, "Remote - US" suffixes and pay snippets removed; Sr., Mgr and SWE expanded.
  • seniority: one of 10 levels: intern, junior, mid, senior, staff, principal, lead, manager, director, exec. People managers are kept apart from IC titles such as Product Manager, and II, III and L5 are understood.
  • function: one of 12 functions (engineering, data, design, product, marketing, sales, support, ops, finance, hr, legal, other), plus a specialty for engineering and data roles (backend, frontend, ml_ai, devops_sre, …).
  • remote: remote, hybrid, onsite or unknown, with regions_allowed (ISO country codes such as US or DE, and regions such as worldwide, emea, europe, latam) and timezone hints.
  • salary: min, max, currency, pay period and an annualized min and max (2,080 hours, 260 days, 52 weeks or 12 months a year). It reads $, €, £, 30 ISO currency codes and European number formats, and ignores funding rounds, stipends and 401(k).
  • employment_type, experience_years, skills (114 known technologies and tools) and flags: visa sponsorship (offered, explicitly not, or not mentioned), security clearance, equity, relocation, travel, degree, required languages, talent-pool postings and AI/ML roles.
  • reasons: one human-readable reason per label, e.g. seniority=senior: title contains 'Senior'.

Results land in the run's dataset, ready to export as CSV, JSON or Excel.

When should I use it?

  • Job boards and aggregators: add consistent filters (seniority, remote region, salary) to scraped or imported postings.
  • Labour-market analysis: compare salaries across hourly, monthly and yearly ads, or count remote roles open to a country.
  • Recruiting and HR-tech: tag incoming postings before they reach your ATS or search index.
  • After a scraper: chain it after any job-scraping Actor to turn raw ads into clean fields.

If you need one posting at a time from your own code, use the Job Posting Parser API instead. It runs the same rules behind a REST endpoint.

Input

{
"postings": [
{ "id": "job-1", "title": "Sr. Backend Engineer (Python) - Remote, US", "location": "Remote - US", "company": "Acme",
"text": "Fully remote, open to candidates based in the United States or Canada. Base salary $160,000 - $200,000 per year plus equity. 5+ years of experience with Python, Django and PostgreSQL. We are unable to sponsor visas. Full-time." },
{ "id": "job-2", "text": "Freelance Product Designer - Remote (EMEA)\n$60 - $80 per hour, 6-month contract." }
]
}
FieldRequiredDescription
textyes, unless title is givenThe ad or job description, plain text or HTML. description is accepted as an alias
titlenoJob title as posted (300 characters). If missing, the first line of text is used
locationnoLocation as posted, e.g. "Remote - US" or "Hybrid (London)"
companynoCompany name, stripped from the title and skills
idnoYour own ID, copied to the output row so you can join results

A plain string in the list is treated as text. You can send up to 1,000 postings per run.

Output

One row per posting (abridged; this is the real output for the first posting above):

{
"index": 0, "id": "job-1", "title": "Sr. Backend Engineer (Python) - Remote, US", "location": "Remote - US", "company": "Acme",
"normalized_title": "Senior Backend Engineer (Python)",
"seniority": { "level": "senior", "confidence": 0.85 },
"function": { "name": "engineering", "confidence": 0.9, "specialty": "backend" },
"remote": { "type": "remote", "confidence": 0.9, "regions_allowed": ["US", "CA"], "timezones": [] },
"salary": { "min": 160000, "max": 200000, "currency": "USD", "period": "year", "text": "$160,000 - $200,000", "annualized_min": 160000, "annualized_max": 200000 },
"employment_type": "full_time",
"experience_years": { "min": 5, "max": null },
"skills": ["Python", "Django", "PostgreSQL"],
"flags": { "visa_sponsorship": false, "equity_offered": true, "...": "..." },
"reasons": ["title: removed 'Remote, US'", "seniority=senior: title contains 'Senior'", "..."],
"meta": { "parser_version": "1.0.0", "description_chars": 226, "description_was_html": false, "description_truncated": false }
}

How accurate is it?

On 44 real held-out postings (title and location only): seniority 97.7%, job function 93.2%, remote type 100%, allowed regions 95.5%, after one round of generic fixes. Before those fixes the same set scored 95.5%, 68.2%, 97.7% and 93.2%. Job function is the weakest field because many titles are genuinely ambiguous.

How much does it cost?

It's pay per result: $0.002 per posting ($2 per 1,000 postings), plus a little Apify platform usage. Postings with no title and no text are skipped and not charged. If you set a maximum spend on the run, it stops when that limit is reached.

FAQ

How do I extract salary, seniority and remote location from job postings in bulk? Paste your postings as postings (or pass a scraper's output), run the Actor, and export the dataset. Each row has the seniority level, remote type with allowed countries, and the salary with an annualized range.

Can it tell which countries a remote job is open to? Yes. remote.regions_allowed lists ISO country codes and regions taken from the title, location and eligibility sentences such as "must be based in…" or "open to candidates in…". Office lists in the description are ignored.

Why not just ask ChatGPT or another LLM to parse the postings? An LLM can return different answers for the same posting and costs tokens per call. This Actor is deterministic, fast, and explains each label, so the same fields come out the same way on every posting.

How does it compare with other job description parsers? The closest Apify Actor for similar fields charges about $2.57 per 1,000; this one is $2 per 1,000. Enterprise parsers such as Textkernel (from about $99 a month) and Affinda (about $800 for 6,000 credits) cost far more.

Is my data stored? The results stay in your own Apify storage, under your account's retention settings. The postings are parsed inside the run and are not sent to any other service.