# NIJobs Scraper - Jobs, Salaries, Skills & Locations (`abotapi/nijobs-scraper`) Actor

Scrape NIJobs.com listings across Northern Ireland by keyword, location, salary, posted date, or URL. Extract 60+ fields including title, company, salary, skills, description, employment type, industry, GPS, address, dates, and apply URL.

- **URL**: https://apify.com/abotapi/nijobs-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Categories:** Jobs, Developer tools, Social media
- **Features:** Limited permissions
- **Stats:** 3 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 job results

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

## NIJobs Scraper: Job Listings, Full Descriptions & GPS Across Northern Ireland

NIJobs Scraper turns nijobs.com into clean, structured job data for Northern Ireland. Search by keyword and location with filters, or paste results-page links, and get the job title, hiring company, location, salary text, posting and closing dates, skills and a snippet on every record. Turn on detail enrichment and each record also gets the full job description, employment type, industry, work type and contract type, the exact GPS coordinate, the full postal address and the apply URL. Export to JSON, CSV or Excel, or pull results straight into your app through the API.

### Why This Scraper?

- **60+ fields per job.** A stable schema, so the output drops straight into any pipeline whether or not detail enrichment ran.
- **Full descriptions.** Job description in both HTML and plain text, plus employment type, industry, work type, contract type, exact GPS and the full postal address.
- **Company data on every record.** Hiring company name, profile URL and logo, plus sponsored, highlighted and work-from-home flags.
- **Two ways in.** Build a search from keywords, location and filters, or paste results-page links directly.
- **Filters and sorting.** Four sort orders, a posted-within filter, a radius, and a minimum-salary filter by year, day or hour.
- **Incremental mode.** Return only new, updated and reappeared jobs on recurring runs, with one clear Max items cap.

### Use Cases

- **Recruitment and staffing teams:** track new Northern Ireland vacancies by keyword and sector to spot roles worth sourcing candidates for.
- **Job boards and aggregators:** mirror nijobs.com listings into your own site or app on a consistent schema.
- **Salary and labour market research:** collect salary text and posting filters across sectors and towns to study pay trends in Northern Ireland.
- **Location intelligence:** use the GPS coordinate and full postal address to map job density by town or county.
- **HR tech and internal tooling:** feed structured listings into your applicant tracking, alerting tool or dashboard through the API.

### Data You Get

> Sample shape. Values are illustrative placeholders, not from a live listing.

| Field | Example |
| --- | --- |
| `id` | `483920175` |
| `title` | `IT Support Technician` |
| `companyName` | `Lagan Valley Logistics Ltd` |
| `companyUrl` | `https://www.nijobs.com/jobs/lagan-valley-logistics` |
| `companyLogoUrl` | `https://www.nijobs.com/CompanyLogos/placeholder-logo.png` |
| `location` | `Lisburn, County Antrim` |
| `salary` | `£24,000 - £28,000 per annum` |
| `employmentType` | `FULL_TIME` |
| `workType` | `Permanent` |
| `contractType` | `Full Time` |
| `industry` | `IT` |
| `datePosted` | `2026-02-03T08:30:00Z` |
| `validThrough` | `2026-03-03T23:59:00Z` |
| `skills` | `["Windows 11", "Active Directory"]` |
| `latitude` / `longitude` | `54.5116` / `-6.0330` |
| `addressLocality` / `addressRegion` | `Lisburn` / `County Antrim` |
| `postalCode` | `BT28 1AA` |
| `description` | `We are looking for a reliable IT support technician to join our growing team...` |
| `applyUrl` | `https://www.nijobs.com/job/it-support-technician/lagan-valley-logistics-job483920175` |
| `isSponsored` / `isHighlighted` | `false` / `true` |
| `listPageUrl` | `https://www.nijobs.com/jobs/it-support/in-lisburn?page=2` (the results page the job was listed on) |
| `workingHours` | `Full time` (from the job page; empty without detail enrichment) |
| `applicationTypes` | `["direct"]` (`direct` or `external`, from the job page; empty without detail enrichment) |

Extra convenience fields on every record: `companyProfileUrl` (same as `companyUrl`), `datePostedISO` (UTC), `isNew` (posted in the 24 hours before the scrape), `isRemote` and `workFromHome` (only a truthy value or `null`).

Every record carries the same set of keys whether or not detail enrichment ran; fields that only detail enrichment can fill (description, GPS, full postal address, employment type, industry, work type, contract type, apply URL) are simply left empty otherwise. nijobs.com does not publish employer reviews or ratings anywhere on the public site, so `companyRating`, `companyReviewCount` and `companyReviews` are always emitted empty on the same stable schema rather than dropped.

### How to Use

1. Pick a **mode**: `search` (build from keywords, location and filters) or `url` (paste results-page links).
2. Fill in the fields for that mode, and turn detail enrichment on or off.
3. Set **Max items** to control run size and cost, then click **Start**.
4. Download the dataset as JSON, CSV or Excel, or read it through the API.

**Search by keyword with filters:**

```json
{
  "mode": "search",
  "keywords": ["Software Developer", "Data Analyst"],
  "location": "Belfast",
  "postedWithin": "7",
  "minSalary": 30000,
  "salaryPeriod": "annual",
  "sortBy": "date",
  "fetchDetails": true,
  "maxItems": 50
}
```

**Search all of Northern Ireland by keyword, no detail enrichment:**

```json
{
  "mode": "search",
  "keywords": ["Nurse"],
  "sortBy": "salary-desc",
  "fetchDetails": false,
  "maxItems": 30
}
```

**Paste results-page links:**

```json
{
  "mode": "url",
  "urls": [
    "https://www.nijobs.com/jobs/software-developer/in-belfast",
    "https://www.nijobs.com/jobs/accountant"
  ],
  "maxPages": 3,
  "maxItems": 100
}
```

**Minimum hourly rate for a keyword:**

```json
{
  "mode": "search",
  "keywords": ["Care Assistant"],
  "minSalary": 12,
  "salaryPeriod": "hourly",
  "maxItems": 20
}
```

**URL shapes.** Every filter in a pasted link's query string (`page`, `sort`, `postedWithin`, `salary`, `salarytypeid` and any other the site writes) is kept as pasted and wins over the run defaults; the keyword, location and filter input fields are ignored in url mode. A link starting at `?page=N` walks from page N and counts as a partial scan. The incremental baseline scope includes the full link. Job detail links are not search pages: they are skipped with a warning in the log.

| URL shape | What it is |
| --- | --- |
| `https://www.nijobs.com/jobs/software-developer` | keyword search |
| `https://www.nijobs.com/jobs/software-developer/in-belfast` | keyword + location |
| `https://www.nijobs.com/jobs/software-developer/in-county-antrim` | keyword + county |
| `https://www.nijobs.com/jobs/in-belfast` | location only |
| `https://www.nijobs.com/jobs/accountancy` | category slug |
| `https://www.nijobs.com/jobs/software-developer/in-belfast?page=2` | starts at page 2 (partial scan: never expires jobs) |
| `https://www.nijobs.com/jobs/software-developer?sort=2` | sorted by date |
| `https://www.nijobs.com/jobs/software-developer?postedWithin=7` | posted within 7 days |
| `https://www.nijobs.com/jobs/software-developer?salary=40000&salarytypeid=1` | salary filter |
| `https://www.nijobs.com/jobs/software-developer/in-belfast?sort=2&postedWithin=7` | sort + posted within |
| `https://www.nijobs.com/jobs/software-developer/in-belfast?page=2&sort=2` | page + sort (starts at page 2) |
| `https://www.nijobs.com/jobs/accountancy/in-belfast/` | trailing slash |
| `http://nijobs.com/jobs/marketing` | apex host over http, redirected to the www site |
| `https://www.nijobs.com/jobs/permanent/software-developer` | contract-type prefix (permanent / contract / part-time) |
| `https://www.nijobs.com/jobs/mcs-group?cmpId=1216528&cmp=1` | one company's jobs page |

Leaving `urls` untouched in url mode scrapes one example of each shape above. Set `maxItems` to bound the run; it is split evenly across the links.

#### Output views

The dataset has three views: **Jobs Overview**, **Job Detail** and **Changes** (incremental runs: change type and changed fields). The run's Output tab links the dataset, the Changes view and, for multi-search runs, a run summary stored as the `OUTPUT` record of the key-value store.

#### Run it from your code

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/nijobs-scraper").call(run_input={"mode": "search", "keywords": ["Nurse"], "maxItems": 20})
for job in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(job.get("title"), job.get("companyName"), job.get("salary"))
```

JavaScript:

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/nijobs-scraper').call({ mode: 'search', keywords: ['Nurse'], maxItems: 20 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the **Integrations** tab.

### Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step **after** the scrape: the Apify dataset is never changed.

**What gets written to the connector:** a condensed, human-readable **summary** of each job, not the full JSON. Each item becomes one entry with a **title** and its key fields flattened to plain text. The **complete record always stays in the Apify dataset**.

1. Authorize a connector once under **Apify, Settings, Integrations** (Notion, Linear, Airtable, or Apify).
2. Select it in the **"Pipe results into your apps"** input field. If the picker is empty, you have not authorized a connector yet.
3. For **Notion**, also set `notionParentPageUrl` to the page where items should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

### Input Parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `mode` | string | `search` | `search` builds searches from keywords, location and filters; `url` reads pasted results-page URLs. |
| `keywords` | array | prefill only, `["Software Developer"]` | Job titles or keywords to search. Each keyword runs its own search. Search mode only. |
| `location` | string | (none) | Optional town, city or county in Northern Ireland to narrow the search. Search mode only. |
| `postedWithin` | string | `any` | Only return jobs posted within `1`, `3`, `7` or `14` days, or `any` time. Search mode only. |
| `radius` | integer | (none) | Include jobs within 5, 10, 20 or 30 miles of the location (other values snap to the nearest). Search mode with a location only. |
| `minSalary` | integer | (none) | Minimum salary, read together with Salary period. Search mode only. |
| `salaryPeriod` | string | `annual` | Which rate Minimum salary refers to: `annual`, `daily` or `hourly`. Search mode only. |
| `sortBy` | string | `relevance` | Result order: `relevance`, `date`, `salary-desc` or `salary-asc`. Search mode only. |
| `urls` | array | one example of each supported URL shape (15 links, see URL shapes) | Results-page URLs to read. URL mode only; the keyword, location and filter fields above are ignored in this mode. |
| `fetchDetails` | boolean | `true` | Fetch each job page to add the full description, GPS coordinate, full postal address, employment type, industry, work type, contract type, closing date and apply URL. |
| `maxPages` | integer | (none) | Optional per-search page ceiling; the schema does not accept `0`, leave it empty for unlimited pages. Max items remains the run's real cap. |
| `maxItems` | integer | `20` | The run's single hard cap: maximum total jobs across all searches. Set `0` for unlimited. Callers that omit it get 20. |
| `proxy` | object | prefill only, Apify Proxy with a residential group and country GB | Connection settings. The prefilled setting is the residential group with country GB; see Plan Requirement for what happens when it is unavailable. |
| `resumeFromRunId` | string | empty | Continue an interrupted pull: jobs already in that earlier run or dataset (run ID or dataset ID) are skipped, not returned and not billed. |
| `incrementalMode` | boolean | `false` | Recurring runs: return only NEW, UPDATED and REAPPEARED jobs. Unchanged jobs are not returned and not billed. |
| `stateKey` | string | (none) | Incremental mode: name of the saved baseline. Empty derives it from the search settings. |
| `emitUnchanged` | boolean | `false` | Incremental mode: also return unchanged jobs (billed like any returned row). |
| `emitExpired` | boolean | `false` | Incremental mode: return EXPIRED rows for jobs no longer found, only after a complete scan (billed like any returned row). |
| `ignoreFieldsForChanges` | array | (none) | Incremental mode: extra fields (dotted for nested) that never count as a change; they stay in the output. |
| `mcpConnectors` | array | (none) | Optional: send a summary of each job to apps you authorized under Integrations. |
| `notionParentPageUrl` | string | (none) | Notion connector only: page under which item pages are created. |
| `maxNotifyListings` | integer | `50` | Cap on items written to each connector per run. Does not affect the dataset. |

Alternative input names are accepted for convenience: `query` (keywords), `salary` (minSalary), `publishedDate` (postedWithin, e.g. `Last 7 days`), `startUrls` (urls, which also switches to URL mode when no keywords are given), `limit` (maxItems) and `proxyConfiguration` (proxy). An alias is used whenever the standard field is empty or still holds its default value (the Console and API fill defaults in); a standard field you changed from its default wins. There is no experience-level filter: the site accepts an `experience` parameter but returns no jobs for any value, so it is not offered.

### Output Example

> Sample shape. Values are illustrative placeholders, not from a live listing.

```json
{
  "id": 483920175,
  "jobId": 483920175,
  "title": "IT Support Technician",
  "companyName": "Lagan Valley Logistics Ltd",
  "companyUrl": "https://www.nijobs.com/jobs/lagan-valley-logistics",
  "companyLogoUrl": "https://www.nijobs.com/CompanyLogos/placeholder-logo.png",
  "location": "Lisburn, County Antrim",
  "salary": "£24,000 - £28,000 per annum",
  "employmentType": "FULL_TIME",
  "workType": "Permanent",
  "contractType": "Full Time",
  "industry": "IT",
  "datePosted": "2026-02-03T08:30:00Z",
  "validThrough": "2026-03-03T23:59:00Z",
  "skills": ["Windows 11", "Active Directory"],
  "textSnippet": "We are looking for a reliable IT support technician to join our team.",
  "description": "We are looking for a reliable IT support technician to join our growing logistics team. You will support office and warehouse staff with day to day IT issues...",
  "latitude": 54.5116,
  "longitude": -6.033,
  "addressLocality": "Lisburn",
  "addressRegion": "County Antrim",
  "postalCode": "BT28 1AA",
  "addressCountry": "GB",
  "isSponsored": false,
  "isHighlighted": true,
  "workFromHome": null,
  "companyRating": null,
  "companyReviewCount": null,
  "companyReviews": [],
  "applyUrl": "https://www.nijobs.com/job/it-support-technician/lagan-valley-logistics-job483920175",
  "url": "https://www.nijobs.com/job/it-support-technician/lagan-valley-logistics-job483920175",
  "scrapedAt": "2026-02-03T09:00:00Z"
}
```

### Plan Requirement

nijobs.com sits behind a bot-protection layer, and its job detail pages are only served to residential connections. A datacenter connection could not be confirmed to work, so a paid Apify plan with residential proxy access is recommended; the default connection is the residential group with country GB. The run reads the connection that was actually granted and moves to a backup connection when the default is refused, without a blind retry loop.

What you see in the log and in the run status:

- On a plan without residential access the log prints "The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable." and, once a page is served that way, "Served over the backup connection (the default connection was unavailable)."
- If the account has no proxy access at all, the run fails with: "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required."
- If residential is unavailable and the backup connection could not load the pages, the run fails with: "No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested nijobs.com pages."
- If every request failed for another reason, the run fails with: "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search."

A run that could not load any page always ends as failed with a message; it never reports an empty result.

### FAQ

#### How much does it cost?

You pay a small fee once per run start, a per-job fee for every listing pushed to the dataset (this includes `EXPIRED` and, when requested, unchanged rows; a genuinely empty search pushes no row and bills no job fee, and nothing is billed for a status message), and a per-job detail fee only for jobs whose detail page was actually fetched and returned data, charged page by page right after each page is saved; a detail fetch that fails or comes back empty is not charged. The **Pricing** tab on the actor page shows the current rates. Use **Max items** to cap the cost of any run.

#### Can I get only new listings on a schedule?

Turn on **Incremental changes** (`incrementalMode`). The first run saves a baseline per State key and returns every job as `NEW`; later runs return only `NEW`, `UPDATED` (with `changedFields`) and `REAPPEARED` jobs, and unchanged jobs are neither returned nor billed. In incremental mode every row carries `changeType`, `changedFields`, `firstSeenAt` and `lastSeenAt`; in normal runs these four fields are empty (nothing is compared). Changing the search settings or `fetchDetails` starts a new baseline (every job is returned as `NEW` again) unless you set a `stateKey`. Search position (`positionOnPage`, `positionAbsolute`), `scrapedAt`, `periodPostedDate`, `travelTime`, `fingerprintCount`, `isBackfilled`, `isNew`, `listPageUrl` and the order of `labels` / `topLabels` are kept in the output but never count as a change; add more with `ignoreFieldsForChanges`. `EXPIRED` rows (`emitExpired`) are produced only after a complete scan: a Max items or Max pages cut, a pasted URL starting at page 2 or later, or an early stop never expires anything. The detail fee applies only to rows that are actually returned. `EXPIRED` rows are pushed to the dataset and billed like any returned row. Without incremental mode, schedule the actor with `sortBy: "date"` and a short `postedWithin` window and dedupe on `id`. With multiple keywords, Max items is split evenly across them (rounded up), so unused budget on one keyword is not handed to the others; raise Max items if a search with many keywords is coming back short.

#### Is it legal to scrape nijobs.com?

This actor collects only publicly available job listings. You are responsible for how you use the data: follow nijobs.com's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Job postings are provided by employers and may carry their own rights and restrictions.

#### Does the output include employer reviews or ratings?

No. nijobs.com does not publish company reviews or star ratings anywhere on the public site, so those fields always come back empty. If you need employer reputation data, look for a source that actually publishes it.

#### Why did my run fail instead of returning an empty dataset?

Two different situations both fail the run rather than report a false result. In url mode, if none of the pasted links are recognisable nijobs.com results pages, the run fails immediately, before any request is sent, because that is a problem with the input, not a search result. Separately, if every request to nijobs.com is refused, the run fails with a connection message instead of claiming the search was empty. A genuinely empty search, where the site was reached but nothing matched, still succeeds with an empty dataset and a status message saying nothing matched.

#### Can I search outside Northern Ireland?

No. nijobs.com only covers Northern Ireland. Leave **Location** empty to search the whole region, or narrow it to a town or county.

#### Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.

### 🔗 Want more jobs data?

Pair this actor with these related scrapers from the same team:

<table>
<tr><td>💼 <a href="https://apify.com/abotapi/irishjobs-ie"><b>IrishJobs.ie Scraper</b></a><br>Scrape job listings from IrishJobs.ie by keyword, location, job type, salary, recency, or...</td><td>🏨 <a href="https://apify.com/abotapi/caterer-com-scraper"><b>Caterer.com Scraper</b></a><br>Scrape UK hospitality jobs from Caterer.com, including chef, hotel, restaurant, bar, and...</td></tr>
<tr><td>💼 <a href="https://apify.com/abotapi/cwjobs-scraper"><b>CWJobs UK Scraper</b></a><br>Scrape CWJobs.co.uk tech and IT job listings by keyword, location, salary, work type...</td><td>💼 <a href="https://apify.com/abotapi/hh-ru-jobs-scraper"><b>HH.ru Jobs Scraper</b></a><br>Scrape HH.ru job listings with 50+ structured fields. Search by filters or URLs and...</td></tr>
<tr><td>💼 <a href="https://apify.com/abotapi/s1jobs-com-scraper"><b>s1jobs Scraper</b></a><br>Scrape jobs from s1jobs.com across Scotland and the UK. Search by keyword, location, or...</td><td>💼 <a href="https://apify.com/abotapi/dice-com-scraper"><b>Dice.com Scraper</b></a><br>Scrape tech job listings from Dice.com by keyword, filters, or URL. Extract job titles...</td></tr>
</table>

👉 [Browse all abotapi scrapers](https://apify.com/abotapi)

### 💬 Support

- 🐞 **Found a bug or a missing field?** Open a ticket on the [Issues tab](https://apify.com/abotapi/nijobs-scraper/issues/open). We usually reply within hours.
- 🛠️ **Need another site, extra fields or a private build?** Email <contact@abotapi.com>.
- ⭐ **Enjoying it?** A quick review on the actor page helps other users find it.

# Actor input Schema

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

search = build searches from keywords + location + filters. url = paste one or more nijobs results-page URLs.

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

Job titles or keywords to search, e.g. Software Developer, Accountant, Nurse. Each keyword runs its own search. Only applies when mode = search.

## `location` (type: `string`):

Optional town, city or county in Northern Ireland to narrow the search, e.g. Belfast, Londonderry, County Antrim. Leave empty to search all of Northern Ireland. Only applies when mode = search.

## `radius` (type: `integer`):

Widen a location search to jobs within this many miles. Values snap to the nearest of 5, 10, 20 or 30 miles (maximum 30). Only applies when mode = search and a location is set.

## `postedWithin` (type: `string`):

Only return jobs posted within this many days. Only applies when mode = search.

## `minSalary` (type: `integer`):

Only return jobs at or above this salary. Read together with Salary period (annual / daily / hourly). Only applies when mode = search.

## `salaryPeriod` (type: `string`):

Which salary rate the Minimum salary value refers to. Only applies when mode = search and Minimum salary is set.

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

Result ordering. Only applies when mode = search.

## `urls` (type: `array`):

Paste one or more nijobs results-page URLs (e.g. https://www.nijobs.com/jobs/software-developer/in-belfast). Multi-URL supported. The keyword/location/filter fields above are ignored in this mode. Left untouched, URL mode scrapes one example of each supported URL shape.

## `fetchDetails` (type: `boolean`):

Fetch each job page to add the full job description, geo coordinates, full postal address, employment type, industry, work type / contract type, validity window and the apply URL. Adds one request per job. Leave on for the richest output.

## `maxPages` (type: `integer`):

Optional safety stop on how many result pages to read per keyword/URL. This does NOT cap the run: leave it empty for unlimited pages and the run is bounded solely by Max items. Set a value only if you also want a per-search page ceiling.

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

The run's single hard cap: maximum total jobs across all searches. Defaults to 20 (also when the field is omitted through the API). Set 0 for unlimited. This is the only default limit; Max pages is unlimited by default and defers to this.

## `proxy` (type: `object`):

Connection used for requests. The default works on any Apify plan, including the free tier.

## `resumeFromRunId` (type: `string`):

Paste a previous run ID or dataset ID to continue a large pull without returning or charging for jobs already collected there. For recurring monitoring of the same search, use Incremental changes below instead.

## `incrementalMode` (type: `boolean`):

For recurring runs, return only NEW, UPDATED and REAPPEARED jobs; jobs unchanged since the last run are not returned or billed. Each job is compared on every field except search position, scrape time, relative posting date, travel time, fingerprint count, backfill flag, new-job flag and list page URL (they stay in the output but never count as a change) and the order of labels. Each row gets changeType, changedFields, firstSeenAt and lastSeenAt; outside incremental mode these four fields are empty. The baseline is kept per State key; changing the search settings or Fetch full job details starts a new baseline unless State key is set.

## `stateKey` (type: `string`):

Incremental mode only. Optional name for this campaign's saved baseline. Leave empty to derive it from the search settings, so each distinct search keeps its own baseline.

## `emitUnchanged` (type: `boolean`):

Incremental mode only. Also return (and bill as normal rows) jobs whose values did not change.

## `emitExpired` (type: `boolean`):

Incremental mode only. Return an EXPIRED row for jobs no longer found (billed like any returned row). Only after a complete scan: a Max items or Max pages cut, a pasted URL that starts at page 2 or later, an early stop or a failed page disables it.

## `ignoreFieldsForChanges` (type: `array`):

Incremental mode only. Extra field names (dotted for nested, e.g. address.city) that never mark a job as UPDATED and are left out of changedFields; they stay in the output. positionOnPage, positionAbsolute, scrapedAt, periodPostedDate, travelTime, fingerprintCount and isBackfilled are always ignored.

## `mcpConnectors` (type: `array`):

Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify, Settings, Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON; the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## Actor input object example

```json
{
  "mode": "search",
  "keywords": [
    "Software Developer"
  ],
  "postedWithin": "any",
  "salaryPeriod": "annual",
  "sortBy": "relevance",
  "urls": [
    "https://www.nijobs.com/jobs/software-developer",
    "https://www.nijobs.com/jobs/software-developer/in-belfast",
    "https://www.nijobs.com/jobs/software-developer/in-county-antrim",
    "https://www.nijobs.com/jobs/in-belfast",
    "https://www.nijobs.com/jobs/accountancy",
    "https://www.nijobs.com/jobs/software-developer/in-belfast?page=2",
    "https://www.nijobs.com/jobs/software-developer?sort=2",
    "https://www.nijobs.com/jobs/software-developer?postedWithin=7",
    "https://www.nijobs.com/jobs/software-developer?salary=40000&salarytypeid=1",
    "https://www.nijobs.com/jobs/software-developer/in-belfast?sort=2&postedWithin=7",
    "https://www.nijobs.com/jobs/software-developer/in-belfast?page=2&sort=2",
    "https://www.nijobs.com/jobs/accountancy/in-belfast/",
    "http://nijobs.com/jobs/marketing",
    "https://www.nijobs.com/jobs/permanent/software-developer",
    "https://www.nijobs.com/jobs/mcs-group?cmpId=1216528&cmp=1"
  ],
  "fetchDetails": true,
  "maxItems": 20,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "GB"
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "ignoreFieldsForChanges": [],
  "maxNotifyListings": 50
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

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

No description

## `changes` (type: `string`):

No description

## `summary` (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 = {
    "mode": "search",
    "keywords": [
        "Software Developer"
    ],
    "urls": [
        "https://www.nijobs.com/jobs/software-developer",
        "https://www.nijobs.com/jobs/software-developer/in-belfast",
        "https://www.nijobs.com/jobs/software-developer/in-county-antrim",
        "https://www.nijobs.com/jobs/in-belfast",
        "https://www.nijobs.com/jobs/accountancy",
        "https://www.nijobs.com/jobs/software-developer/in-belfast?page=2",
        "https://www.nijobs.com/jobs/software-developer?sort=2",
        "https://www.nijobs.com/jobs/software-developer?postedWithin=7",
        "https://www.nijobs.com/jobs/software-developer?salary=40000&salarytypeid=1",
        "https://www.nijobs.com/jobs/software-developer/in-belfast?sort=2&postedWithin=7",
        "https://www.nijobs.com/jobs/software-developer/in-belfast?page=2&sort=2",
        "https://www.nijobs.com/jobs/accountancy/in-belfast/",
        "http://nijobs.com/jobs/marketing",
        "https://www.nijobs.com/jobs/permanent/software-developer",
        "https://www.nijobs.com/jobs/mcs-group?cmpId=1216528&cmp=1"
    ],
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "GB"
    },
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "ignoreFieldsForChanges": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/nijobs-scraper").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 = {
    "mode": "search",
    "keywords": ["Software Developer"],
    "urls": [
        "https://www.nijobs.com/jobs/software-developer",
        "https://www.nijobs.com/jobs/software-developer/in-belfast",
        "https://www.nijobs.com/jobs/software-developer/in-county-antrim",
        "https://www.nijobs.com/jobs/in-belfast",
        "https://www.nijobs.com/jobs/accountancy",
        "https://www.nijobs.com/jobs/software-developer/in-belfast?page=2",
        "https://www.nijobs.com/jobs/software-developer?sort=2",
        "https://www.nijobs.com/jobs/software-developer?postedWithin=7",
        "https://www.nijobs.com/jobs/software-developer?salary=40000&salarytypeid=1",
        "https://www.nijobs.com/jobs/software-developer/in-belfast?sort=2&postedWithin=7",
        "https://www.nijobs.com/jobs/software-developer/in-belfast?page=2&sort=2",
        "https://www.nijobs.com/jobs/accountancy/in-belfast/",
        "http://nijobs.com/jobs/marketing",
        "https://www.nijobs.com/jobs/permanent/software-developer",
        "https://www.nijobs.com/jobs/mcs-group?cmpId=1216528&cmp=1",
    ],
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "GB",
    },
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "ignoreFieldsForChanges": [],
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/nijobs-scraper").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 '{
  "mode": "search",
  "keywords": [
    "Software Developer"
  ],
  "urls": [
    "https://www.nijobs.com/jobs/software-developer",
    "https://www.nijobs.com/jobs/software-developer/in-belfast",
    "https://www.nijobs.com/jobs/software-developer/in-county-antrim",
    "https://www.nijobs.com/jobs/in-belfast",
    "https://www.nijobs.com/jobs/accountancy",
    "https://www.nijobs.com/jobs/software-developer/in-belfast?page=2",
    "https://www.nijobs.com/jobs/software-developer?sort=2",
    "https://www.nijobs.com/jobs/software-developer?postedWithin=7",
    "https://www.nijobs.com/jobs/software-developer?salary=40000&salarytypeid=1",
    "https://www.nijobs.com/jobs/software-developer/in-belfast?sort=2&postedWithin=7",
    "https://www.nijobs.com/jobs/software-developer/in-belfast?page=2&sort=2",
    "https://www.nijobs.com/jobs/accountancy/in-belfast/",
    "http://nijobs.com/jobs/marketing",
    "https://www.nijobs.com/jobs/permanent/software-developer",
    "https://www.nijobs.com/jobs/mcs-group?cmpId=1216528&cmp=1"
  ],
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "GB"
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "ignoreFieldsForChanges": []
}' |
apify call abotapi/nijobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/nijobs-scraper"
        }
    }
}
```

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/6qkMfhyL69cMvszhp/builds/zBE4ZmIxvxPt3Is1w/openapi.json
