# solid.jobs Polish IT Jobs Scraper: Poland, Salary in PLN (`solidfetch/poland-it-jobs`) Actor

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.

- **URL**: https://apify.com/solidfetch/poland-it-jobs.md
- **Developed by:** [Solid Fetch](https://apify.com/solidfetch) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 jobs

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

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

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](#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.

```json
{
    "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.

```json
{
    "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):

```json
{
    "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"]
}
```

| Field | Description |
|---|---|
| `technology`, `city`, `experienceLevel`, `contractType`, `category` | The group keys you chose in `groupBy`, and only those. |
| `offers` | Offers in the group. An offer with several skills, cities or levels counts in each of its groups. Copies of one offer count once. |
| `withSalary` | Offers in the group with a B2B or UoP salary. |
| `b2bOffers`, `uopOffers` | Offers with a B2B (net) or UoP (gross) salary. The two are never blended: B2B and UoP figures are separate columns. |
| `b2bPlnMin`, `b2bPlnP25`, `b2bPlnMedian`, `b2bPlnP75`, `b2bPlnMax` | Minimum, 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` ... `uopEurMax` | The same figures in EUR at the National Bank of Poland rate of the run. `null` when the rates were unavailable. |
| `sampleOfferUrls` | Up 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):

```json
{
    "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
}
```

| Field | Description |
|---|---|
| `id` | Stable ID: `solidjobs` plus the offer ID on solid.jobs. |
| `source`, `url` | Always `solidjobs`, and the offer page on solid.jobs. |
| `alsoListedOn` | Other listings of the same offer, for example a copy for another city, merged into this row and not charged again. Usually empty. |
| `cities`, `workplace`, `remote` | All cities of the offer, and `remote`, `hybrid` or `office`. |
| `contractTypes` | `UoP`, `B2B`, `other`. Empty when the board does not say. |
| `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod`, `salaryContract` | The best salary of the offer as the board states it (for the contract types you filtered on). |
| `salaryPlnMonthlyMin`, `salaryPlnMonthlyMax` | The same salary in PLN per month. |
| `salaryEurMonthlyMin`, `salaryEurMonthlyMax`, `salaryUsdMonthlyMin`, `salaryUsdMonthlyMax` | The 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. |
| `salaries` | Every salary of the offer, one per contract type, with the PLN monthly values and `gross`. |
| `seniority` | `intern`, `junior`, `mid`, `senior`, `lead`. |
| `skills` | Required and nice-to-have technologies together, names only. |
| `requiredSkills`, `niceToHaveSkills` | The same split: required technologies with `level` (`basic`, `advanced`, `expert`, or `null`), and the names of the nice-to-have ones. |
| `category`, `subCategory` | solid.jobs' category (`Developer`, `DevOps`, `Tester`...) and specialisation (`React`, `Java`...). |
| `companyLogoUrl` | Link to the company logo on the solid.jobs CDN. |
| `benefits` | Benefits as solid.jobs lists them, in Polish, for example `Pakiet medyczny`. |
| `languages` | Spoken languages the offer asks for, in Polish as the board names them (`Angielski`), with `level` `basic`, `advanced`, `expert` or `niceToHave`. |
| `publishedAt`, `expiresAt` | Publish date as the board shows it (a refreshed offer counts from the refresh) and the end date. |
| `description` | Plain text, up to 6,000 characters. Long descriptions keep the beginning and the end, where requirements usually are. `null` when `includeDescription` is off. |
| `changeType`, `firstSeenAt` | With `onlyNewSinceLastRun`: `new` or `updated`, and when the actor first saw the offer. |
| `fitScore`, `verdict`, `reasons`, `requiredYears`, `hardStops`, `aiError` | Only 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:

- [React developer jobs in Warsaw from solid.jobs](https://apify.com/solidfetch/poland-it-jobs/examples/react-jobs-warsaw)
- [Remote IT jobs in Poland](https://apify.com/solidfetch/poland-it-jobs/examples/remote-it-jobs-poland)
- [Polish B2B IT jobs above a minimum salary](https://apify.com/solidfetch/poland-it-jobs/examples/b2b-it-jobs-poland-salary)
- [Junior and intern IT jobs in Poland from the last week](https://apify.com/solidfetch/poland-it-jobs/examples/junior-it-jobs-poland)
- [Alert for new IT jobs in Poland](https://apify.com/solidfetch/poland-it-jobs/examples/new-it-jobs-alert-poland)

### 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:

| Event | Free and Bronze | Silver | Gold 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) | free | free | free |
| 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?**

```bash
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.

# Actor input Schema

## `mode` (type: `string`):

"Job list" saves one row per job offer (pay per job). "Salary report" reads the same offers with the same filters and saves one row per group instead, for example per technology and experience level: offer counts and PLN and EUR monthly salary percentiles, B2B (net) and UoP (gross) kept apart. Report rows are free until 4 November 2026 and charged per row from then on (see Pricing); the offers read for a report are not charged as jobs. Fields "Max items", "Sort by" and "Include description" are ignored in report mode: it reads every offer that passes the filters.

## `keywords` (type: `array`):

A job matches when its title or skills contain any of these words (OR). Spelling variants count as one: front-end and frontend, React.js and React, C# and csharp. Empty means all IT jobs.

## `keywordsIn` (type: `string`):

Where keywords must appear. "Everything" also searches the description.

## `excludeKeywords` (type: `array`):

Drop jobs whose title contains any of these words, for example Senior, Lead, Java.

## `experienceLevels` (type: `array`):

Keep jobs at any of these levels. Empty means all levels.

## `categories` (type: `array`):

Keep jobs in these solid.jobs categories or specialisations, for example Developer, DevOps, DataScience, Tester, Analyst, Architect, ItManager, UXUIDesigner, Security, Support, or React, Java, Python, DotNet, Angular. Case and spaces do not matter. Each job shows its own category and subCategory. Empty means all.

## `cities` (type: `array`):

Polish or English names work: Warszawa or Warsaw, Kraków, Krakow or Cracow, Trójmiasto. Fully remote jobs always pass this filter; turn on "Remote only" to get just those.

## `remoteOnly` (type: `boolean`):

Keep only fully remote jobs. Hybrid jobs are dropped.

## `contractTypes` (type: `array`):

UoP is an employment contract (umowa o pracę), B2B is a contract with your own company, other covers umowa zlecenie, o dzieło and internships. Jobs whose contract is not stated are dropped when you pick any.

## `minSalaryPln` (type: `integer`):

Keep jobs whose top of the salary range, for the chosen contract types, is at least this much per month in PLN. Hourly rates count 168 hours a month; other currencies use the National Bank of Poland rate. Jobs without a salary are dropped. B2B is usually net, UoP gross.

## `withSalaryOnly` (type: `boolean`):

Drop jobs that state no salary. Setting a minimum salary already does this.

## `publishedWithinDays` (type: `integer`):

Keep jobs published or refreshed by the board within this many days.

## `excludeCompanies` (type: `array`):

Company names to skip, for example the ones you already applied to. Legal suffixes like sp. z o.o. do not matter.

## `maxItems` (type: `integer`):

Stop after saving this many jobs. Newest jobs come first.

## `sortBy` (type: `string`):

Newest first (default), or best paid first by the top of the salary range in PLN per month. Best paid first reads every offer of the board before it picks the top ones, about four requests, so the run takes a few seconds longer.

## `includeDescription` (type: `boolean`):

Add the job description (plain text, up to 6,000 characters). Turn off for smaller results.

## `onlyNewSinceLastRun` (type: `boolean`):

For scheduled runs: save only jobs this search has not returned before, or whose title, salary or contract changed. Unchanged jobs are skipped and not charged.

## `monitorName` (type: `string`):

Optional name for the memory of earlier runs. By default each different search keeps its own. Letters, digits and !-\_.'() only.

## `profile` (type: `string`):

A few lines about the candidate: years of experience, stack, level, wanted salary and contract, city or remote, deal-breakers. Each job that passes the filters gets a 0-100 fit score, a verdict and short reasons. Up to 4,000 characters.

## `llmProvider` (type: `string`):

Only if you bring your own key. Cheapest model of each: Claude Haiku, GPT-5 nano, Gemini Flash-Lite.

## `llmApiKey` (type: `string`):

Needed for the AI fit score. Used only to call your provider during this run; it is stored encrypted by Apify and never written to the log or the results.

## `maxAiScores` (type: `integer`):

Jobs after this many are saved without a score.

## `groupBy` (type: `array`):

Salary report only. One row per combination of these keys. Technology is a required skill of the offer (an offer counts in each of its skills), city is any city of the offer, level is the experience level, contract is UoP, B2B or other, category is the solid.jobs category. Offers without a value for a chosen key are left out. Empty means technology and experience level.

## `minOffers` (type: `integer`):

Salary report only. Groups with fewer offers are left out and counted in the run summary. Empty means 3.

## Actor input object example

```json
{
  "mode": "jobs",
  "keywords": [
    "React"
  ],
  "keywordsIn": "titleAndSkills",
  "cities": [
    "Warszawa"
  ],
  "remoteOnly": false,
  "withSalaryOnly": false,
  "maxItems": 50,
  "sortBy": "newest",
  "includeDescription": true,
  "onlyNewSinceLastRun": false,
  "maxAiScores": 200
}
```

# Actor output Schema

## `jobs` (type: `string`):

No description

## `salaries` (type: `string`):

No description

## `details` (type: `string`):

No description

## `aiFit` (type: `string`):

No description

## `salaryReport` (type: `string`):

No description

## `reportSummary` (type: `string`):

No description

## `sourcesStatus` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "keywords": [
        "React"
    ],
    "cities": [
        "Warszawa"
    ],
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("solidfetch/poland-it-jobs").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "keywords": ["React"],
    "cities": ["Warszawa"],
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("solidfetch/poland-it-jobs").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "keywords": [
    "React"
  ],
  "cities": [
    "Warszawa"
  ],
  "maxItems": 50
}' |
apify call solidfetch/poland-it-jobs --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,solidfetch/poland-it-jobs"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/beeQZeKgrpFlqXKOd/builds/zeFTEV4zR3KNaqLej/openapi.json
