Job Posting Parser — seniority, salary and remote regions
Pricing
from $2.00 / 1,000 posting parseds
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
Maintained by CommunityActor 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." }]}
| Field | Required | Description |
|---|---|---|
text | yes, unless title is given | The ad or job description, plain text or HTML. description is accepted as an alias |
title | no | Job title as posted (300 characters). If missing, the first line of text is used |
location | no | Location as posted, e.g. "Remote - US" or "Hybrid (London)" |
company | no | Company name, stripped from the title and skills |
id | no | Your 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.
Related
- Job Posting Parser API: the same parser as a REST API, one posting or a batch of up to 20 per call.