APS Jobs Search Scraper avatar

APS Jobs Search Scraper

Pricing

from $2.99 / 1,000 aps jobs job records

Go to Apify Store
APS Jobs Search Scraper

APS Jobs Search Scraper

Scrape job listings from APSJobs.gov.au, the official Australian Public Service job board. Extract job titles, agencies, locations, salary ranges, and descriptions for Australian government recruitment.

Pricing

from $2.99 / 1,000 aps jobs job records

Rating

0.0

(0)

Developer

Jobs API

Jobs API

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

11 days ago

Last modified

Share

APSJobs Jobs Search Scraper

Extract detail-verified vacancies from the official APSJobs portal. The Actor searches the public Australian Public Service vacancy feed, follows official vacancy pages, and emits one enriched job record per vacancy.

What this Actor does

  • Searches APSJobs by keyword and location.
  • Follows only official apsjobs.gov.au vacancy URLs and reconciles each record to its Salesforce vacancy ID.
  • Traverses the portal's public Shadow DOM detail sections.
  • Extracts structured vacancy metadata, full bounded detail text, section HTML, lists, links, application instructions, contact information, and organization context.
  • Normalizes duties, selection criteria, eligibility, qualifications, mandatory requirements, desirable requirements, salary, dates, work arrangements, and opportunity status when the source publishes them.
  • Writes only complete, detail-verified vacancies to the dataset.
  • Stores structured output, run summary, health, and source diagnostics in the default key-value store.

This Actor reads public job information only. It does not log in, bypass access controls, defeat challenges, or submit applications.

Why use it

APSJobs search cards contain only a small subset of the information available on a vacancy page. This Actor joins the search-card identity to the official detail page so that downstream recruiting, research, and job-matching workflows receive useful fields instead of opaque page fragments.

Each record keeps both normalized fields and bounded source evidence. That makes the output easy to query while retaining the context needed to audit where a value came from.

Rich output

Every emitted row represents a complete vacancy and includes the following groups when published by APSJobs:

Field groupIncluded data
Identityid, recordId, actorName, actorVersion, title, detailUrl, recordType, recordStatus
Organizationagency, organization.name, organization.about, website, agencyEmploymentAct
LocationFull source location text, parsed cities and states, country, country code, and location components
Classification and payAPS classification, salary text, numeric minimum/maximum, currency, pay period, and disclosure flag
Vacancy metadataPublished date, closing date, job category, office arrangement, arrangement details, opportunity type/status, and employment type
DescriptionBounded plain text, descriptionTextLength, descriptionWordCount, source HTML where available, ordered detail sections, list items, and links
Requirementsresponsibilities, selectionCriteria, eligibility, qualifications, mandatoryRequirements, desirableRequirements, and notes
ApplicationApplication URL(s), method, instructions, requested materials, and source-provided links
ContactContact name, phone, email(s), website, position number, and vacancy number
Provenancesource, sourceDomain, sourceWebsite, sourceMode, dataAvailable, found, scrapedAt, contentSource, extractionMethod, and sourceRecord
CompletenessOnly records with a public identity, structured detail sections, and a substantive description are emitted

Optional fields are omitted when APSJobs does not publish the corresponding value. Missing information is not invented.

How to scrape APSJobs vacancies

  1. Enter a search phrase in query, such as policy officer, software engineer, or project manager.
  2. Enter an APSJobs location in location, such as Canberra, Sydney, or Australia.
  3. Set maxItems to the number of complete vacancies you want.
  4. Run the Actor.
  5. Open the dataset and inspect the structured vacancy fields and the separate run diagnostics when needed.

The default configuration is intentionally small and uses ordinary direct public access. Requests run sequentially, without retries, proxy routing, custom headers, or session rotation. If APSJobs returns an access-denial status or displays a verification/security challenge, the Actor stops, discards buffered jobs, records SKIPPED, and preserves the request receipts.

Example input

{
"query": "policy officer",
"location": "Canberra",
"maxItems": 3,
"backfillItems": 3,
"maxLoadMoreClicks": 2,
"navigationTimeoutSecs": 75,
"requestHandlerTimeoutSecs": 90
}

Input fields

FieldTypeDefaultDescription
querystringpolicy officerPublic APSJobs keyword search. Maximum 120 characters.
locationstringCanberraFilters result cards by their visible location text. Use a city, state, territory, or Australia. Maximum 120 characters.
maxItemsinteger3Maximum complete rows to emit. Range: 1–100.
backfillItemsinteger3Extra candidates used to replace rejected or failed detail pages. Range: 0–20.
maxLoadMoreClicksinteger3Maximum public search-feed expansions. Range: 0–20.
navigationTimeoutSecsinteger75Page navigation timeout. Range: 20–120 seconds.
requestHandlerTimeoutSecsinteger90Request-handler timeout. Range: 30–180 seconds.

The Actor derives a bounded request budget from 1 + maxItems + backfillItems. It does not accept an unbounded page count or workload.

Example output

{
"recordType": "job",
"recordStatus": "complete",
"recordId": "apsjobs-a05OY00000QhJ21YAF",
"actorName": "apsjobs-jobs-search-scraper",
"actorVersion": "0.4.0",
"id": "a05OY00000QhJ21YAF",
"title": "Special Advisor, Media and Public Affairs",
"agency": "Climate Change Authority",
"organization": {
"name": "Climate Change Authority",
"about": "The Climate Change Authority is an independent statutory agency..."
},
"location": {
"text": "Sydney NSW",
"city": "Sydney",
"state": "NSW",
"country": "Australia",
"countryCode": "AU"
},
"salary": {
"text": "$121,755 to $139,816",
"min": 121755,
"max": 139816,
"currency": "AUD",
"disclosed": true
},
"classification": "Executive Level 1",
"publishedAt": "2026-09-04",
"closingDate": "2026-09-27",
"workArrangement": "Hybrid",
"workArrangementDetails": "Flexible working arrangements, including work from home, are available subject to operational requirements",
"opportunityType": "Full-Time",
"opportunityStatus": "Ongoing",
"jobCategory": "Communication, Media Marketing",
"description": "The Special Advisor, Media and Public Affairs supports the Chair and CEO...",
"descriptionText": "The Special Advisor, Media and Public Affairs supports the Chair and CEO...",
"descriptionTextLength": 83,
"descriptionWordCount": 12,
"descriptionSectionCount": 4,
"descriptionItemCount": 2,
"descriptionLinkCount": 1,
"responsibilities": [
"Draft speeches, opinion pieces, event talking points and public commentary for the Chair and CEO.",
"Support media engagement on behalf of the Chair and CEO."
],
"selectionCriteria": [
"Strong writing and editorial skills, with the ability to translate complex material into clear and compelling public messages."
],
"eligibility": [
"Citizenship: to be eligible for employment with the Authority you must be an Australian citizen."
],
"application": {
"method": "email",
"instructions": "You are required to submit a 500-word pitch...",
"materials": ["Submit your current CV and a 500-word pitch."]
},
"contact": {
"name": "Mia Swainson",
"phone": "0432 928 775",
"email": "mia.swainson@cca.gov.au",
"positionNumber": "TBC",
"vacancyNumber": "VN-0772444"
},
"detailUrl": "https://www.apsjobs.gov.au/s/job-details?title=special-advisor-media-and-public-affairs&Id=a05OY00000QhJ21YAF",
"applicationUrl": "mailto:recruitment@cca.gov.au?...",
"applicationLinkCount": 1,
"hasApplicationAction": true,
"source": "APSJobs",
"sourceDomain": "apsjobs.gov.au",
"sourceWebsite": "https://www.apsjobs.gov.au",
"sourceMode": "public-search-page-and-detail",
"dataAvailable": true,
"found": true,
"scrapedAt": "2026-09-22T00:00:00.000Z",
"contentSource": "apsjobs",
"extractionMethod": "shadow_dom_detail_sections",
"sourceRecord": {
"sourceId": "a05OY00000QhJ21YAF",
"extractionMethod": "shadow_dom_detail_sections"
}
}

The example is abbreviated for readability. Actual rows retain the bounded details.sections, ordered details.sectionsList, descriptionHtml, source links, application materials, and sourceRecord evidence.

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

Run status and key-value store

The default key-value store contains:

KeyPurpose
OUTPUTTerminal status, input summary, counts, request budget, and dataAvailable
OUTPUT_SUMMARYCopy of the machine-readable run summary for integrations
RUN_HEALTHHealth, completeness, and diagnostic count for the run
DIAGNOSTICSBounded source-barrier, deferred-request, invalid-candidate, and completeness-rejection diagnostics
REQUEST_RECEIPTSOrdered search/detail request URLs, observed statuses, and terminal outcomes

The status field is the Apify process outcome and is always SUCCEEDED or FAILED. The separate resultStatus field describes the data result:

  • COMPLETE: the requested result completed without known omissions.
  • LIMITED: usable complete jobs were stored, but fewer than maxItems were found or a request, extraction, storage, or metadata issue limited the result. The Apify run remains successful so already stored rows are preserved.
  • SKIPPED: APSJobs returned HTTP 401, 403, 429, or 451, or displayed a source-authored access-denial, CAPTCHA, human-verification, or security-challenge page. Buffered rows are discarded.
  • DEFERRED: a handled browser/transport error, rejected candidate, or extraction issue prevented a trustworthy populated result, without evidence that APSJobs blocked access.
  • NO_DATA: the source explicitly reported no matching jobs, recorded as noDataConfirmed: true with a matching successful search receipt. Unverified empty pages or zero-candidate parser outcomes are DEFERRED, not a clean empty result.
  • FAILED: a fatal error prevented a valid zero-row result, or run metadata could not be persisted when no rows were stored.

limitedResults is true only for resultStatus: LIMITED. Treat a run as populated only when status: SUCCEEDED, dataAvailable: true, and resultStatus is COMPLETE or LIMITED. Legacy stored summaries without resultStatus remain readable as historical records; they are not rewritten or reinterpreted as current-format outcomes.

Reliability and data quality

  • Official vacancy IDs are deduplicated before detail navigation.
  • Detail URLs must use HTTPS, the official APSJobs host, the official job-details path, and a valid vacancy ID.
  • Search results are backfilled within bounded limits when a detail page is unavailable or fails the complete-job contract.
  • Only rows with more than 20 populated, meaningful source fields pass the completeness gate.
  • A detected access barrier stops the crawl immediately and no buffered rows are pushed to the dataset.
  • Detail records are rejected when identity, title, agency, location, description, structured sections, or provenance is missing.
  • All text, HTML, list, link, and diagnostic collections are bounded to keep dataset rows practical.
  • sourceRecord preserves the bounded source sections and search-card context used to build each emitted row.

Cost and runtime

The Actor uses one browser search request plus up to maxItems + backfillItems detail requests, subject to the configured request budget. Runtime and cost depend on the number of detail pages, browser startup time, and current APSJobs response time. Requests stay sequential and are never retried.

Local development

npm ci
npm run check
apify validate-schema .actor/input_schema.json
$store = "storage-apsjobs-validation-$((Get-Date).ToUniversalTime().ToString('yyyyMMddHHmmss'))"
if (Test-Path $store) { throw "Storage path already exists: $store" }
if (Test-Path .\apify_storage) { throw "Preserve apify_storage or run from an isolated working copy first." }
$env:APIFY_LOCAL_STORAGE_DIR = $store
apify run --resurrect --input-file INPUT.json
npm run validate:dataset -- $store

The local validation gate checks the dataset schema, complete-job contract, more than 20 meaningful fields per row, unique IDs and URLs, provenance, rich detail sections, and OUTPUT/RUN_HEALTH/DIAGNOSTICS/REQUEST_RECEIPTS consistency. Use a fresh actor-relative store and preserve existing stores. Do not run with --purge or commit local storage output.

FAQ

Why are some optional fields absent?

APSJobs vacancies do not all publish salary, contact, work arrangement, application, or requirement sections. The Actor omits unavailable values instead of guessing.

Why did the Actor return fewer rows than requested?

The requested count applies to complete public vacancies. The source may have fewer matching vacancies, a vacancy may close between search and detail navigation, or the source may temporarily block a page. Check OUTPUT, RUN_HEALTH, and DIAGNOSTICS.

Does the Actor apply to jobs?

No. It only extracts public application instructions and links. Applications must be submitted by the user through the official vacancy or agency channel.

Can I use this for commercial recruiting?

Review APSJobs terms, the relevant agency's vacancy terms, privacy obligations, and any licensing requirements before redistributing or contacting people using extracted information.

Disclaimer

This Actor is an independent data-extraction tool and is not affiliated with, endorsed by, or sponsored by APSJobs or the Australian Government. APSJobs is a dynamic third-party website; markup, availability, vacancy content, and access policies can change. Use the data responsibly, respect the source's terms and applicable law, and verify important details on the official vacancy page before making decisions.

Support

For a reproducible issue, include the Actor input, run status, relevant diagnostics, and the affected official vacancy URL. Do not include credentials, private application data, or other sensitive information.