# SEEK Jobs Scraper — AU/NZ Leads & Intelligence (`trakk/seek-job-scraper`) Actor

Scrape SEEK Australia and New Zealand jobs with salaries, descriptions, skills, visa signals, application questions, and company/recruiter profiles. Extract public emails and phones where published. Track new, updated, reposted, reappeared, and expired roles.

- **URL**: https://apify.com/trakk/seek-job-scraper.md
- **Developed by:** [Kelopr\_bk](https://apify.com/trakk) (community)
- **Categories:** Jobs, Automation, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 seek 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.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## SEEK Jobs Scraper — AU/NZ Leads & Intelligence

Turn SEEK searches and job URLs into structured Australia and New Zealand hiring data. Collect titles, employers, locations, salaries, work arrangements, classifications and dates; add complete descriptions, public contacts, company profiles, skills, visa-sponsorship signals and recurring job-change monitoring when you need them.

Use the Actor for recruitment, lead generation, salary research, job-board datasets, workforce planning, competitor hiring analysis, remote-work studies and technology-demand intelligence.

### 🚀 Your first run

1. Open **Input** and keep **What do you want to scrape? → Search jobs**.
2. Choose **Australia** or **New Zealand**.
3. Under **Search queries**, enter one phrase, for example `software engineer`.
4. Enter a location such as `All Australia`, `All Sydney NSW`, `Auckland` or `All New Zealand`.
5. Set **Maximum jobs per search** to `3` for a small first run.
6. Leave **Fetch full job details** off for a quick overview, or enable it for descriptions, contacts, application questions, company data and job intelligence.
7. Click **Start**, open **Output**, choose a table and export JSON, CSV or Excel.

Already have job URLs? Select **Job details from URLs**, paste them into **Direct SEEK job URLs**, and start the run.

```text
Keyword + location ──→ Search jobs ──→ Job cards, salaries and classifications
                                  └─→ Full details enabled
                                           ↓
                       Descriptions · contacts · companies · skills · visa signals

SEEK search URLs ─────→ Preserve selected search filters ──→ Paginated job results

Direct job URLs ──────→ Complete records for specific AU/NZ jobs

Recurring search ─────→ Incremental mode ──→ NEW · UPDATED · REPOST · EXPIRED
```

### 🎛️ Choose what to collect

| Workflow | Input | What you get |
|---|---|---|
| Search jobs | `scrapeType: "search"` | Job IDs, titles, companies, locations, displayed salaries, work types, arrangements, classifications, dates, teasers, bullets and URLs. |
| Search with full details | `scrapeType: "search"` + `includeJobDetails: true` | Search fields plus descriptions, expiry, application questions, public contacts, company/recruiter information, skills and visa evidence. |
| SEEK search URLs | Add URLs to `searchUrls` | Jobs from one or more complete SEEK searches, including the filters encoded in those URLs. |
| Direct job URLs | `scrapeType: "jobDetails"` | Complete records for specific seek.com.au and seek.co.nz jobs. |
| Incremental monitoring | `incrementalMode: true` | NEW, UPDATED, UNCHANGED, REAPPEARED, REPOST and EXPIRED classifications across recurring runs. |

Fast search is ideal for market scans and large datasets. Enable full details when you need job text, contacts, application questions, company intelligence or description-based analysis.

### ▶️ Ready-to-use inputs

#### Quick Australian job search

```json
{
  "scrapeType": "search",
  "country": "AU",
  "searchQueries": ["software engineer"],
  "location": "All Australia",
  "includeJobDetails": false,
  "maxItems": 10,
  "maxPagesPerSearch": 2
}
```

#### Full Sydney technology-job audit

```json
{
  "scrapeType": "search",
  "country": "AU",
  "searchQueries": ["software engineer", "data engineer"],
  "location": "All Sydney NSW",
  "classificationId": "6281",
  "includeJobDetails": true,
  "maxItems": 50,
  "maxPagesPerSearch": 3,
  "maxConcurrency": 8
}
```

#### New Zealand remote roles

```json
{
  "scrapeType": "search",
  "country": "NZ",
  "searchQueries": ["software engineer"],
  "location": "All New Zealand",
  "workArrangement": "3",
  "sortMode": "ListedDate",
  "dateRange": 14,
  "includeJobDetails": true,
  "maxItems": 25
}
```

#### Public recruiter contacts

Contact fields are returned only when a job advert publishes them.

```json
{
  "scrapeType": "search",
  "country": "AU",
  "searchQueries": ["recruitment consultant"],
  "location": "Sydney NSW",
  "includeJobDetails": true,
  "maxItems": 25
}
```

#### Visa-sponsorship research

```json
{
  "scrapeType": "search",
  "country": "AU",
  "searchQueries": ["visa sponsorship"],
  "location": "All Australia",
  "includeJobDetails": true,
  "maxItems": 50
}
```

#### Inspect specific jobs

Replace these illustrative IDs with current SEEK job URLs.

```json
{
  "scrapeType": "jobDetails",
  "jobUrls": [
    "https://www.seek.com.au/job/12345678",
    "https://www.seek.co.nz/job/87654321"
  ],
  "maxConcurrency": 4
}
```

#### Monitor new and changed jobs

Use the same `stateKey` for every recurring run of the same search.

```json
{
  "scrapeType": "search",
  "country": "AU",
  "searchQueries": ["data engineer"],
  "location": "All Australia",
  "sortMode": "ListedDate",
  "incrementalMode": true,
  "stateKey": "data-engineer-au",
  "emitUnchanged": false,
  "emitExpired": false,
  "skipReposts": false,
  "maxItems": 500,
  "maxPagesPerSearch": 25
}
```

### 📥 Useful input settings

| Setting | How to use it |
|---|---|
| `scrapeType` | `search` for queries/search URLs or `jobDetails` for specific job URLs. |
| `country` | `AU` for Australia or `NZ` for New Zealand. Query searches use this market; direct URLs retain their own market. |
| `searchQueries` | One literal job title, skill or company phrase per entry. Multiple entries run separate searches in one Actor run. |
| `location` | City, suburb, region, state or nationwide label such as `All Australia` or `All New Zealand`. |
| `searchUrls` | Complete SEEK search-result URLs. Use this when you already configured a search on SEEK. |
| `includeJobDetails` | Adds descriptions, contacts, application questions, company/recruiter data, skills and visa signals. Default: off. |
| `jobUrls` | Direct seek.com.au or seek.co.nz job URLs used in Job details mode. AU and NZ URLs can be mixed. |
| `sortMode` | `KeywordRelevance` or `ListedDate`. |
| `dateRange` | Only jobs listed within the last N days. `0` means any time. |
| `workType` | Any, Full time (`242`), Part time (`243`), Contract/Temp (`244`) or Casual/Vacation (`245`). |
| `workArrangement` | Any, On-site (`1`), Hybrid (`2`) or Remote (`3`). |
| `classificationId` | Optional numeric SEEK classification ID, for example `6281` for Information & Communication Technology. |
| `subClassificationId` | Optional numeric sub-classification ID; requires a parent classification ID. |
| `salaryMin`, `salaryMax` | Optional salary band in AUD or NZD. |
| `salaryType` | Interpret the salary filter as `annual` or `hourly`. |
| `radiusKm` | Search distance around a specific location. Default: 50 km. |
| `maxItems` | Maximum successfully saved jobs per query or search URL. Default: 20. |
| `maxPagesPerSearch` | Page safety cap per query or search URL. Default: 5. |
| `maxConcurrency` | Maximum number of full job records processed at the same time. Default: 8. |
| `incrementalMode` | Enable persistent NEW/UPDATED/REAPPEARED/REPOST/EXPIRED tracking. |
| `stateKey` | Stable identifier for one monitored search. Leave blank to derive it from the current inputs. |
| `emitUnchanged` | Include jobs whose tracked content did not change. Default: off. |
| `emitExpired` | Include jobs no longer present after a complete monitored scan. Default: off. |
| `skipReposts` | Omit new IDs that match an inactive title + company + location fingerprint. Default: off. |

`maxItems` counts unique successfully saved jobs. Duplicate, unavailable, failed, unchanged and skipped-repost candidates do not consume the saved-result allowance.

### 📦 Core job fields

The default dataset has one row per job. Fields remain flat and friendly to JSON, CSV, Excel and databases.

#### Identity and search context

| Field | Meaning |
|---|---|
| `recordType` | Record type; job rows use `job`. |
| `jobId` | Numeric SEEK job ID. |
| `globalId` | Market-safe identity such as `seek:au:12345678`. |
| `title` | Job title. |
| `jobUrl` | Canonical job URL. |
| `sourceCountry` | `AU` or `NZ`. |
| `searchQuery`, `searchLocation` | Query and location that produced the result. |
| `searchSourceUrl` | Related SEEK search URL. |
| `searchResultPosition` | Position in the collected search result page. |
| `searchTotalCount` | Total matching jobs reported for the search. |

#### Employer

| Field | Meaning |
|---|---|
| `companyName` | Primary company/advertiser name. |
| `searchCompanyName`, `detailCompanyName` | Separate names published in summary and complete-job data when they differ. |
| `advertiserName`, `advertiserId` | Advertiser identity. |
| `employerId` | SEEK employer identifier. |
| `companyProfileId` | Company-profile identifier when available. |
| `advertiserVerified` | Advertiser verification status when published. |
| `advertiserRegistrationDate` | Advertiser registration timestamp when available. |
| `isPrivateAdvertiser` | Whether the advert uses a private advertiser. |
| `employerLogoUrl` | Employer/listing logo. |

#### Location and work arrangement

| Field | Meaning |
|---|---|
| `location` | Complete display location. |
| `locationArea`, `locationCity` | Broader area and city. |
| `locationSuburb`, `locationState` | Suburb and state/region. |
| `locationPostcode` | Postcode when published. |
| `locationCountry`, `locationCountryCode` | Country and `AU`/`NZ` code. |
| `locationHierarchy` | Broader location labels associated with the job. |
| `workTypes` | Full time, part time, contract/temp or casual/vacation. |
| `workArrangements` | Published on-site, hybrid or remote labels. |
| `remoteType` | Normalized `onsite`, `hybrid`, `remote` or empty value. |

#### Classification and promotion

| Field | Meaning |
|---|---|
| `classification`, `classificationId` | Parent SEEK job category and ID. |
| `subClassification`, `subClassificationId` | Sub-category and ID. |
| `roleId` | Normalized SEEK role identifier. |
| `isFeatured` | Featured/promoted indicator. |
| `displayType`, `displayStyleSearch` | Available listing presentation labels. |

#### Dates and status

| Field | Meaning |
|---|---|
| `listingDate` | Primary publication timestamp. |
| `searchListingDate`, `detailListingDate` | Separate summary and complete-job timestamps when available. |
| `listingDateDisplay` | Human-readable age such as `2d ago`. |
| `expiresAt` | Advert expiry timestamp. |
| `status` | Current advert status. |
| `isExpired` | Expiry flag. |
| `isLinkOut` | Whether the application continues on another website. |
| `scrapedAt` | Collection timestamp. |

### 💰 Salary fields

| Field | Meaning |
|---|---|
| `salary` | Primary salary text. |
| `searchSalary`, `detailSalary` | Separate summary and complete-job salary text when available. |
| `salaryMin`, `salaryMax` | Numeric salary boundaries. |
| `salaryCurrency` | `AUD` or `NZD`. |
| `salaryPeriod` | `annual`, `monthly`, `weekly`, `daily` or `hourly`. |
| `salaryIncludesSuper` | Whether the displayed amount explicitly includes superannuation; empty when silent. |
| `salaryParseConfidence` | Confidence that the displayed compensation was fully normalized. |

Salary fields are normalized only from compensation information published in the advert. Missing salary data is not estimated. A single “up to” amount can produce only a maximum value; a “from” amount can produce only a minimum.

### 📄 Complete job content

Enable `includeJobDetails` or use direct job URLs to add:

| Field | Meaning |
|---|---|
| `teaser` | Short job summary. |
| `bulletPoints` | Highlight bullets associated with the advert. |
| `descriptionText` | Complete readable description. |
| `descriptionHtml` | Original formatted description. |
| `descriptionWordCount` | Word count of the collected description. |
| `applicationQuestions` | Published application/screening questions. |
| `applicationQuestionCount` | Number of collected application questions. |
| `applyUrl` | Public application link. |
| `shareUrl` | Public share link. |
| `hasRoleRequirements` | Whether role requirements are published. |
| `employerCoverImageUrl` | Advert/employer cover image when available. |
| `employerVideoUrl`, `employerVideoTitle` | Employer video information when published. |
| `detailStatus` | `ok` for a complete detail result or `not_requested` for summary-only results. |

### 📬 Public emails, phones and links

Full job records can include contact information explicitly published in the advert.

```text
Published job contact information
              ↓
Email · phone · external website · social profile · application link
              ↓
Structured contact fields in the Contacts output table
```

| Field | Meaning |
|---|---|
| `contactName`, `contactNames` | One compact contact name and all distinct names when available. |
| `contactEmail`, `emails` | One compact email and all distinct public emails. |
| `contactPhone`, `phoneNumbers` | One compact telephone value and all distinct published numbers. |
| `externalUrls` | External websites linked from the advert. |
| `socialProfileUrls` | Published LinkedIn, Facebook, Instagram, X, YouTube or TikTok profiles. |
| `applyUrl` | Public job-application URL. |
| `contactAvailability` | `email`, `phone`, `email_and_phone` or `none`. |

Contacts are conditional. Many jobs do not publish an email address or phone number. Missing contacts remain empty and are never fabricated. Handle published business and recruiter contact data responsibly.

### 🏢 Company and recruiter intelligence

When SEEK publishes an employer or recruiter profile, full job records can include:

#### Company fields

| Field | Meaning |
|---|---|
| `companyProfileName`, `companyProfileId` | Company profile identity. |
| `companyProfileUrl`, `companyProfileSlug` | Company profile link and slug when available. |
| `companyIndustry` | Published industry. |
| `companySize` | Published employee-size range. |
| `companyWebsite` | Company website. |
| `companyDescription` | Company overview. |
| `companyLogoUrl`, `companyCoverImageUrl` | Company media. |
| `companyReviewRating`, `companyReviewCount` | Published rating and review count when available. |
| `companyPerks` | Published perks and benefits. |
| `companyTags` | Available company tags. |
| `companyJobsUrl` | Link to other jobs from the employer. |

#### Recruiter fields

| Field | Meaning |
|---|---|
| `recruiterName` | Recruiter/profile name. |
| `recruiterRating`, `recruiterReviewCount` | Published recruiter rating and review count. |
| `recruiterContactNumber` | Published recruiter telephone number. |
| `recruiterAgencyName`, `recruiterAgencyWebsite` | Recruitment agency details. |
| `recruiterCountry`, `recruiterState`, `recruiterCity`, `recruiterPostcode` | Published recruiter location. |
| `recruiterSpecialisations` | Recruitment specialisations. |
| `recruiterPlacementCount` | Published placement count when available. |

Profile coverage varies. Private advertisers and employers without completed profiles can return empty company or recruiter fields while retaining the job record.

### 🧠 Job intelligence

#### Skills

`detectedSkills` lists technology and platform terms present in the complete job description. Covered terms include:

- Languages: Python, Java, JavaScript, TypeScript, C#, C++, Go, Rust, PHP, Ruby, Swift and Kotlin.
- Web frameworks: React, Angular, Vue.js, Node.js, Django, Flask, FastAPI and Spring.
- Data: SQL, PostgreSQL, MySQL, MongoDB, Redis, Kafka, Spark, Snowflake and Databricks.
- Cloud and operations: AWS, Azure, Google Cloud, Docker, Kubernetes, Terraform, Git, CI/CD and Linux.
- Analytics and business platforms: Power BI, Tableau, Salesforce, SAP and Oracle.
- AI: machine learning, generative AI and large language model terminology.

Only matched terms are returned. The Actor does not invent a skill from a job category alone.

#### Seniority

| Field | Meaning |
|---|---|
| `seniority` | `intern`, `entry`, `senior`, `lead`, `staff`, `principal`, `manager`, `director`, `vp`, `executive` or `unspecified`. |
| `senioritySource` | Whether the matching phrase came from the title or description. |
| `seniorityEvidence` | The exact matched seniority phrase. |

#### Visa sponsorship

| Value | Meaning |
|---|---|
| `explicit_sponsorship` | The advert explicitly says sponsorship is available. |
| `open_to_sponsorship` | The advert says sponsorship may be considered. |
| `no_sponsorship` | The advert explicitly rejects sponsorship or requires unrestricted work rights. |
| `not_mentioned` | No supported sponsorship statement was found. |

`visaSponsorshipEvidence` preserves the relevant wording so the classification can be reviewed. This is a text signal, not immigration or legal advice.

#### Data quality

| Field | Meaning |
|---|---|
| `dataCompletenessScore` | Percentage of important job fields populated. |
| `parseConfidence` | Overall confidence in the normalized job record. |
| `parseWarnings` | Specific missing or partially normalized fields. |
| `contentHash` | Stable content identifier for change tracking. |
| `fingerprintHash` | Title + company + location fingerprint for repost detection. |

### ♻️ Incremental job monitoring

Incremental mode remembers the previous state of one monitored search. Keep the same `stateKey` across recurring runs.

| Change type | Meaning |
|---|---|
| `NEW` | Job ID observed for the first time. |
| `UPDATED` | Important tracked job content changed. |
| `UNCHANGED` | No tracked content changed. Omitted unless `emitUnchanged` is enabled. |
| `REAPPEARED` | The same job ID returned after becoming inactive. |
| `REPOST` | A new job ID matches an inactive title + company + location fingerprint. |
| `EXPIRED` | A previously active job is absent from a fully completed monitored scan. |

| Field | Meaning |
|---|---|
| `changeType` | Current incremental classification. |
| `firstSeenAt`, `previousSeenAt`, `lastSeenAt` | Observation timestamps. |
| `expiredAt` | Time the job was confirmed absent from a complete scan. |
| `isRepost`, `repostOfId`, `repostDetectedAt` | Repost detection values. |
| `stateKey` | Monitored search identity. |

**Expired jobs require a complete scan.** If a run stops at `maxItems`, `maxPagesPerSearch`, a spending limit or a source failure, unseen jobs are not marked expired. This prevents limited runs from creating false expiry records.

### 📊 Where to find your data

The default dataset stores one flat row per job. Output views organize the same records for different workflows.

| Output table | Contents |
|---|---|
| Jobs | IDs, titles, companies, countries, locations, salaries, work arrangements, seniority, classifications, dates, URLs and confidence. |
| Full details | Status, expiry, application questions, full descriptions, media, employer data and links. |
| Contacts | Contact names, emails, phones, websites, social profiles and apply URLs. |
| Company & recruiter | Company industry, size, website, description, media, reviews/perks and recruiter/agency details. |
| Job intelligence | Skills, seniority evidence, visa evidence, normalized salary and data-quality metrics. |
| Changes | NEW/UPDATED/REPOST/EXPIRED status, observation times, hashes and state key. |

The default key-value store also contains an `OUTPUT` summary with effective options, saved counts, input warnings, duplicate and incremental skips, source failures and per-search stop reasons.

### 🧾 Example full job record

This abbreviated example is fictional. The company, job ID, contact details and URLs are placeholders.

```json
{
  "recordType": "job",
  "jobId": "12345678",
  "globalId": "seek:au:12345678",
  "title": "Senior Software Engineer",
  "companyName": "Demo Technology Pty Ltd",
  "advertiserVerified": true,
  "location": "Sydney NSW",
  "locationCity": "Sydney",
  "locationState": "New South Wales",
  "locationCountryCode": "AU",
  "salary": "$150,000 – $180,000 per year + super",
  "salaryMin": 150000,
  "salaryMax": 180000,
  "salaryCurrency": "AUD",
  "salaryPeriod": "annual",
  "salaryIncludesSuper": false,
  "workTypes": ["Full time"],
  "workArrangements": ["Hybrid"],
  "remoteType": "hybrid",
  "classification": "Information & Communication Technology",
  "subClassification": "Engineering - Software",
  "listingDateDisplay": "2d ago",
  "status": "Active",
  "isExpired": false,
  "teaser": "Build customer-facing services in a collaborative product team.",
  "applicationQuestions": [
    "Which statement best describes your right to work in Australia?",
    "How many years of software engineering experience do you have?"
  ],
  "contactEmail": "jobs@example.com",
  "emails": ["jobs@example.com"],
  "phoneNumbers": ["0412 345 678"],
  "contactAvailability": "email_and_phone",
  "companyIndustry": "Technology",
  "companySize": "201-500 employees",
  "companyWebsite": "https://example.com/careers",
  "detectedSkills": [
    "Python",
    "TypeScript",
    "React",
    "PostgreSQL",
    "AWS",
    "Docker",
    "Terraform"
  ],
  "seniority": "senior",
  "senioritySource": "title",
  "seniorityEvidence": "Senior",
  "visaSponsorship": "not_mentioned",
  "descriptionWordCount": 850,
  "applicationQuestionCount": 2,
  "dataCompletenessScore": 96.4,
  "parseConfidence": 1.0,
  "detailStatus": "ok",
  "jobUrl": "https://www.seek.com.au/job/12345678"
}
```

### 💳 Pricing

The current Store configuration includes platform usage in the event price.

| Plan | Price per 1,000 saved jobs |
|---|---:|
| Free / no discount | $1.00 |
| Starter | $0.90 |
| Scale | $0.80 |
| Business | $0.70 |

An Actor Start event of `$0.00005` applies per run up to 1 GB of memory. Higher memory can charge additional start events according to the current Pricing tab.

Only successfully written job rows trigger the result event. Duplicate, failed and incrementally skipped records are not written as paid job results. The **Pricing** tab is authoritative if prices change.

### ❓ Practical questions

**Why is a field empty?** The job or associated profile may not publish it, or full details may be disabled. Summary-only rows use `detailStatus: not_requested`. Conditional fields remain empty rather than receiving guessed values.

**Are emails and phone numbers guaranteed?** No. Contacts are returned only when published in the advert. Many jobs expose only an application link.

**Does the Actor estimate missing salaries?** No. Numeric salary fields are created only when the advert publishes enough compensation information.

**Why can search and detail values differ?** SEEK can publish a compact value in a search result and a more precise value in the complete job record. Separate `search...` and `detail...` fields preserve both values.

**Are applicant counts included?** No. Applicant count, resume percentage and cover-letter percentage are not returned or estimated.

**What does `visaSponsorship` mean?** It summarizes explicit wording found in the job description. Always review `visaSponsorshipEvidence`; it is not legal advice or confirmation of eligibility.

**How are duplicates handled?** Jobs are deduplicated by market and job ID across all inputs in the same run. Duplicates do not consume `maxItems`.

**Why did incremental mode save zero rows?** If every collected job is `UNCHANGED` and `emitUnchanged` is off, a successful run can intentionally produce no job rows. The `OUTPUT` summary reports the skipped count.

**When is a job marked expired?** Only after a complete scan confirms the previously active job is absent. Limited or failed scans do not create expiry records.

**What happens with incorrect input?** The run finishes with a clear correction and does not add a diagnostic row to the jobs dataset.

**Can one run contain AU and NZ jobs?** Query mode uses one selected market. Direct URL mode can process Australian and New Zealand URLs together.

**What formats are available?** JSON, JSONL, CSV, Excel, XML, RSS and HTML are available through Apify datasets.

### 🔌 API access

Use the same input JSON from your application, command line or automation platform. Keep your Apify token private.

```bash
curl -X POST "https://api.apify.com/v2/acts/trakk~seek-job-scraper/runs" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "scrapeType": "search",
    "country": "AU",
    "searchQueries": ["software engineer"],
    "location": "All Australia",
    "includeJobDetails": true,
    "maxItems": 10
  }'
```

The run response contains the default dataset ID. Use it to download job records or select one of the focused Output views.

### ✅ Responsible use

This Actor collects publicly available job and company information. Use results in accordance with applicable laws, privacy requirements and the terms that apply to your use case. Public recruiter and business contact details must be handled responsibly and must not be used for unlawful or unsolicited activity.

# Actor input Schema

## `scrapeType` (type: `string`):

Search jobs collects listings by keyword or search URL. Job details collects complete records from direct job URLs.

## `country` (type: `string`):

Select seek.com.au or seek.co.nz for query searches. Direct URLs keep their own market.

## `searchQueries` (type: `array`):

One literal job-search phrase per entry, for example software engineer or registered nurse.

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

SEEK location label used with every query, for example All Sydney NSW, Melbourne VIC, Auckland, or All Australia.

## `sortMode` (type: `string`):

Sort query results by SEEK relevance or listing date.

## `dateRange` (type: `integer`):

Only jobs listed within this many days. Use 0 for any time.

## `workType` (type: `string`):

Filter query results by employment type.

## `workArrangement` (type: `string`):

Filter query results by on-site, hybrid, or remote arrangement.

## `classificationId` (type: `string`):

Optional numeric SEEK category ID, for example 6281 for Information & Communication Technology.

## `subClassificationId` (type: `string`):

Optional numeric SEEK sub-category ID. Requires a parent Classification ID.

## `salaryMin` (type: `integer`):

Optional minimum salary in AUD or NZD.

## `salaryMax` (type: `integer`):

Optional maximum salary in AUD or NZD.

## `salaryType` (type: `string`):

Interpret the salary range as annual or hourly values.

## `radiusKm` (type: `integer`):

Search radius in kilometres around a specific location.

## `searchUrls` (type: `array`):

Optional public seek.com.au or seek.co.nz search-result URLs. URL filters and sort options are preserved while pages are collected.

## `includeJobDetails` (type: `boolean`):

Adds full HTML/text, expiry, application questions, contacts, apply URL, company/recruiter profile data, skills, visa evidence, normalized salary, and detailed location fields. One extra request per selected job.

## `jobUrls` (type: `array`):

Used in Job details mode. Paste URLs such as https://www.seek.com.au/job/94231469.

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

Maximum unique successfully saved jobs for each search query or search URL. Filtered, duplicate, and failed records do not consume this allowance.

## `maxPagesPerSearch` (type: `integer`):

Safety cap per search. Reaching this cap is reported as max\_pages rather than source exhaustion.

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

Persist a search snapshot and label rows NEW, UPDATED, REAPPEARED, REPOST, or UNCHANGED across scheduled runs.

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

Optional stable name for this monitored search. Leave blank to derive it from the inputs automatically.

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

When incremental mode is enabled, also save jobs whose tracked content did not change.

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

Emit EXPIRED rows only when every monitored source was exhaustively collected in the run.

## `skipReposts` (type: `boolean`):

Do not emit a new job ID when its title, company, and location match an inactive prior listing.

## `maxConcurrency` (type: `integer`):

Number of job detail pages processed concurrently.

## `maxRetries` (type: `integer`):

Maximum attempts for retryable source errors.

## `proxyConfiguration` (type: `object`):

Connection settings used to retrieve public SEEK pages.

## Actor input object example

```json
{
  "scrapeType": "search",
  "country": "AU",
  "searchQueries": [
    "software engineer"
  ],
  "location": "All Australia",
  "sortMode": "KeywordRelevance",
  "dateRange": 0,
  "workType": "",
  "workArrangement": "",
  "classificationId": "",
  "subClassificationId": "",
  "salaryType": "annual",
  "radiusKm": 50,
  "searchUrls": [],
  "includeJobDetails": false,
  "jobUrls": [],
  "maxItems": 3,
  "maxPagesPerSearch": 1,
  "incrementalMode": false,
  "stateKey": "",
  "emitUnchanged": false,
  "emitExpired": false,
  "skipReposts": false,
  "maxConcurrency": 3,
  "maxRetries": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

No description

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

No description

## `contacts` (type: `string`):

No description

## `company` (type: `string`):

No description

## `intelligence` (type: `string`):

No description

## `incremental` (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 = {
    "scrapeType": "search",
    "country": "AU",
    "searchQueries": [
        "software engineer"
    ],
    "location": "All Australia",
    "includeJobDetails": false,
    "maxItems": 3,
    "maxPagesPerSearch": 1,
    "maxConcurrency": 3,
    "maxRetries": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("trakk/seek-job-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 = {
    "scrapeType": "search",
    "country": "AU",
    "searchQueries": ["software engineer"],
    "location": "All Australia",
    "includeJobDetails": False,
    "maxItems": 3,
    "maxPagesPerSearch": 1,
    "maxConcurrency": 3,
    "maxRetries": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("trakk/seek-job-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 '{
  "scrapeType": "search",
  "country": "AU",
  "searchQueries": [
    "software engineer"
  ],
  "location": "All Australia",
  "includeJobDetails": false,
  "maxItems": 3,
  "maxPagesPerSearch": 1,
  "maxConcurrency": 3,
  "maxRetries": 3
}' |
apify call trakk/seek-job-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,trakk/seek-job-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/IU21301Ng52G7hlO0/builds/MY03ksyohgRpaqtbx/openapi.json
