solid.jobs Polish IT Jobs Scraper: Poland, Salary in PLN avatar

solid.jobs Polish IT Jobs Scraper: Poland, Salary in PLN

Pricing

from $1.00 / 1,000 jobs

Go to Apify Store
solid.jobs Polish IT Jobs Scraper: Poland, Salary in PLN

solid.jobs Polish IT Jobs Scraper: Poland, Salary in PLN

IT job offers from solid.jobs, Poland. Salaries converted to PLN per month, contract tagged UoP or B2B. Filter by keyword, city, level, contract, remote and minimum salary. Only-new mode for scheduled alerts. Optional AI fit score. Pay per job after filters.

Pricing

from $1.00 / 1,000 jobs

Rating

0.0

(0)

Developer

Solid Fetch

Solid Fetch

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Get IT job offers from solid.jobs, a Polish IT job board, as a clean feed or an API. Every salary is converted to PLN per month, with EUR and USD equivalents, and the contract is tagged UoP or B2B. Filter by keyword, city, level, category, contract type, remote, only offers with a salary and minimum salary, sort by newest or best paid, and pay only for the jobs that pass the filters. Schedule it with only-new mode for a daily alert. The data comes from the public API of solid.jobs and covers only that board.

What people use it for

  • A job search feed with real filters. One list of React, Python or .NET jobs from solid.jobs, already filtered to B2B in Warsaw from 20,000 PLN a month, with the link to each offer.
  • Daily alerts. Schedule the same search every morning with onlyNewSinceLastRun and get only offers that are new or whose salary, contract or title changed. Unchanged offers are skipped and cost nothing.
  • Recruiting and market research. Salary ranges per technology, level, city and contract type, normalised to one unit, for hiring plans, salary benchmarks or lead lists of companies that are hiring.
  • Salary benchmarks without a spreadsheet. Set mode to salaryReport and get one row per technology and experience level (or city, contract, category) with offer counts and PLN and EUR monthly salary percentiles, B2B and UoP kept apart. See Salary report mode.
  • An AI shortlist (optional). Describe the candidate in a few lines and each job gets a fit score from 0 to 100, a verdict and short reasons, after the hard filters have already removed what does not fit.

How to use it

  1. Type keywords (any of them can match), cities and the filters you need. All fields are optional: an empty input returns the newest IT offers from solid.jobs.
  2. Run it and download the results as JSON, CSV or Excel, or read them through the API.
  3. For alerts, save the input as a task, turn on Only new or changed since the last run and add a schedule.
{
"keywords": ["React", "Next.js"],
"cities": ["Warsaw"],
"contractTypes": ["B2B"],
"minSalaryPln": 20000,
"experienceLevels": ["mid", "senior"],
"publishedWithinDays": 14,
"maxItems": 200
}

How the filters work

  • Keywords are OR: a job matches when its title or skills contain any of them. Spelling variants count as the same word, for example front-end, front end and frontend, or React.js, ReactJS and React, or JS and JavaScript. C# and .NET are matched as written. Words match whole, so Java does not match JavaScript. Set keywordsIn to title for title-only matching, or to everything to search descriptions too.
  • Cities accept Polish and English names: Warszawa or Warsaw, Kraków, Krakow or Cracow, Wrocław, Łódź, and Trójmiasto for Gdańsk, Gdynia and Sopot. Fully remote jobs pass the city filter. Turn on remoteOnly to keep only those.
  • Contract types are UoP (umowa o pracę), B2B and other (umowa zlecenie, o dzieło, internships). An offer whose contract is not stated is dropped when you pick a contract type.
  • Minimum salary compares the top of the salary range, in PLN per month, for the contract types you picked. Hourly rates count 168 hours a month, daily rates 21 days, and other currencies use the National Bank of Poland rate of the day. Offers without a salary are dropped when this filter is set. B2B amounts are usually net and UoP amounts gross, and the gross field on each salary says which.
  • Categories are solid.jobs' own: Developer, DevOps, DataScience, Tester, Analyst, Architect, ItManager, UXUIDesigner, Security, Support, Administrator, OtherIT, or a specialisation such as React, Java, Python, DotNet, Angular, ProjectManager. A job passes when its category or subCategory is in your list; case and punctuation do not matter, so UX/UI Designer works. The list is read from recorded offers, so the board may have more.
  • Only jobs with a salary (withSalaryOnly) drops offers that state no salary, without asking for a minimum.
  • Order (sortBy) is newest (default) or salary, the top of the salary range in PLN per month for the contract types you picked, offers without a salary last. Best paid first needs every offer before it can pick the top ones, so the actor reads all pages of the board (about four requests of 500, still one every 500 ms) instead of stopping early; the run takes a few seconds longer.
  • Excluded companies and words remove offers from companies you already applied to, or titles with words like Senior or Angular. Legal suffixes such as sp. z o.o. do not matter.

Every filter runs before anything is saved or charged, and expired offers are always removed. A field the actor does not know rejects the run with an error, so a typo such as keyword instead of keywords cannot turn into a run of unfiltered jobs.

Salary report mode

Set mode to salaryReport to get aggregates instead of single offers. The actor reads the offers exactly as in the job list, with the same filters (keywords, cities, experienceLevels, contractTypes, remoteOnly, publishedWithinDays, categories, minSalaryPln, withSalaryOnly, excludeKeywords, excludeCompanies), and saves one row per group.

{
"mode": "salaryReport",
"groupBy": ["technology", "experienceLevel"],
"minOffers": 5,
"cities": ["Warsaw"],
"publishedWithinDays": 60
}
  • groupBy: any of technology (also accepted as skill), city, experienceLevel, contractType, category. Default: technology and experienceLevel.
  • minOffers: groups with fewer offers are left out and counted in the run summary. Default 3.
  • A report reads every offer that passes the filters. maxItems, sortBy and includeDescription are ignored, and profile (AI score) and onlyNewSinceLastRun are rejected.

A row built from the solid.jobs responses recorded on 3 October 2026 (groupBy left at the default, so the row is mid-level offers that require SQL):

{
"technology": "SQL",
"experienceLevel": "mid",
"offers": 10,
"withSalary": 10,
"b2bOffers": 9,
"b2bPlnMin": 11350,
"b2bPlnP25": 19300,
"b2bPlnMedian": 21000,
"b2bPlnP75": 23550,
"b2bPlnMax": 26050,
"b2bEurMin": 2595,
"b2bEurP25": 4412,
"b2bEurMedian": 4801,
"b2bEurP75": 5383,
"b2bEurMax": 5955,
"uopOffers": 1,
"uopPlnMin": 12500,
"uopPlnP25": 12500,
"uopPlnMedian": 12500,
"uopPlnP75": 12500,
"uopPlnMax": 12500,
"uopEurMin": 2857,
"uopEurP25": 2857,
"uopEurMedian": 2857,
"uopEurP75": 2857,
"uopEurMax": 2857,
"sampleOfferUrls": ["https://solid.jobs/o/3tzqfew5/solidfetch", "https://solid.jobs/o/rkflekzk/solidfetch", "https://solid.jobs/o/477a7jop/solidfetch"]
}
FieldDescription
technology, city, experienceLevel, contractType, categoryThe group keys you chose in groupBy, and only those.
offersOffers in the group. An offer with several skills, cities or levels counts in each of its groups. Copies of one offer count once.
withSalaryOffers in the group with a B2B or UoP salary.
b2bOffers, uopOffersOffers with a B2B (net) or UoP (gross) salary. The two are never blended: B2B and UoP figures are separate columns.
b2bPlnMin, b2bPlnP25, b2bPlnMedian, b2bPlnP75, b2bPlnMaxMinimum, 25th percentile, median, 75th percentile and maximum of the midpoint of each offer's salary range, PLN per month. The same five fields with the uop prefix for UoP. null when no offer in the group has that salary.
b2bEurMin ... b2bEurMax, uopEurMin ... uopEurMaxThe same figures in EUR at the National Bank of Poland rate of the run. null when the rates were unavailable.
sampleOfferUrlsUp to 3 offers of the group, those with a salary and the newest first.

How the numbers are made:

  • Midpoint. An offer with 20,000 to 24,000 PLN counts as 22,000. Hourly, daily and foreign-currency salaries are converted to PLN per month first, like in the job list.
  • Technology means the technologies an offer marks as required, with spelling variants merged (React, React.js, ReactJS). Nice-to-have skills are not counted. City is every city of the offer, category is solid.jobs' own category.
  • Contract types. Only B2B and UoP salaries are summed up; a salary under other is not in the report. With contractTypes set, only those contracts count, also for an offer that states both. Grouped by contractType, a group counts only its own contract.
  • Offers without a value for a chosen key (for example no city) are left out, and the run message says how many.
  • Small groups. A group with 3 offers and one salary still gets a row; read withSalary, b2bOffers and uopOffers before trusting a median.
  • The run message and the REPORT_SUMMARY record in the key-value store give the totals: offers read, offers with a salary, groups, rows built (rows) and saved (rowsSaved), and groups left out for minOffers. If solid.jobs failed part way, the message says the report is built on part of the offers.
  • Maximum cost. Once report rows are charged, a run with a maximum cost saves as many rows as it covers, the groups with the most offers first, and says so in the message (stoppedByChargeLimit in REPORT_SUMMARY).

Output

A row built from a solid.jobs response recorded on 3 October 2026 (keywords: ["Python"], includeDescription: false, so description is empty):

{
"id": "solidjobs:bf935ae2-400a-4cb4-a72a-494368ace488",
"source": "solidjobs",
"url": "https://solid.jobs/o/h2xptmo5/solidfetch",
"title": "Senior Test Automation Engineer",
"company": "DCG",
"cities": ["Warszawa"],
"remote": false,
"workplace": "hybrid",
"contractTypes": ["B2B"],
"salaryMin": 21000,
"salaryMax": 22700,
"salaryCurrency": "PLN",
"salaryPeriod": "month",
"salaryContract": "B2B",
"salaryPlnMonthlyMin": 21000,
"salaryPlnMonthlyMax": 22700,
"salaryEurMonthlyMin": 4801,
"salaryEurMonthlyMax": 5189,
"salaryUsdMonthlyMin": 5401,
"salaryUsdMonthlyMax": 5838,
"salaries": [
{ "contract": "B2B", "min": 21000, "max": 22700, "currency": "PLN", "period": "month", "gross": false, "plnMonthlyMin": 21000, "plnMonthlyMax": 22700, "eurMonthlyMin": 4801, "eurMonthlyMax": 5189, "usdMonthlyMin": 5401, "usdMonthlyMax": 5838 }
],
"seniority": ["senior"],
"skills": ["Python", "Robot Framework", "SQL"],
"requiredSkills": [
{ "name": "Python", "level": "advanced" },
{ "name": "Robot Framework", "level": "advanced" },
{ "name": "SQL", "level": "advanced" }
],
"niceToHaveSkills": [],
"category": "Tester",
"subCategory": "TestAutomationEngineer",
"companyLogoUrl": "https://cdn.solid.jobs/companies/logos/eab6a3169f974c89aebe723c4f6c901f.jpeg",
"benefits": [],
"languages": [{ "name": "Angielski", "level": "advanced" }],
"publishedAt": "2026-09-30T09:12:50.878Z",
"expiresAt": "2026-10-31T09:12:50.878Z",
"description": null,
"alsoListedOn": [],
"changeType": null,
"firstSeenAt": null
}
FieldDescription
idStable ID: solidjobs plus the offer ID on solid.jobs.
source, urlAlways solidjobs, and the offer page on solid.jobs.
alsoListedOnOther listings of the same offer, for example a copy for another city, merged into this row and not charged again. Usually empty.
cities, workplace, remoteAll cities of the offer, and remote, hybrid or office.
contractTypesUoP, B2B, other. Empty when the board does not say.
salaryMin, salaryMax, salaryCurrency, salaryPeriod, salaryContractThe best salary of the offer as the board states it (for the contract types you filtered on).
salaryPlnMonthlyMin, salaryPlnMonthlyMaxThe same salary in PLN per month.
salaryEurMonthlyMin, salaryEurMonthlyMax, salaryUsdMonthlyMin, salaryUsdMonthlyMaxThe same salary in euro and US dollars per month, at the National Bank of Poland rate of the run (table A, one request per run). null when that request failed; the run message says so and the run does not fail.
salariesEvery salary of the offer, one per contract type, with the PLN monthly values and gross.
seniorityintern, junior, mid, senior, lead.
skillsRequired and nice-to-have technologies together, names only.
requiredSkills, niceToHaveSkillsThe same split: required technologies with level (basic, advanced, expert, or null), and the names of the nice-to-have ones.
category, subCategorysolid.jobs' category (Developer, DevOps, Tester...) and specialisation (React, Java...).
companyLogoUrlLink to the company logo on the solid.jobs CDN.
benefitsBenefits as solid.jobs lists them, in Polish, for example Pakiet medyczny.
languagesSpoken languages the offer asks for, in Polish as the board names them (Angielski), with level basic, advanced, expert or niceToHave.
publishedAt, expiresAtPublish date as the board shows it (a refreshed offer counts from the refresh) and the end date.
descriptionPlain text, up to 6,000 characters. Long descriptions keep the beginning and the end, where requirements usually are. null when includeDescription is off.
changeType, firstSeenAtWith onlyNewSinceLastRun: new or updated, and when the actor first saw the offer.
fitScore, verdict, reasons, requiredYears, hardStops, aiErrorOnly with a profile, see below.

The SOURCES_STATUS record in the run's key-value store lists solid.jobs with the number of offers listed, saved, and dropped by each filter, and gives it a status: ok, noMatches, partial (stopped part way, the jobs read before the error are kept), blocked or failed, with the reason. The run log prints the same lines.

AI fit score (optional)

Write a short profile: years of experience, stack, level, wanted salary and contract, city or remote, deal-breakers. Each job that passed the filters then gets:

  • fitScore from 0 to 100,
  • verdict: match, maybe or no,
  • reasons: two to four short sentences,
  • requiredYears: the minimum years of experience the offer asks for, or null,
  • hardStops: requirements the candidate fails, such as "asks for 5+ years, candidate has 2".

The model sees only jobs that passed the filters, so the score is spent on real candidates. Scoring uses your own API key (llmProvider and llmApiKey) for Anthropic (Claude Haiku), OpenAI (GPT-5 nano) or Google (Gemini Flash-Lite). Without a key the run stops at the start and says so, so set the key or remove profile. The key is a secret input: Apify stores it encrypted, and the actor sends it only to your provider and does not write it to the log or the results. If the model answers with something that is not a valid score, the job is still saved with aiError and is not charged for scoring. maxAiScores (default 200) caps the number of scored jobs per run.

Ready-made searches

Open one of these, change the input and run it:

Send results to Make, Zapier, n8n or a CRM

Long runs do not need to keep a Make or Zapier scenario waiting:

  1. Start the actor or one of its saved tasks on a schedule, or from your scenario with the asynchronous "Run Actor" step.
  2. Trigger the next step on the finished run. In Make use the Apify module "Watch Actor Runs", in Zapier the Apify trigger for a finished actor run, in n8n the Apify node.
  3. Read the rows with "Get Dataset Items" using the run's dataset ID.

For your own endpoint, open the actor's Integrations tab and add an HTTP webhook on "Run succeeded". Apify retries failed deliveries, and the payload contains resource.defaultDatasetId, which you can read at https://api.apify.com/v2/datasets/<datasetId>/items?format=json. Add &format=csv for a spreadsheet, or &flatten=<field> to turn nested objects into flat columns.

Pricing

You pay per job saved, after filters, duplicate merging and expired-offer removal:

EventFree and BronzeSilverGold and above
Job saved$2.00 per 1,000$1.50 per 1,000$1.00 per 1,000
AI fit score (you pay your LLM provider directly)freefreefree
Salary report row (mode: salaryReport)free until 4 November 2026, then $0.01$0.008 from 4 Nov$0.006 / $0.005 (Gold) from 4 Nov

Salary report rows are free until 4 November 2026; from then on each report row (one group) is charged once, and the offers read for the report are never charged as jobs. A run also has a start fee of $0.00005 per run start (per GB of memory). There is no extra charge for platform usage. A run that finds nothing costs only the start fee, merged duplicates and unchanged offers in scheduled runs are free, and the run stops on its own at the maximum cost you set. If the platform migrates or restarts a run, the jobs saved before are not saved or charged again, and they still count toward maxItems.

FAQ

Which board and how many offers? Only solid.jobs. On 3 October 2026 it listed 1,651 IT offers through its public API. The actor reads that API, up to 500 offers per request, and stops when it has enough matches (with sortBy set to salary it reads them all first). It sends a campaign name with every request, as solid.jobs asks, and waits between requests to stay far below the limit of 300 requests a minute.

What happened to NoFluffJobs, bulldogjob.pl and justjoin.it? They are no longer read, because their terms do not allow automated downloading. Saved tasks and API calls that still send sources with those names keep working: the names are dropped with a warning in the run log and the run uses solid.jobs. The old sources and proxyConfiguration fields are accepted and ignored. Because the search memory of only-new mode no longer depends on the board list, the first scheduled run after this change returns the matching offers once more.

Why fewer jobs than solid.jobs shows? maxItems limits each run (default 100, up to 5,000), and the actor stops reading once it has enough matching offers. Merged duplicates count once.

How fast is it? In test runs from Poland, 30 to 40 filtered jobs with descriptions took 2 to 15 seconds, and 300 jobs took about 100 seconds. Offers come with their descriptions in the list itself, so includeDescription mostly changes the size of the result.

Does it need a login or cookies? No. The solid.jobs public API is read without an account.

Can I filter by salary when a job pays per hour or in euro? Yes. The minimum salary compares the PLN monthly value, so 150 PLN per hour (25,200 PLN a month) passes a 25,000 PLN minimum.

Can I use it from code or an AI agent?

curl -X POST "https://api.apify.com/v2/acts/solidfetch~poland-it-jobs/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"keywords": ["Python"], "remoteOnly": true, "maxItems": 50}'

It also works through the Apify MCP server in Claude, Cursor and other agents, and with the Apify integrations for Make, n8n, Zapier and Google Sheets.

Limits

  • One board. The actor covers solid.jobs only, which lists fewer offers than all Polish boards together. Pracuj.pl, LinkedIn and others are not included.
  • Fields solid.jobs does not give. There is no apply link other than the offer page (url), and no company website, company size, office coordinates or daily tasks in its public API, so the rows do not have them. Recruiter names, e-mails and phone numbers are never collected.
  • EUR and USD are a conversion, not the board's figure. They use the National Bank of Poland mid rate of the last working day, applied to the monthly PLN amount.
  • Contract and salary come from solid.jobs. Some offers state no contract or no salary. Those rows have an empty contractTypes or no salary.
  • Publish dates are solid.jobs' own. A refreshed offer shows the refresh date.
  • The AI score is an opinion of a small, cheap model. It reads the description and the profile and can be wrong. Use it to sort a list, not to reject candidates.
  • If solid.jobs changes its API format, the run reports the board as failed with the reason instead of ending as an empty success. Found a problem? Open an issue on the actor page with the input you used.

When a run fails, an error report with the error message and the shape of the input (which fields are set, how long the lists are), never your input values, profile, API key or results, is sent to the developer to fix bugs.

This is an independent tool and is not affiliated with solid.jobs.

If this actor saved you time, a short review on the actor page helps other people find it.