Seek Jobs Scraper | $2.99 / 1k |
Pricing
from $2.99 / 1,000 results
Seek Jobs Scraper | $2.99 / 1k |
Scrape Seek job ads across Australia and New Zealand. One row per listing with title, company, suburb, salary parsed to min and max, work type, classification, listing date and the full ad text. Export to CSV, JSON or Excel.
Pricing
from $2.99 / 1,000 results
Rating
0.0
(0)
Developer
Raffy
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
What does Seek Jobs Scraper do?
Get every job ad on Seek as a clean spreadsheet row: job title, company, suburb, the advertised salary parsed into salaryMin and salaryMax, work type, industry classification, listing date and the full ad text. It is built for recruiters, job boards and labour-market analysts who need Australian and New Zealand job listings in bulk instead of one browser tab at a time.
Type a keyword and a location - software engineer in Sydney NSW, registered nurse in Auckland - and scrape Seek jobs into JSON, CSV or Excel, or read them straight from the Apify API. The Actor covers both Seek sites, seek.com.au (Australia) and seek.co.nz (New Zealand), so it doubles as a practical Seek API alternative and a general Australian job listings API when you have no documented feed to build on.
No headless browser, no residential proxies, no scraper to maintain. The default 20-job run, descriptions included, finished in 9.9 seconds on the Apify platform.
It does not log in, does not read anything behind a paywall or a login wall, and does not work around access controls. It reads only the job data Seek serves publicly to anonymous visitors.
Use cases for this Seek scraper
- Recruitment agency building a client pipeline. Pull every engineering ad posted in Melbourne VIC in the last 7 days, sort by
companyandlistingDate, and call the employers who started hiring this week - ten open roles is a budget you can see. - Market researcher tracking salary trends.
salaryMin,salaryMaxandsalaryPeriodare parsed from the advertised label, so you can chart pay bands per role, suburb orclassification, then re-run the same search monthly to build a time series. - Job board or aggregator seeding listings. Schedule one run per keyword, export the ads with
descriptionTextandbulletPoints, and fill a niche board (nursing, trades, remote tech) with complete, first-party ad copy instead of thin stubs. - Sales team finding companies that are hiring. A company advertising for Salesforce admins is a company buying Salesforce services. Filter on
classification,subClassificationandlistingDateto hand your reps a weekly list of accounts with fresh hiring intent. - Workforce or policy analyst measuring a regional labour market. Group by
area,countryCodeandclassificationto track vacancy volumes across Sydney, Auckland or an entire state over time. - Careers product exporting job ads to CSV. Power a job-matching feature, a "who is hiring for X" newsletter or an internal dashboard from a scheduled dataset export.
What data you get from every Seek job ad
One row per job ad. Every column below exists in the dataset schema; the Overview table view shows title, company, location, salary, workType, listingDate, url, status, error and scrapedAt.
Row status and provenance
| Field | Type | Description |
|---|---|---|
url | string | Public job page, e.g. https://www.seek.com.au/job/94002068. On not_found / error rows this is the request that failed. |
status | string | ok, not_found or error (see the table below). |
error | string | Reason when status is not ok. Absent on ok rows. |
scrapedAt | string | ISO 8601 time the row was extracted. |
site | string | seek.com.au or seek.co.nz. |
keyword | string | The search keyword that produced this row. |
Job and employer
| Field | Type | Description |
|---|---|---|
id | string | Seek job id, e.g. 94002068. |
title | string | Job title as advertised. |
company | string | Advertiser or employer name shown on the ad. Absent on ads posted as "Private Advertiser". |
companyProfileUrl | string | Seek company profile URL, when the employer has one. |
Location
| Field | Type | Description |
|---|---|---|
location | string | Location label as displayed, e.g. Surry Hills, Sydney NSW. |
area | string | Metropolitan area or region part of the location, e.g. Sydney NSW. |
suburb | string | Suburb part of the location, when the ad has one. |
countryCode | string | AU or NZ. |
Pay
| Field | Type | Description |
|---|---|---|
salary | string | Salary exactly as the advertiser wrote it, e.g. $160k to $180k + super. Absent when the ad shows no salary. |
salaryMin | number | Lower bound parsed from salary (best effort). |
salaryMax | number | Upper bound parsed from salary (best effort). |
salaryPeriod | string | hour, day, week, month or year, when it can be read from the label. |
Role details
| Field | Type | Description |
|---|---|---|
workType | string | Full time, Part time, Contract/Temp or Casual/Vacation. |
workArrangement | string | Remote, Hybrid or On-site, when the advertiser set it. |
classification | string | Seek industry classification, e.g. Information & Communication Technology. |
subClassification | string | Seek sub-classification, e.g. Engineering - Software. |
Dates and listing lifecycle
| Field | Type | Description |
|---|---|---|
listingDate | string | ISO 8601 time the ad was listed. |
expiresAt | string | ISO 8601 expiry time. Needs includeDescription. |
isExpired | boolean | Whether Seek marks the ad as expired. Needs includeDescription. |
listingStatus | string | Seek's own listing status, e.g. Active. Not the same thing as the row status. Needs includeDescription. |
Ad copy
| Field | Type | Description |
|---|---|---|
teaser | string | Short teaser shown in the search results. |
bulletPoints | array | Up to three highlight bullets from the ad. |
descriptionText | string | Full job description as plain text, paragraphs and bullets preserved. Needs includeDescription. |
descriptionHtml | string | The description in the advertiser's original HTML. Needs includeDescriptionHtml. |
descriptionError | string | Set when only the description could not be fetched; the rest of the row is still valid list-level data. |
Ad placement flags
| Field | Type | Description |
|---|---|---|
isFeatured | boolean | Seek's featured flag. |
isPremium | boolean | The ad uses Seek's Premium display type. |
isStandOut | boolean | The ad uses Seek's StandOut display type. |
displayType | string | Raw Seek display type, e.g. standard. |
isLinkOut | boolean | Applying happens on the advertiser's own site instead of on Seek. |
A missing field is honest: it means Seek did not publish that value for this ad, never a guess. Deliberately not collected: recruiter names, e-mail addresses, phone numbers and any other contact data - see the legal notice at the end.
Result status (tri-state output)
status | Meaning | Billed? |
|---|---|---|
ok | The job was found and extracted. | Yes |
not_found | Seek answered, but nothing matches the search (no jobs for that keyword, location and filter combination). | No |
error | Seek could not be read after retries (network error, challenge page, or an endpoint change). error says why. | No |
If only a job's description fails, you still get the full list-level row with status: ok and a descriptionError explaining the gap - you never lose a job because one extra request failed.
How to scrape Seek job ads with this Actor
- Open the Actor in Apify Console and click Try for free.
- Type one or more Keywords (one per line), exactly as you would type them into the Seek search box.
- Set the Location (
Sydney NSW,Auckland,All Australia, ...) and pick the Seek site. - Set Maximum results - start with the default 20 to see the output shape - and optionally the posted-within, minimum-salary and work-type filters.
- Click Start. The default input finishes in well under a minute; rows appear in the dataset as they are scraped.
- Open the Output tab or Export the dataset as JSON, CSV, Excel, XML or HTML.
To automate it, use the API tab (Node.js, Python, curl examples) or add a Schedule.
Input
Every field is optional - the prefilled values already produce a complete run. See the Input tab for the full schema.
| Field | Type | Default | When to change it |
|---|---|---|---|
keywords | array of strings | ["software engineer"] | Set the roles you want. Each keyword is a separate search and a job found under several keywords is returned once; leave the list empty to take every job in the location. |
location | string | Sydney NSW | Narrow or widen the geography: Melbourne VIC, Brisbane QLD, Auckland, All Australia, All New Zealand. Leave it empty for the whole country of the selected site. |
site | string | seek.com.au | Switch to seek.co.nz for New Zealand ads; locations, currency labels and classifications follow the site you pick. |
maxItems | integer | 20 | Raise it for production pulls, lower it while you shape the input. It counts rows across all keywords and is your main spending cap. |
includeDescription | boolean | true | Turn it off for the fastest, list-level-only runs. With it on, each job costs one extra request and gains descriptionText, expiresAt, isExpired, listingStatus and a salary label when the search result had none. |
includeDescriptionHtml | boolean | false | Turn it on when you need the advertiser's original markup in descriptionHtml (formatting, links). It roughly doubles the row size. |
postedWithinDays | integer | empty (any date) | Set 1 on a daily schedule, or 7 for a weekly market snapshot, to collect only fresh ads. Accepts 1-31. |
salaryMin | integer | empty (no filter) | Set it to skip ads below a pay threshold. Seek applies the filter itself, so ads without a disclosed salary are excluded by Seek. |
workType | string | empty (all types) | Restrict to Full time, Part time, Contract/Temp or Casual/Vacation when only one employment model matters. |
proxyConfiguration | object | Apify Proxy off | Leave it off - the Actor works from datacenter IPs. Enable the Apify Proxy datacenter group only if runs start returning error rows. |
Example input (exactly the prefilled default):
{"keywords": ["software engineer"],"location": "Sydney NSW","site": "seek.com.au","maxItems": 20,"includeDescription": true,"includeDescriptionHtml": false,"proxyConfiguration": { "useApifyProxy": false }}
Output
You can download the dataset as JSON, CSV, Excel, XML or HTML. Here is a real row from a run of the example input above, with descriptionText trimmed for readability (in the dataset it is the whole ad, 3,192 characters):
{"url": "https://www.seek.com.au/job/94002068","status": "ok","scrapedAt": "2026-09-08T10:34:11.303Z","id": "94002068","title": "Robotics Software Engineer","company": "AEY & Associates","location": "Sydney NSW","area": "Sydney NSW","countryCode": "AU","salary": "$160k to $180k + super","salaryMin": 160000,"salaryMax": 180000,"salaryPeriod": "year","workType": "Full time","workArrangement": "Hybrid","classification": "Information & Communication Technology","subClassification": "Engineering - Software","listingDate": "2026-08-16T09:24:44Z","expiresAt": "2026-09-15T09:24:00.000Z","isExpired": false,"listingStatus": "Active","teaser": "Build intelligent software for one of Australia's most exciting deep-tech engineering companies.","bulletPoints": ["Solve complex problems spanning robotics, AI, computer vision, and software","Experts across software, hardware, algorithms, sensing, and machine learning","High ownership, challenging technical problems, and real-world impact"],"descriptionText": "We're looking for experienced Software Engineers who enjoy solving difficult technical problems and building systems that perform reliably out in the field.\n\nWhat You'll Be Working On\n\n- Designing and building production-quality software for complex autonomous systems\n\n- Solving challenging engineering problems across robotics, sensing, AI, data processing, and distributed software\n\n...","isFeatured": false,"isPremium": false,"isStandOut": false,"displayType": "standard","isLinkOut": false,"site": "seek.com.au","keyword": "software engineer"}
A search that matches nothing produces one free row instead of an empty dataset:
{"url": "https://www.seek.com.au/api/jobsearch/v5/search?siteKey=AU-Main&where=Sydney+NSW&page=1&keywords=underwater+basket+weaver","status": "not_found","error": "No jobs on seek.com.au match \"underwater basket weaver\" in Sydney NSW with the given filters","scrapedAt": "2026-09-08T10:34:12.104Z"}
How much does it cost to scrape Seek?
This Actor uses pay-per-event pricing:
| Event | Price | Charged when |
|---|---|---|
| Actor start | $0.005 per run | Once when the run starts. The platform charges one event per GB of memory and the Actor runs on 1 GB, so this is one event. |
| Result | $0.00299 per job | One record with status: ok was saved to the dataset. |
1,000 job ads cost about $3.00 ($0.005 to start plus 1,000 x $0.00299). You are never charged for a row with status not_found or error, and never for a duplicate: a job that turns up under several keywords or on two pages of the same search is emitted once, because the Actor deduplicates on the Seek job id for the whole run. The free Apify plan's $5 of monthly credit covers about 1,670 jobs in a single run.
You can cap spending per run with Maximum results and with the run's Max total charge option. When the charge limit is reached the Actor stops gracefully and keeps everything it has already saved.
How it compares
This Actor is deliberately narrow and fast. It reads Seek's own public JSON over plain HTTP, which is why a 20-job run takes seconds rather than minutes and why it needs no browser, no proxy and no login. If you want broad Seek coverage across Australia and New Zealand with parsed salaries, full ad text and a tri-state row you can trust inside an automated pipeline, this is a good fit.
It is not for you if you need candidate data, applications or anything inside a Seek employer account; if you need Seek's other regional brands; if you need a vendor-backed, contractually stable data feed; or if you want one Actor that also covers other job boards. It reads a single public source, and says so honestly when that source changes.
Integrations, exports and API access
Results export to CSV, JSON, Excel, XML and HTML from the Output tab or the dataset API. From there, Apify integrations and webhooks push the same rows into Google Sheets, Airtable or a CRM, plus Slack, Amazon S3 or your own endpoint - directly, or through Zapier, Make and n8n. Add a Schedule and yesterday's ads land in your sheet every morning.
The Actor can also be called from the Apify API (Node.js, Python and curl snippets are on the API tab), from the Apify MCP server, or by any AI agent that can call a tool: the inputs are plain strings and numbers, and every row carries status and error, so an agent can tell an empty search apart from a failure without parsing prose.
Tips
- Keep
maxItemssmall while you shape your input, then raise it. One keyword can return thousands of ads. - Put several keywords in one run instead of running the Actor once per keyword: you pay the start fee once, and duplicates across keywords are removed automatically.
- Turn
includeDescriptionoff when you only need the list-level columns. That roughly halves the number of requests. - Use
postedWithinDays: 1on a daily schedule to collect only the ads posted since yesterday. salaryis free text written by the advertiser. Filter onsalaryMin/salaryMaxfor analysis and fall back tosalarywhen they are empty - labels such asCompetitivecannot be parsed into numbers.
Limitations
- Seek publishes no documented public API. This Actor reads the same JSON endpoints the Seek website itself calls. They are undocumented, are covered by no stability promise, and can change without notice; when that happens rows come back as
errorand the Actor is fixed quickly (report it in the Issues tab with the run ID). - Australia and New Zealand only.
seek.com.auandseek.co.nzare supported. Seek's other regional brands (Jobstreet, Jobsdb) are not. - About 5,000 ads per keyword per run. Each keyword is paged 100 ads at a time for at most 50 pages. Split deeper pulls by keyword, location or
postedWithinDaysacross several runs. - Descriptions require
includeDescription. With it off,descriptionText,descriptionHtml,expiresAt,isExpiredandlistingStatusare absent, because the search endpoint does not carry them. With it on, every job costs one extra request. - Salary appears only when the advertiser disclosed it. Many ads show no salary at all, and
salaryMin/salaryMaxare a best-effort parse of a free-text label, not a number Seek provides. - No candidate data and no applications. The Actor reads job ads only; it cannot see applicants, employer dashboards or anything behind a Seek login.
- A row is a snapshot. Ads are edited and removed constantly, so re-run the Actor to refresh. A job that disappears between the search and the detail request is still delivered as an
okrow carrying adescriptionError.
FAQ
Do I need a Seek login, an account or an API key? No. The Actor reads the same public job data an anonymous visitor sees, so all you need is an Apify account. There is no login step and no key to manage.
How do I get more results? Raise maxItems - it is the only limit that stops a run early. Beyond about 5,000 ads per keyword, add more keywords, split the search by location, or run a daily schedule with postedWithinDays: 1 and let the results accumulate in one dataset.
How often does the data change? Constantly. Seek ads are posted, edited and expired every hour, and most listings run for about 30 days. For a moving market picture, schedule a daily or weekly run rather than treating one export as permanent.
What happens if Seek changes its site? Rows come back with status: error and a reason instead of silently wrong data, so your pipeline can alert on it. Report it in the Issues tab with the run ID and the Actor is updated; you are not billed for error rows in the meantime.
Does it work for New Zealand? Yes. Set site to seek.co.nz and use a New Zealand location such as Auckland, Wellington or All New Zealand.
Can I use this Actor from an AI agent or MCP client? Yes. Inputs are plain strings and numbers, every row is self-describing (status plus error), and results can be fetched through the dataset API or the Apify MCP server.
Why did I get fewer rows than maxItems? The search matched fewer jobs than you asked for, or the run hit your Max total charge limit. The run log says which - look for "Stopping gracefully".
Why is a field missing from a row? Optional fields are omitted when Seek does not publish them for that ad - many ads carry no salary, no suburb or no work arrangement. If a field that should always be there is missing, open an issue in the Issues tab with the run ID.
Legal and data-protection notice
Job advertisements are business data: a company, a role, a location, a pay range and ad copy written for the public to read. This Actor extracts only that, and only from pages Seek publishes publicly. It does not log in, does not read anything behind an access control, and does not attempt to defeat one.
No recruiter names, e-mail addresses or phone numbers are collected. Seek's job endpoint can return contact details (phoneNumber, contactMatches); this Actor's query deliberately does not ask for them, and no output column holds contact data, a personal profile or a photo. The only free text in a row is the advertiser's own ad copy in teaser, bulletPoints and descriptionText/descriptionHtml: if an advertiser typed a contact detail into the body of their ad it will be in there, so turn includeDescription off if you do not want the ad body at all.
Your results could still contain personal data. Personal data is protected by the GDPR in the European Union, by the Privacy Act 1988 in Australia, by the Privacy Act 2020 in New Zealand, and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you are unsure whether your reason is legitimate, consult your lawyers. You are responsible for complying with Seek's terms of service and applicable law when using the extracted data.
This Actor is an independent tool. It is not affiliated with, endorsed by or sponsored by Seek Limited or its owners. All trademarks belong to their respective owners.