SEEK Jobs Search Lookup — Postings by Keyword & Location avatar

SEEK Jobs Search Lookup — Postings by Keyword & Location

Pricing

from $0.50 / 1,000 job posting returneds

Go to Apify Store
SEEK Jobs Search Lookup — Postings by Keyword & Location

SEEK Jobs Search Lookup — Postings by Keyword & Location

Run keyword + location job searches on SEEK, Australia's largest job board, and get one clean row per posting — title, company, location, category, pay range (if stated) and link. No login required. You pay per posting returned, and a search that finds nothing is free.

Pricing

from $0.50 / 1,000 job posting returneds

Rating

0.0

(0)

Developer

Adrian Voss

Adrian Voss

Maintained by Community

Actor stats

1

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

You write job searches the way you'd type them into SEEK — developer @ Melbourne VIC — and this actor runs each one against SEEK's own public search API, Australia's largest job board, and returns one clean row per posting: title, company, location, category, pay range (when SEEK displays one), and a permanent link.

No login. No API key. SEEK's search-results page itself is behind a bot wall, but the JSON endpoint that page calls under the hood is not — see "Why this one" below.

Who it's for

The accountable_eel catalogue sells company and hiring intelligence columns for outbound and recruiting. Each actor takes a list of identifiers — domains, company slugs, and here, job searches — and returns one flat, stably-named row per result: the shape a Clay table, an n8n workflow, or an AI agent can consume without post-processing. Pricing is pay-per-event: a fraction of a cent for a row you actually got, and nothing at all for a search that finds nothing. No seat licence, no monthly minimum, no credit system to decode.

This actor is the Australian counterpart to linkedin-jobs-search-lookup: wide-net keyword + location search rather than a per-company listing. The ATS lookups in the same family (greenhouse-jobs-lookup, lever-jobs-lookup and friends) answer "what is this company hiring for" — you bring the company list. This one answers "who is hiring for this role, in this part of Australia" when you don't have the list yet.

Why this one

  • Reaches data a plain page-load can't. seek.com.au's search-results page and every individual job page return HTTP 403 to a direct request — a bot wall. The page's own backing API, www.seek.com.au/api/jobsearch/v5/search, does not: it's the same JSON call your browser makes to render the page, and it answers a plain unauthenticated request with real, live results. No proxy, no browser automation, no CAPTCHA-solving — a control this catalogue will not build regardless (see the top-level rules this portfolio operates under).
  • The filters are real. keywords, where (location) and "posted within" are all genuinely honoured upstream — verified by watching the total-match count actually change per filter (2,495 → 494 → 19 across three narrowing steps on the same search) — not decorative parameters the endpoint silently ignores.
  • You are never billed for the same posting twice. Every posting is deduplicated by its SEEK job ID across the pages of one search and, by default, across every search in the run — an overlapping pair of searches returns, and bills, each posting once.
  • Honest about what's NOT here. SEEK's job-detail page is behind the same bot wall as its search page, with no working JSON alternative found — so there is no full-description enrichment on this actor. teaser, SEEK's own one-line summary, is what every row carries instead, and it's labelled as a teaser, not sold as a full posting.
  • A real depth ceiling, stated rather than hit blind. SEEK stops serving new results after about 500 postings per search regardless of how many more it claims exist — totalAvailable and truncated tell you when a search hit that wall.

What you get

One row per job posting by default. (Turn off "One row per job posting" in the Input tab to get one row per search instead, with the whole posting list nested in jobs.) Every row carries these fields:

FieldType / formatDescription
querytextThe search line you passed in, unchanged.
foundbooleantrue if the search returned at least one posting. false rows are never charged.
statustextOK, NOT_FOUND (no postings for that search), BAD_FORMAT (the line had neither keywords nor a location), or BLOCKED.
searchKeywordstextThe keywords actually sent to SEEK.
searchLocationtextThe location actually sent to SEEK.
jobCountnumberHow many postings this search returned after your filters — this is exactly what you're charged for.
totalAvailablenumberSEEK's own total-match count for the search, before this actor's page/depth limits.
truncatedbooleantrue if more postings were available than you asked for, or if paging stopped early (SEEK's own 500-result depth cap, or a mid-run rate limit).
jobsarrayThe full posting list. Present in every row; it's what gets expanded into separate rows in "one row per posting" mode.
jobIdtextSEEK's own numeric posting ID — stable, and what deduplication keys on.
titletextJob title.
companyNametextHiring company as SEEK names it.
advertisertextThe listing's advertiser — often the same as companyName, but a recruitment agency's name when one is posting on the employer's behalf.
locationtextLocation as SEEK prints it on the posting (e.g. "Sydney NSW", "Melbourne VIC").
remotebooleantrue if the location, work arrangement, or title reads as remote.
classificationtextSEEK's top-level job category (e.g. "Information & Communication Technology").
subClassificationtextSEEK's sub-category (e.g. "Engineering - Software").
workTypesarraye.g. ["Full time"], ["Contract/Temp"].
workArrangementtexte.g. "Hybrid", "Remote", "On-site", when SEEK states one.
salaryLabeltextThe pay range or rate exactly as SEEK's advertiser wrote it (e.g. "$120,000 – $140,000 per year"). Present only when the advertiser chose to disclose one.
teasertextSEEK's own one-line summary of the posting — the only description-shaped field this actor offers (see "Why this one").
bulletPointsarrayShort highlight bullets SEEK shows on some cards. Empty on most postings.
isFeaturedbooleantrue if SEEK marks this a featured/promoted listing.
postedAtdate (ISO)SEEK's own listing timestamp.
postedAgotextThe same thing in SEEK's words ("17m ago", "2 days ago").
jobUrllinkPermanent link to the posting on seek.com.au.
companyLogoUrlimageCompany/advertiser logo image URL, when SEEK has one on file.
scrapedAtdate (ISO)When this actor fetched the row.

A search that returns no postings comes back as a single found: false row with a status/message explaining why, and is never charged. So does a blank line.

Pricing

  • Job posting returned: $1 per 1,000 job postings

Plus a $0.00005 start fee per run. Each event above is billed independently, only when it actually returns data — misses (found:false) are never charged.

You're charged per posting returned, not per search — a search that returns 12 postings costs twelve, a search that returns none costs nothing, and a BAD_FORMAT line costs nothing.

Because you pay per posting, "Most postings to return per search" is your budget control: leave it at 50 and a ten-search run costs at most 500 postings' worth. SEEK stops serving new results past roughly 500 per search regardless, so that is the real ceiling per line.

How to use

  1. In the Apify Console. Open the actor page and click Start — the searches field is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found.
  2. Via the API. Call it directly with a POST request — no Console needed once you have an API token:
    curl "https://api.apify.com/v2/acts/accountable_eel~seek-jobs-search-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
    -X POST \
    -H "Content-Type: application/json" \
    -d '{"searches":["developer @ Melbourne VIC"]}'
  3. On a schedule. Save this actor as an Apify Task with the input you want, then add a Schedule (hourly, daily, weekly) so it runs on its own — no server of your own required.

Paste one search per line:

developer @ Melbourne VIC
registered nurse
marketing manager @ Sydney NSW

A line with no @ location uses the location you set once in 🔍 Search settings — leave that blank too and the search covers all of Australia.

🔍 Search settings — these are sent to SEEK, so they narrow the search before results are returned, which makes runs cheaper as well as more relevant:

InputWhat it does
defaultLocationLocation for any line that doesn't name one. Write it as SEEK does — "Sydney NSW", "Melbourne VIC".
maxJobsPerQueryMost postings to return per search. Default 50, capped at SEEK's own ~500-result depth limit.
postedWithinPast 24 hours / 3 days / week / 2 weeks.

🎯 Narrow the results — applied here, to the postings after they arrive, so you can filter on things SEEK's own search box doesn't expose. They combine with AND across fields and OR within a field:

InputWhat it does
titleKeywordsKeep only titles containing one of these — ["engineer","analyst"].
excludeTitleKeywordsDrop titles containing one of these — ["intern","trainee"]. Applied after the include list.
companiesKeep only these companies — partial names match.
excludeCompaniesDrop these companies — useful for filtering out recruitment agencies you already know.
locationsNarrow a wide search to particular suburbs or regions.
remoteOnlyKeep only roles whose location, work arrangement, or title reads as remote.
skipDuplicateJobsOn by default. Each posting is returned, and billed, once per run even if two searches overlap.

Input

{
"searches": [
"developer @ Melbourne VIC"
]
}

One search per line. Write it as "keywords @ location", or just the keywords and set a location below. Accepted formats: developer @ Melbourne VIC, registered nurse, marketing manager @ Sydney NSW.

Output

queryfoundstatussearchKeywordssearchLocationjobCounttotalAvailabletruncatedjobsjobIdtitlecompanyNameadvertiserlocationremoteclassificationsubClassificationworkTypesworkArrangementsalaryLabelteaserbulletPointsisFeaturedpostedAtpostedAgojobUrlcompanyLogoUrlscrapedAt
actuary @ Canberra ACTtrueOKactuaryCanberra ACT1010false<all postings found (full list)>940440642027 Technology Consulting Graduate ConsultantSEEK GradSEEK GradCanberra ACTfalseConsulting & StrategyOther["Full time"]MinterEllison is currently recruiting for Technology Consulting Graduates in our Canberra office.[]false2026-08-18T04:51:46Z13d agohttps://www.seek.com.au/job/94044064https://bx-branding-gateway.cloud.seek.com.au/f9e136a9-04ad-4f08-bf58-5d62cd652db0.1/jdpLogo2026-08-31T06:50:13.710Z

A miss comes back as a row with "found": false and is never charged.

Use it from Clay, n8n, Make, or an AI agent

This actor runs synchronously over plain HTTP — call it directly from a script, a workflow tool, or an AI agent, no Apify Console needed once you have an API token.

curl "https://api.apify.com/v2/acts/accountable_eel~seek-jobs-search-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
-X POST \
-H "Content-Type: application/json" \
-d '{"searches":["developer @ Melbourne VIC"]}'

n8n. Add an HTTP Request node: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~seek-jobs-search-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body Content Type JSON, JSON Body {"searches":["developer @ Melbourne VIC"]} (swap in an expression from an earlier node for a real value).

Clay. Add an "HTTP API" column: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~seek-jobs-search-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body {"searches":["{{search}}"]}, mapping the row's search into the searches array.

MCP. In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "SEEK Jobs Search Lookup | Apify" — the agent will find and run this actor.