Jora.com – Job Listings, Salaries & Full Descriptions avatar

Jora.com – Job Listings, Salaries & Full Descriptions

Pricing

from $1.00 / 1,000 dataset items

Go to Apify Store
Jora.com – Job Listings, Salaries & Full Descriptions

Jora.com – Job Listings, Salaries & Full Descriptions

Collect Jora.com job listings by keyword, filters, or URLs across supported countries. Returns full descriptions, salary, work type, company, location, and connector export.

Pricing

from $1.00 / 1,000 dataset items

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

9 days ago

Last modified

Share

Jora Jobs Scraper

The Jora Jobs Scraper collects current job listings from Jora across Australia, New Zealand, Singapore, Hong Kong, Malaysia, Indonesia, the United States, the United Kingdom, and Canada. It supports keyword/location search mode and URL mode for existing Jora search pages or job detail pages. Detail mode adds the full description, apply redirect, source name, salary, work type, and work arrangement when available.

Why This Scraper?

  • Search by keywords and location across all supported Jora country sites.
  • Start from Jora search URLs or direct job URLs when you already have a curated source list.
  • Includes Jora filters for listed date, job type, quick apply, sort, distance, and minimum salary.
  • Uses maxItems as the main output cap; maxPages is unlimited by default, walking every result page for a search.
  • Detail mode adds full job descriptions and apply URLs.
  • Daily/recurring change monitoring: turn on Incremental mode to get only NEW, UPDATED, and REAPPEARED jobs on every scheduled run, instead of the same full list again.
  • Optional MCP connector export sends a concise job summary into your selected apps while the complete record stays in the Apify dataset.

Data You Get

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

FieldExample
id00000000000000000000000000000001
jobId00000000000000000000000000000001
titleSample Software Engineer
companySample Company
locationSydney NSW
countryCodeau
urlhttps://au.jora.com/job/Sample-Job-00000000000000000000000000000001
sourceUrlhttps://au.jora.com/j?q=software+engineer&l=Sydney%2C+NSW
salary$100,000 - $120,000 a year
salaryMin100000
salaryMax120000
workTypeFull time
workArrangementHybrid
postedAtTextPosted 3d ago
quickApplytrue
isSponsoredfalse
rank1
page1
abstractShort summary from the search card.
snippetBullets["Build sample services", "Work with a sample team"]
descriptionTextFull job description appears here when fetchDetails=true.
descriptionHtml<div>Full job description appears here.</div>
applyUrlhttps://au.jora.com/job/rd/00000000000000000000000000000001
sourceNameSample Source
searchKeywordssoftware engineer
searchLocationSydney, NSW
searchTotalCount250
detailFetchedtrue
scrapedAt2026-01-01T00:00:00.000Z
changeTypeNEW (incremental mode only — see "Recurring updates" below)
changedFields["salary"] (incremental mode, UPDATED rows only)
firstSeenAt2026-01-01T00:00:00.000Z (incremental mode only)
lastSeenAt2026-01-02T00:00:00.000Z (incremental mode only)

How to Use

Search by keyword and location:

{
"mode": "search",
"searches": [
{
"keywords": "software engineer",
"location": "Sydney, NSW",
"country": "au"
}
],
"maxItems": 20
}

Search with filters:

{
"mode": "search",
"searches": [
{
"keywords": "developer",
"location": "Melbourne VIC",
"country": "au"
}
],
"postedWithin": "7d",
"workType": "contract",
"quickApply": true,
"sort": "date",
"salaryMin": 90000,
"maxItems": 25,
"fetchDetails": true
}

Run several searches in one run:

{
"mode": "search",
"searches": [
{ "keywords": "data analyst", "location": "Auckland", "country": "nz" },
{ "keywords": "data analyst", "location": "Singapore", "country": "sg" }
],
"maxItems": 40
}

Start from URLs:

{
"mode": "url",
"urls": [
"https://au.jora.com/j?q=software+engineer&l=Sydney%2C+NSW",
"https://au.jora.com/job/Sample-Job-00000000000000000000000000000001"
],
"maxItems": 20
}

Send results into your apps:

{
"mode": "search",
"searches": [
{ "keywords": "marketing manager", "location": "Sydney", "country": "au" }
],
"mcpConnectors": ["your-connector-id"],
"notionParentPageUrl": "https://www.notion.so/sample-parent-page",
"maxNotifyListings": 10
}

The connector export writes a condensed, human-readable summary for each selected job: title, company, location, salary, work type, posted text, and links. The complete JSON record is always kept in the Apify dataset.

Input Parameters

ParameterTypeDefaultDescription
modestringsearchChoose search for keyword/filter searches or url for existing Jora URLs.
searchesarraysoftware engineer in SydneySearch mode inputs. Each item can include keywords, location, and country.
postedWithinstringanytimeDate filter: anytime, 24h, 7d, 14d, or 30d.
workTypestringanyJob type filter such as full_time, part_time, contract, permanent, or internship.
quickApplybooleanfalseLimits results to Jora quick apply jobs.
sortstringrelevanceUse relevance or date.
distanceKmintegeremptyOptional location radius.
salaryMinintegeremptyOptional minimum salary filter.
urlsarraysample search URLURL mode inputs. Accepts search result URLs and job detail URLs.
fetchDetailsbooleantrueOpens job pages for full details.
maxItemsinteger20Maximum matching rows to save. 0 means unlimited. Results can be fewer when the source has fewer matching jobs.
maxPagesintegeremptyMaximum search pages per source. Leave empty to walk every result page for that search until Jora has no next page; maxItems remains the main cap.
resumeFromRunIdstringemptyA previous run ID or dataset ID to continue a full-catalogue walk across separate runs. Jobs already collected there (matched by jobId) are skipped, so this run only saves the new ones.
incrementalModebooleanfalseDaily/recurring monitoring of this same search. The first run returns everything as NEW; later runs return only NEW, UPDATED, and REAPPEARED rows by default. See "Recurring updates" below.
stateKeystringemptyOptional name for a monitoring campaign, so its incremental state stays stable or is deliberately shared. Derived automatically from your search scope and fetchDetails setting when left empty.
emitUnchangedbooleanfalseIncremental mode only. Also return jobs unchanged since the last run, marked UNCHANGED. Adds — and bills for — extra rows you already have.
emitExpiredbooleanfalseIncremental mode only. Also return jobs from a previous run that are no longer found, marked EXPIRED, once a run has covered the whole tracked search (not capped by maxItems/maxPages, not a resume). Adds — and bills for — extra rows.
proxyobjectResidential AUConnection settings. Residential AU is selected by default.
mcpConnectorsarrayemptyOptional MCP connector ids for app export.
notionParentPageUrlstringemptyRequired only for Notion page export.
maxNotifyListingsinteger50Maximum jobs sent to each connector. Does not affect the dataset.

Resuming a full-catalogue walk

For an unbounded pull (maxPages empty, maxItems: 0), two things protect a long run:

  • resumeFromRunId lets you continue in a brand-new run: paste the ID of a previous run (or its dataset), and this run skips every jobId already saved there, appending only new jobs.
  • A checkpoint is saved automatically as the run progresses. If the run is interrupted by an Apify platform migration or you click Resurrect on a failed run, it picks back up from where it left off in the same run, without re-saving (or re-charging for) jobs it already collected. No input is needed for this; it's automatic.

Recurring updates (incremental mode)

Resuming and incremental monitoring are two different things — pick the one that matches what you are doing:

NeedUse
One long pull stopped and should continueresumeFromRunId / the automatic checkpoint
Run the same search every day and receive only what changedincrementalMode
Keep separate daily campaigns for similar searchesdistinct stateKey values
Run a normal full snapshotleave both off

Incremental mode (incrementalMode) is meant for a schedule. The actor remembers the previous run of the same search by itself, so there is no run ID to paste. The first run returns every matching job as NEW. Later runs return only NEW, UPDATED, and REAPPEARED jobs — everything unchanged since last time is suppressed and not billed. UPDATED rows carry changedFields listing exactly which fields moved, and every row carries firstSeenAt and lastSeenAt so you can tell a long-running listing from a fresh one.

Turn on emitUnchanged or emitExpired only when you also want those rows back — they are returned and billed for, so leave them off unless you specifically need a full snapshot every run or explicit expiry tracking. emitExpired additionally holds back its rows on any run that did not cover the whole tracked search (capped by maxItems/maxPages, or resumed), so a short run never reports jobs as gone when they simply were not reached.

State is isolated automatically: each distinct search scope — mode, searches/urls, and the filters — gets its own state, and so does each fetchDetails setting, so a detail run and a card-only run of the same search never compare against each other. Set stateKey to give a campaign a stable name of your own, or to deliberately point two differently-configured runs at the same state.

Scheduled-run example — the same search, run daily:

{
"mode": "search",
"searches": [
{ "keywords": "software engineer", "location": "Sydney, NSW", "country": "au" }
],
"incrementalMode": true,
"stateKey": "sydney-swe-daily",
"maxItems": 100
}

Day 1 returns every job with "changeType": "NEW". From day 2 on, the identical input returns brand-new postings as NEW, jobs whose salary/title/description changed as UPDATED with changedFields naming them, jobs that were missing and came back as REAPPEARED — and nothing else.

What does not count as a change. Six fields are deliberately left out of change detection, because measurement across repeated runs of the identical search showed they move on their own while the job itself is untouched: url and applyUrl (they carry tracking parameters that differ per request), postedAtText (a relative age that drifts by itself, 4d ago9d ago), rank and searchTotalCount (a position and a total-match count belong to the search, not to the job), and scrapedAt (a per-run timestamp). When only these move, the job is not reported as UPDATED. All six are still returned on every row exactly as before — only change detection ignores them.

Output Example

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

{
"id": "00000000000000000000000000000001",
"jobId": "00000000000000000000000000000001",
"title": "Sample Software Engineer",
"company": "Sample Company",
"location": "Sydney NSW",
"countryCode": "au",
"url": "https://au.jora.com/job/Sample-Job-00000000000000000000000000000001",
"sourceUrl": "https://au.jora.com/j?q=software+engineer&l=Sydney%2C+NSW",
"salary": "$100,000 - $120,000 a year",
"salaryMin": 100000,
"salaryMax": 120000,
"workType": "Full time",
"workArrangement": "Hybrid",
"postedAtText": "Posted 3d ago",
"quickApply": true,
"isSponsored": false,
"rank": 1,
"page": 1,
"abstract": "Short summary from the search card.",
"snippetBullets": ["Build sample services", "Work with a sample team"],
"descriptionHtml": "<div>Full job description appears here.</div>",
"descriptionText": "Full job description appears here when fetchDetails=true.",
"applyUrl": "https://au.jora.com/job/rd/00000000000000000000000000000001",
"sourceName": "Sample Source",
"searchKeywords": "software engineer",
"searchLocation": "Sydney, NSW",
"searchTotalCount": 250,
"detailFetched": true,
"scrapedAt": "2026-01-01T00:00:00.000Z"
}

Plan Requirement

Residential AU is selected by default because Jora can return empty responses from cloud datacenter connections. For searches outside Australia, choose the closest Residential country supported by your Apify plan. Detail mode uses the detail-enrichment charge event in addition to the built-in dataset item event.