SimplyHired Scraper icon

SimplyHired Scraper

Scrape active SimplyHired jobs across the US, UK, Canada, Australia, Ireland and India from $1/1K listings. Search by filters or URL. Extract 40+…

Start using this actor on Apify ↗Need a custom scraper?Contact us ↗

SimplyHired Scraper at a glance

SimplyHired Scraper is a ready-to-run Apify actor from abotapi for collecting jobs data. Its documented output includes id, change type (incremental mode), url, title and company, which you can export as JSON, CSV or Excel or read through the Apify API. It costs $1.50 per 1,000 results on the Apify Free plan and from $1.00 on paid plans, with smaller per-run or optional feature charges listed on Apify.

Runs on
Apify cloud: console, API, schedules and integrations
Data type
Jobs, Automation, Developer Tools
Pricing
$1.50 per 1,000 results (Free plan), from $1.00 on paid plans
Output
Documented below · JSON, CSV, Excel
Inputs
27 options

Scrape active SimplyHired jobs across the US, UK, Canada, Australia, Ireland and India from $1/1K listings. Search by filters or URL. Extract 40+ fields including job titles, companies, salary ranges, full HTML descriptions, qualifications, coordinates and apply URLs.

What SimplyHired Scraper can do

  • 40+ fields per job ad. Includes a parsed salary range (min, max, currency, period), city, state, latitude/longitude, work setting, qualifications, benefits and the full HTML description, not just the 10 to 15 fields typical scrapers return.
  • Two ways to search. Build with keywords, location, job type and country site, or paste any simplyhired.com /search URL and the scraper walks pagination forward from there, or a /job URL for that single listing.
  • Six regional sites. One input field covers United States, United Kingdom, Canada, Australia, Ireland and India.
  • Detail enrichment. Concurrent detail-page enrichment with per-record delivery, so a mid-page failure still keeps the listings already fetched instead of losing the whole page.
  • No duplicates. Client-side de-duplication across pages and searches by the canonical listing id, with the listing budget split evenly across multiple keywords in one run.
  • Connection fallback. Automatic retry across several connection routes when one is challenged or refused, and a clear failure message (never a silently empty result) when no page could be read.

Choose what to collect

These inputs let you configure SimplyHired Scraper - Jobs, Salaries & Company Details. Open the actor on Apify to enter your values and review the current options.

Supported input fields
InputWhat it controls
modestring · requiredSearch mode = pick keywords + location + filters below. URL mode = paste any simplyhired.com /search or /job URL refined in your browser.

Choices: search, url

queriesarrayFree-text search terms (e.g. "software engineer", "nurse", "data analyst"). One scrape per keyword. Leave empty to search by location only; a search needs a keyword or a location.
locationstringCity, state, ZIP, or "Remote". Examples: "New York, NY", "Boston, MA", "94103", "Remote". Leave empty to search nationwide (a keyword is then required).
countrystringWhich SimplyHired regional site to query. The site language follows the host. Defaults to the US site.

Choices: us, uk, ca, au, ie, in

jobTypestringFilter by employment scope. "Any" walks the unfiltered SERP.

Choices: any, fulltime, parttime, contract, temporary, internship, commission

skipSponsoredbooleanDrop sponsored / promoted job cards. Applied as a client-side filter.
datePostedstringOnly jobs posted within this window. Sent to the site as a native filter in Search mode and also applied to each row's post date on this side.

Choices: any, 1, 3, 7, 14

Show 20 more inputs
More input fields
InputWhat it controls
minSalaryintegerOnly jobs whose listed minimum pay is at least this yearly amount (hourly, weekly and monthly pay is annualised; jobs with no listed pay are dropped). Sent to the site as a native filter in Search mode and also checked on this side. 0 = off.
remoteOnlybooleanKeep only jobs flagged remote. Applied on this side to each listing.
sortBystringSimplyHired ignores its own sort parameters, so 'Newest first' orders the listings of each fetched page by post date on this side; it does not re-order across pages.

Choices: relevance, date

keywordstringSingle-keyword alias for the Keywords field, accepted so runs built for other SimplyHired scrapers keep working. Ignored when Keywords is filled.
results_wantedintegerAlias for Max listings. Used when Max listings is left unset or still at its default of 20; a Max listings value you changed yourself takes priority.
max_pagesintegerAlias for Max pages per search, used only when that field is empty.
urlsarrayOne or more simplyhired.com URLs (also the .co.uk.ca.com.au.ie and .co.in sites). Supported: keyword + location search, keyword-only, location-only, paged (pn), job-type filtered (jt), search with a job= preselect, and a single /job page. Each search URL pages forward independently. Only the keyword, location, job type and start page come from the pasted URL; the Date posted, Minimum yearly salary, Remote only, Sort by and Skip sponsored fields above are still applied on this side to the results of every URL, so clear them if you want the pasted search unfiltered.
startUrlsarrayAlias for the Search URLs field. When filled it replaces the sample Search URLs, and when no keywords are given the run switches to URL mode automatically. A Search URLs list you edited yourself takes priority.
maxPagesintegerHow many SERP pages to walk per query × location combination (or per pasted URL). Each page returns up to 20 listings. Leave empty to walk every result page. Use maxListings in tandem to cap the total budget across all searches.
maxListingsintegerStop after this many listings across all searches. 0 = no cap.
fetchDetailsbooleanWhen ON, also fetch each job's detail page for the full HTML description, qualifications list, employer logo, lat/lng, and apply URL. SERP cards already carry id, title, company, location, snippet, and posted date, so simple feeds work fine with this OFF. Default ON for richer output.
resumeFromRunIdstringPaste a previous run ID or dataset ID to continue a full-catalogue walk across separate runs. Listings already collected there (matched by id) are skipped, so this run only saves the new ones. Leave empty for a normal fresh run. For recurring daily monitoring of the same search, use Incremental mode below instead.
incrementalModebooleanTurn this on for daily or recurring monitoring. The first run returns all matching listings as NEW. Later runs normally return only NEW, UPDATED, and REAPPEARED listings. A listing counts as UPDATED when any returned field other than the ignored ones changes (title, company, location, salary, job type, description, qualifications, benefits and so on); ignored by default and never compared: scrapedAt, applyUrl, mobileApplyUrl, jobCardTrackingKey, pageNumber and auction (they change with every scrape), plus jobKey, summary, skills, jobType and sourceSearchUrl (copies or derivations of compared fields: id, snippet or descriptionText, skillsAll, jobTypes and your search inputs, so a real change still shows through the source field). A plain field name is ignored at any depth, including inside nested objects (see Ignore fields when detecting changes to add more). Turn on "Emit unchanged" or "Emit expired" only when you also want those listings returned (and billed). State is kept separately for each query/location/URL and detail-mode setup; use State key when you want to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above.
stateKeystringOptional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently-configured runs. Leave empty to let the actor derive a key automatically from the query/location/URL and detail settings, different searches then never mix state with each other.
emitUnchangedbooleanOff by default. Turn on to also return listings that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have, so leave it off unless you specifically want the full snapshot every run.
emitExpiredbooleanOff by default. Turn on to also return listings that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search, not when Max listings capped it or when Resume was used. This returns, and bills, extra synthetic rows, so leave it off unless you need expiry tracking.
ignoreFieldsForChangesarrayOptional. Field names that must not make a listing count as UPDATED, in addition to the built-in ignored fields. A plain name (for example employerLogoUrl) is ignored at any depth; a dotted path (for example compensation.min) ignores exactly that nested field. The fields are still returned in the output, just never compared. Leave empty to use the defaults.
mcpConnectorsarrayOptionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON, the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).
notionParentPageUrlstringURL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.
maxNotifyListingsintegerCap on items written to each connector per run. Does not affect the dataset.

Fields in the output

The documented dataset includes the fields below. Availability can depend on the source page and selected mode.

idID
changeTypeChange type (incremental mode) (text)
urlURL (link)
titleTitle
companyCompany
companyRatingRating
cityCity
stateState
latitudeLat
longitudeLng
salarySalary
salaryMinMin Pay
Show 17 more fields
salaryMaxMax Pay
salaryPeriodPeriod
jobTypesType
remoteAttributesRemote / setting
datePostedPosted
applyUrlApply (link)
skillsAllSkills
qualificationsQualifications
benefitsBenefits
sponsoredSponsored
changedFieldsChanged fields (incremental mode) (array)
firstSeenAtFirst seen (incremental mode) (date)
lastSeenAtLast seen (incremental mode) (date)
scrapedAtScraped
descriptionTextDescription
requirementsRequirements
salaryCurrencyCurrency

Example output

An example from this actor’s documentation. Values are illustrative; this is not a fresh live result.

{
  "id": "abcd1234example",
  "url": "https://www.simplyhired.com/job/abcd1234example",
  "title": "Software Engineer",
  "displayTitle": "Software Engineer, Backend",
  "normalizedTitle": "software engineer",
  "company": "Sample Company Inc",
  "companyRating": 4.2,
  "companyPageUrl": "https://www.simplyhired.com/company/000-sample-company-inc",
  "employerLogoUrl": "https://logos.example-cdn.com/sample-company-inc.png",
  "employerHomepage": "https://www.samplecompany.example",
  "location": "New York, NY",
  "formattedLocation": "New York, NY",
  "city": "New York",
  "state": "NY",
  "latitude": 40.7128,
  "longitude": -74.006,
  "country": "us",
  "jobTypes": [
    "Full-time"
  ],
  "workSettings": [
    "Hybrid"
  ],
  "remoteAttributes": [],
  "salary": "$140,000 - $180,000 a year",
  "salaryMin": 140000,
  "salaryMax": 180000,
  "salaryCurrency": "USD",
  "salaryPeriod": "year",
  "compensation": {
    "currency": "USD",
    "period": "year"
  },
  "snippet": "Short listing preview text appears here...",
  "descriptionHtml": "<p>Full long-form HTML description appears here.</p>",
  "descriptionText": "Full long-form description as plain text appears here.",
  "requirements": [
    "Python",
    "AWS"
  ],
  "qualifications": [
    "Bachelor's degree",
    "5+ years experience"
  ],
  "benefits": [
    "Health insurance",
    "401(k)"
  ],
  "skillsAll": [
    "Python",
    "AWS",
    "API design"
  ],
  "datePosted": "2026-09-20T08:00:00.000Z",
  "datePostedEpochMs": 1789891200000,
  "dateOnIndeed": 1789891200000,
  "applyUrl": "https://www.simplyhired.com/out?r=sampletoken000",
  "mobileApplyUrl": "https://www.simplyhired.com/m/out?r=sampletoken000",
  "indeedApply": false,
  "sponsored": false,
  "auction": false,
  "expired": false,
  "jobCardTrackingKey": "0-pdx0-0-0000000000000000-0000000000000000",
  "jobTypeRequested": "fulltime",
  "searchQuery": "software engineer",
  "searchLocation": "New York, NY",
  "pageNumber": 1,
  "source": "SimplyHired",
  "scrapedAt": "2026-09-29T12:00:00.000Z"
}

Ways to use this data

  • Job boards and aggregators: pull fresh SimplyHired listings by keyword and location to mirror or enrich your own job feed.
  • Recruiter and sourcing tools: track new postings for target companies or roles as soon as they appear, and pull only what changed on a schedule.
  • Compensation research: build salary-range datasets by title, location and job type from the parsed salaryMin / salaryMax fields.
  • Labor market analytics: measure posting volume, remote-vs-onsite mix and qualifications trends across regions and countries.
  • Application tooling: collect the SimplyHired apply link and full job description text to feed an autofill, alerting or matching tool.

Before you run

Start with a small input and check the resulting records against your expected fields. Source content and actor options can change; the current Apify listing is the reference for availability and pricing.

Questions about this actor

What data does SimplyHired Scraper return?

The documented output for SimplyHired Scraper includes id, change type (incremental mode), url, title, company, rating, city and state. Availability of each field depends on the source page and the selected mode.

How much does SimplyHired Scraper cost?

It costs $1.50 per 1,000 results on the Apify Free plan and from $1.00 on paid plans, with smaller per-run or optional feature charges listed on Apify. The Apify listing shows the current rate for every plan.

Can I get only new or changed listings on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new and updated listings, and unchanged ones are not billed unless you turn on Emit unchanged. Turn on Emit expired to also get EXPIRED listings after a run completes a full, uncapped scan; REAPPEARED appears only after such a run has marked a listing expired.

Why do my keyword and location filters have no effect?

Search-builder fields (queries, location, jobType) only apply when mode is search. In url mode, the scraper follows whatever filters are already baked into the pasted URL and ignores the builder fields entirely, since two different filter sources for the same run would conflict.

Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.

Ready to collect with SimplyHired Scraper?

Run it on Apify with your own input and export the results as JSON, CSV or Excel.