JustJoin.it Scraper
Pricing
from $0.95 / 1,000 results
JustJoin.it Scraper
[π° $0.95 / 1K] Extract IT jobs from JustJoin.it β salaries in the posted pay period, skills with proficiency levels, company, location, and apply route. Search by keyword and city, filter by category, seniority, contract type, and remote/hybrid/office.
Pricing
from $0.95 / 1,000 results
Rating
0.0
(0)
Developer
SolidCode
Maintained by CommunityActor stats
2
Bookmarked
26
Total users
7
Monthly active users
7 days ago
Last modified
Categories
Share
Pull IT job listings from JustJoin.it at scale β disclosed salary ranges in the employer's own pay period, a 1-5 proficiency level on every required skill, Polish contract-type breakdowns, geo-coordinates, and the apply route for every role across the Polish and Central European tech market β including the employer's own apply link on the 81% of offers that take applications off-platform. Built for tech recruiters, sourcers, salary-benchmarking analysts, and developers job-hunting in the CEE market who need structured salary and skill data without copy-pasting one offer page at a time.
Why This Scraper?
- Real disclosed salary ranges, with the employer's own pay period β every job that publishes pay returns
salaryFrom,salaryTo,salaryCurrencyandsalaryUnitexactly as posted (PLN, EUR, USD, GBP; hourly, daily, monthly or yearly), never a converted estimate and never re-based to a different period. - A proficiency level on every required skill β in a 780-job sample all 4,618
requiredSkillsentries carried the employer's wanted level on a 1-5 scale (Python: 5, Django: 4), averaging 5.9 skills per job across 1,134 distinct technologies.niceToHaveSkillsuses the same name-plus-level shape, but JustJoin.it employers populate it on only about 1% of offers. - Geo-coordinates on 100% of listings β latitude, longitude and city on every row, spanning 59 cities in a single 780-job pull, ready to map or cluster. A street address comes with the roughly 72% of jobs whose employer published one, and is empty rather than a filler character on the rest. The ISO country code arrives with the full-description option switched on.
- Polish/CEE contract-type breakdown β B2B, Permanent (UoP), Mandate contract, Specific-task contract, and Internship captured per job, with salary attached to each contract type, plus a resolved
contractTypeslist so open-to-negotiation roles are never mistaken for non-matches. - 25 named tech categories β Python, Java, JavaScript, DevOps, Data, AI/ML, Testing, Mobile, Security, PHP, Ruby, Go, Scala, C/C++, .NET, UX/UI, PM, Architecture, ERP, Analytics, Game, HTML, Admin, Support, and Other.
- 6 seniority levels β filter to Intern, Junior, Mid, Senior, Team Leader / Manager, or C-level roles.
- Remote / Hybrid / Office working-mode filter, plus CEFR language requirements β each job lists the languages the employer expects with a CEFR level from A2 to C2 across 12 language codes (English and Polish dominate, then German, French, Portuguese, Danish, Italian, Norwegian), so you can target fully-remote roles that accept a B2 English speaker in one pass.
- The apply route on every row β
applyMethodis filled on 100% of jobs and splits them cleanly:external(81% of 3,265 offers measured across 15 categories) means the employer takes applications on their own site, and those roles carry the employer'sapplyUrl;form(the other 19%) means applications go through JustJoin.it's in-platform form, so there is no external URL to capture. - Up to 10,000 results per search with a one-toggle full-description option that adds 7 fields at once β description HTML and plain text,
applyUrl,companyUrl,companySize,countryand the live/closedisActiveflag β or switch it off for faster bulk pulls.
Use Cases
Tech Recruitment & Sourcing
- Build candidate-facing role lists filtered by stack, seniority, and city
- Surface fully-remote roles open to your candidates' languages
- Track competitor hiring by company across categories
- Capture apply links for direct candidate referrals
Salary Benchmarking
- Compare disclosed B2B vs Permanent pay for the same role
- Benchmark salary ranges by city, seniority, and tech category
- Track pay movements over time with repeated newest-first pulls
- Map salary against required skill levels
Market Research & Talent Analytics
- Measure demand for specific frameworks and languages across the CEE market
- Map hiring density by city using per-listing geo-coordinates
- Quantify remote vs hybrid vs office offerings by category
- Profile company sizes hiring for a given stack
Competitive Intelligence
- Monitor a competitor's open roles, stack, and seniority mix
- Detect new openings the day they go live with newest-first sorting
- Track which contract types competitors offer in your market
Job Seekers
- Filter to remote, salary-disclosed roles matching your skills
- Sort by highest salary to surface top-of-market openings
- Pull full job descriptions and apply links for shortlisted roles
Getting Started
Simple keyword search
{"keywords": "Python","maxItems": 50}
Keyword, city, category, and seniority
{"keywords": "React","city": "Warszawa","categories": ["javascript"],"seniority": ["senior"],"workingMode": ["remote"],"withSalaryOnly": true,"maxItems": 200}
Start URLs with filters and a result cap
{"startUrls": ["https://justjoin.it/job-offers/warszawa/python","https://justjoin.it/job-offer/example-senior-data-engineer"],"employmentType": ["b2b", "permanent"],"sortBy": "salary-desc","includeDescription": false,"maxItems": 500}
Input Reference
Search
| Parameter | Type | Default | Description |
|---|---|---|---|
keywords | string | "Python" | Search term for job titles, skills, or companies (e.g. "React", "DevOps"). Leave empty to browse all jobs. |
city | string | "" | City name to filter by (e.g. "Warszawa", "KrakΓ³w", "WrocΕaw", "Berlin"). Also includes nearby jobs within ~30 km of the city. Leave empty for all locations. |
startUrls | string[] | [] | Paste full JustJoin.it search or job-offer URLs to scrape directly. Used in addition to the keyword/city search. |
Filters
| Parameter | Type | Default | Description |
|---|---|---|---|
categories | select[] | [] | Tech categories to include: AI/ML, JavaScript, HTML, PHP, Ruby, Python, Java, .NET, Scala, C / C++, Mobile, Testing, DevOps, Admin, UX/UI, Project Manager, Game, Analytics, Security, Data, Go, Support, ERP, Architecture, Other. Leave empty for all. |
seniority | select[] | [] | Experience levels: Intern, Junior, Mid, Senior, Team Leader / Manager, C-level. Leave empty for all. |
employmentType | select[] | [] | Contract types: B2B, Permanent (UoP), Mandate contract, Internship, Specific-task contract. Leave empty for all. |
workingMode | select[] | [] | Work arrangements: Remote, Hybrid, Office. Leave empty for all. |
withSalaryOnly | boolean | false | When on, only include jobs that publish a salary range. |
sortBy | select | Default (relevance) | Result order: Default (relevance), Newest first, Highest salary first, Lowest salary first. "Newest first" uses JustJoin.it's own newest ranking, which puts freshly published jobs ahead of older listings an employer has renewed. |
Output & Limits
| Parameter | Type | Default | Description |
|---|---|---|---|
includeDescription | boolean | true | Include each job's full description text and HTML. Turn off for a faster, lighter run when you only need summary fields. |
maxItems | integer | 100 | Maximum number of jobs to collect. Set to 0 for no limit (everything matching your search). |
Output
Each job posting is one flat row. Here's a representative result with includeDescription on. Seven of these fields β descriptionHtml, descriptionText, applyUrl, companyUrl, companySize, country and isActive β come from the full job detail, so they are null (or absent) on runs with includeDescription off:
{"id": "a1b2c3d4-1234-5678-90ab-cdef12345678","slug": "senior-python-engineer-acme-warszawa","url": "https://justjoin.it/job-offer/senior-python-engineer-acme-warszawa","title": "Senior Python Engineer","company": "Acme Tech","companyUrl": "https://justjoin.it/companies/acme-tech","companySize": "100 - 499","companyLogo": "https://justjoin.it/logos/acme.png","category": "python","experience": "senior","salary": "20,000 - 28,000 PLN / Month","salaryFrom": 20000,"salaryTo": 28000,"salaryCurrency": "PLN","salaryUnit": "Month","employmentTypes": [{ "type": "b2b", "from": 20000, "to": 28000, "fromPerUnit": 20000, "toPerUnit": 28000, "currency": "PLN", "currencySource": "original", "unit": "Month", "gross": false }],"contractTypes": ["b2b"],"openToAnyContractType": false,"workingMode": "remote","workingTime": "full_time","city": "Warszawa","street": "Krucza 50","country": "PL","latitude": 52.2297,"longitude": 21.0122,"locations": [{ "city": "Warszawa", "street": "Krucza 50", "latitude": 52.2297, "longitude": 21.0122, "slug": "warszawa" }],"requiredSkills": [{ "name": "Python", "level": 5 },{ "name": "Django", "level": 4 }],"niceToHaveSkills": [{ "name": "Kubernetes", "level": 3 }],"languages": [{ "code": "en", "level": "B2" }],"remoteInterview": true,"openToHireUkrainians": true,"promoted": false,"isSuperOffer": false,"applyMethod": "external","applyUrl": "https://acme-tech.com/careers/senior-python","isActive": true,"datePosted": "2026-05-20T08:00:00Z","lastPublishedAt": "2026-05-22T08:00:00Z","expiresAt": "2026-06-21T08:00:00Z","descriptionHtml": "<p>We are looking for a Senior Python Engineer...</p>","descriptionText": "We are looking for a Senior Python Engineer...","source": "justjoin.it"}
Core Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique job offer identifier |
slug | string | URL slug for the offer |
url | string | Public JustJoin.it listing URL |
title | string | Job title |
category | string | Tech category (e.g. python, devops) |
experience | string | Seniority level (intern, junior, mid, senior, manager, c_level) |
workingMode | string | remote, hybrid, or office |
workingTime | string | Full-time or part-time |
source | string | Source marker ("justjoin.it") |
Company
| Field | Type | Description |
|---|---|---|
company | string | Employer / company name |
companyLogo | string | Company logo URL |
companyUrl | string | Company profile URL. Requires includeDescription. Even then, JustJoin.it publishes it on roughly 3 in 10 offers; null otherwise |
companySize | string | Company size band (e.g. "100 - 499"). Requires includeDescription, and is published on roughly the same 3 in 10 offers as companyUrl |
Salary
| Field | Type | Description |
|---|---|---|
salary | string | Human-readable salary range summary, e.g. 20,000 - 28,000 PLN / Month |
salaryFrom | number | Lower bound of the disclosed salary, in salaryUnit |
salaryTo | number | Upper bound of the disclosed salary, in salaryUnit |
salaryCurrency | string | Salary currency (PLN, EUR, USD, GBP) |
salaryUnit | string | Pay period the figures are quoted in: Hour, Day, Month or Year |
contractTypes | string[] | Every contract type the job is available on, deduplicated and ready to filter on: b2b, permanent, mandate_contract, contract, internship. When the employer has not restricted the contract type, all five are listed. |
openToAnyContractType | boolean | true when the employer named no specific contract type and is open to any of them (JustJoin.it labels these offers "Any"). false when the types in contractTypes were stated explicitly. |
employmentTypes | object[] | Contract types with per-type salary, currency, unit, and gross flag. fromPerUnit/toPerUnit are the figures as posted (in that entry's unit); from/to are the same pay expressed as a monthly equivalent, which is what JustJoin.it ranks and filters on. They match when unit is Month. May include a converted mirror of a row alongside the employer's original figure β the original always has currencySource: "original". |
Location
| Field | Type | Description |
|---|---|---|
city | string | Primary city |
street | string | Street address, or empty when the employer published none (about 28% of jobs) |
country | string | Uppercase ISO 3166-1 alpha-2 country code (e.g. PL, GB, PT). Requires includeDescription |
latitude | number | Geo latitude |
longitude | number | Geo longitude |
locations | object[] | All listed work locations with city, street, and coordinates |
Skills & Languages
| Field | Type | Description |
|---|---|---|
requiredSkills | object[] | Must-have skills, each with name and proficiency level |
niceToHaveSkills | object[] | Nice-to-have skills, same name-and-level shape as requiredSkills. JustJoin.it employers rarely fill this in β expect [] on about 99% of jobs |
languages | object[] | Required languages, each with code and proficiency level |
remoteInterview | boolean | Whether a remote interview is available |
openToHireUkrainians | boolean | Whether the employer is open to hiring Ukrainians |
Dates & Apply
| Field | Type | Description |
|---|---|---|
applyMethod | string | How the employer takes applications. Two values only: external (their own site) or form (JustJoin.it's in-platform form). Filled on 100% of rows |
applyUrl | string | The employer's external application URL. Requires includeDescription, and is null on every form job β about 1 in 5 β because those apply on JustJoin.it itself via the url field |
isActive | boolean | Whether the listing is still open. Requires includeDescription |
datePosted | string | The publication date JustJoin.it shows on the offer page. Refreshed when an employer renews a listing, so it can be later than the job first appeared |
lastPublishedAt | string | When this listing was published in its own right. Matches datePosted until the employer renews the ad, and is the field "Newest first" ranks on |
expiresAt | string | Listing expiry date |
promoted | boolean | Promoted listing flag |
isSuperOffer | boolean | Featured "super offer" flag |
Description
Populated when includeDescription is on; null when it is off.
| Field | Type | Description |
|---|---|---|
descriptionHtml | string | Full job description in HTML |
descriptionText | string | Full job description in plain text |
Tips for Best Results
- Start small, then combine inputs β set
maxItemsto 25-50 on your first run to confirm the data matches your needs, then scale up and mix a keyword, a city, several categories and start URLs in one run; results are de-duplicated across every entry point. Pairingsenioritywith a category (Senior + Data + Remote) gives a focused, mappable slice, and "Highest salary first" puts top-of-market roles at the front of the export. - Always group on
salaryUnitbefore comparing pay β turn onwithSalaryOnlyto drop the undisclosed rows, then read the unit: of 434 salaried jobs we measured, 51% quoted a monthly figure and 45% an hourly one, so a rawsalaryFromcomparison mixes two different scales. - Keep
includeDescriptionon whenever you need company or apply data β switching it off makes large runs noticeably quicker and still returns salary, skills, contract types, coordinates, dates andapplyMethod, but it blanks all seven detail fields:descriptionHtml,descriptionText,applyUrl,companyUrl,companySize,countryandisActive. - Split your outreach on
applyMethodβexternaljobs hand you the employer's ownapplyUrlfor direct contact, whileformjobs (about 1 in 5) accept applications only inside JustJoin.it, so route those to the row'surlinstead of treating the missingapplyUrlas a gap. - "Newest first" ranks on
lastPublishedAt, notdatePostedβ a job an employer renewed this morning carries today'sdatePostedeven though the ad has been live for weeks. In a recent "Newest first" pull every one of the top 300 jobs had gone live within 7 days onlastPublishedAt, against 84% older than that in a plain unsorted pull of the same size. Sort your export onlastPublishedAtto reproduce the run order, or ondatePostedto rank by the date candidates see on the listing. - Read
employmentTypesfor true compensation β a single job often lists different pay for B2B vs Permanent; the per-type array shows each figure with its currency and pay period, so you compare like-for-like. Usefrom/towhen you want every offer on one monthly scale, andfromPerUnit/toPerUnitwhen you want the figure as the employer wrote it. The array also includes converted mirrors of each row; filter to entries wherecurrencySourceis"original"to keep only the employer's posted figures. - Filter contract type on
contractTypes, not the raw type list β many CEE employers leave the contract open to negotiation instead of naming one, and JustJoin.it returns those jobs in every contract-type search.contractTypesalready resolves them to the full set, so a B2B run gives you"b2b"on every row. CheckopenToAnyContractTypewhen you want only the employers who committed to B2B in writing, and expect these open-contract jobs to be the ones without a published salary.
Pricing
From $0.95 per 1,000 results β competitively priced for the CEE tech-hiring market. No compute charges β you only pay per result returned. Bronze, Silver, and Gold subscribers pay progressively less; the table below shows total cost at each discount tier.
| Results | No discount | Bronze | Silver | Gold |
|---|---|---|---|---|
| 100 | $0.11 | $0.11 | $0.10 | $0.10 |
| 1,000 | $1.10 | $1.05 | $1.00 | $0.95 |
| 10,000 | $11.00 | $10.50 | $10.00 | $9.50 |
| 100,000 | $110.00 | $105.00 | $100.00 | $95.00 |
A "result" is one job posting row in the output dataset. There are no separate compute or per-event charges β you pay only for the jobs returned.
Integrations
Export data in JSON, CSV, Excel, XML, or RSS. Connect to 1,500+ apps via:
- Zapier / Make / n8n β Workflow automation
- Google Sheets β Direct spreadsheet export
- Slack / Email β Notifications on new results
- Webhooks β Trigger custom integrations on run completion
- Apify API β Full programmatic access
Legal & Ethical Use
This actor is designed for legitimate recruitment research, salary benchmarking, and labor-market analysis. Users are responsible for complying with applicable laws and JustJoin.it's Terms of Service. Do not use extracted data for spam, harassment, or any unlawful purpose, and handle any personal data in line with applicable privacy regulations such as GDPR.