Indeed Jobs Scraper — Job Listings & Salary Data API (No Key) avatar

Indeed Jobs Scraper — Job Listings & Salary Data API (No Key)

Pricing

from $1.50 / 1,000 results

Go to Apify Store
Indeed Jobs Scraper — Job Listings & Salary Data API (No Key)

Indeed Jobs Scraper — Job Listings & Salary Data API (No Key)

Keyless job-listings API in the spirit of Indeed — no login, no Cloudflare walls. Aggregates thousands of fresh openings from public job-board APIs plus real Indeed postings from the public web archive. Filter by keyword, location, remote, type and salary. Export to JSON, CSV or Excel.

Pricing

from $1.50 / 1,000 results

Rating

0.0

(0)

Developer

Logiover

Logiover

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

Indeed Jobs Scraper — Job Listings, Salary & Company Data API (No API Key)

Apify Actor No API key Pay per result Category Export

An Indeed jobs scraper and structured job-listings data API in a single Apify Actor. Pull thousands of fresh job postings — title, company, location, salary, remote flag, job type, tags and full description — and export job data to JSON, CSV or Excel for recruiting, lead generation, salary benchmarking and labour-market analytics. No API key, no login, no cookie, no Cloudflare walls.

🏆 How it works (read this first — it's the honest bit)

Indeed's own website is protected end-to-end by Cloudflare Turnstile and returns 403 to any keyless, self-contained scraper. So this Actor does not hammer indeed.com live — that approach is blocked for everyone without a paid unblocker. Instead it delivers the same kind of data, keyless and ToS-clean, through two engines:

  • live (default) — aggregates fresh openings from four public job-board developer APIs (Arbeitnow, RemoteOK, Jobicy, Himalayas), normalizes them into one unified schema, de-duplicates across sources, and filters by your keyword / location / remote / type / salary. A single run easily returns 500 – 1,000+ jobs.
  • indeedArchive — pulls real Indeed job postings from the public web archive (web.archive.org, which is not behind Indeed's Cloudflare), parsing the JobPosting JSON-LD and Indeed's own job-cards data out of archived snapshots.

You get Indeed-style job data with zero API keys and zero blocked requests. This README never claims to live-scrape indeed.com — because nobody can do that keyless, and honesty beats a broken promise.


✨ What this Actor does / Key features

  • 💼 Thousands of fresh jobs per run — the live engine paginates four keyless job feeds and aggregates them into one dataset. Empty input alone returns 500+ current openings.
  • 🧭 Filter like Indeed — by keyword (title / skill / role), location (city, region, country or remote), remote-only, job type (full-time / part-time / contract / temporary / internship), date posted and minimum salary.
  • 💰 Real salary datasalaryMin, salaryMax, salaryCurrency and salaryPeriod as real numbers, plus a human-readable salaryText, wherever the source publishes pay.
  • 🏢 Company + logocompany, companyLogo, and a clickable applyUrl / jobUrl on every row.
  • 🌍 Location, split for youlocation, plus best-effort city / state / country, and a boolean remote flag.
  • 📝 Full descriptions — both descriptionHtml (original markup) and a clean descriptionText, plus a short snippet for previews.
  • 🔀 Cross-source de-duplication — the same job posted on two boards is merged by title + company, so you don't pay for duplicates.
  • 🗄️ Real Indeed archive mode — historical Indeed postings via the Wayback Machine, with automatic Cloudflare-challenge-page detection (empty/challenge captures are skipped, never saved as junk rows).
  • 🗂️ 3 pre-built dataset views — Overview, Live jobs, Indeed archive — slice the data with zero post-processing.
  • Keyless & fast — pure HTTP (no browser, no OAuth). Every item carries source, _mode and scrapedAt (ISO 8601).

The 2 engines (modes)

ModeWhat it returns
liveAggregated fresh job feed from Arbeitnow + RemoteOK + Jobicy + Himalayas, normalized, de-duped and filtered (highest volume, the default).
indeedArchiveReal Indeed job postings parsed from public web-archive snapshots (JobPosting JSON-LD + Indeed job-cards), Indeed-branded historical data.

👥 Who is it for

  • Recruiters & staffing agencies building a live pipeline of open roles and hiring companies.
  • Lead-generation teams who want a fresh list of companies that are hiring (a company that's hiring is a company that's spending).
  • HR & compensation analysts benchmarking salaries by role, seniority and location.
  • Job-board & aggregator builders who need a keyless upstream feed to seed or supplement their own listings.
  • Data scientists & researchers studying the labour market, remote-work trends, skills demand or wage distributions.

🎯 Use cases

  • Recruiting pipeline — pull every open "React developer" or "registered nurse" role and route them to your ATS.
  • Sales prospecting — a company hiring 20 engineers is scaling; surface it before your competitors do.
  • Salary benchmarking — aggregate salaryMin / salaryMax by title and seniority to set competitive bands.
  • Remote-work analytics — filter remote:true and chart the share of remote roles by category over time.
  • Skills-demand tracking — count how often a technology appears in tags / title week over week.
  • Market monitoring — schedule the Actor daily and diff the results to catch new postings the moment they appear.

💡 Why use it (vs. fighting Cloudflare yourself)

  1. It actually returns data. Live Indeed 403s keyless scrapers; this Actor sidesteps that entirely and still gives you rich job rows.
  2. No API keys, no accounts, no cookies. Nothing to register, rotate or get suspended.
  3. Volume by design. Real pagination across four sources → hundreds to thousands of rows in one run.
  4. Clean, typed output. Numbers are numbers, booleans are booleans, dates are ISO 8601 — ready for BI tools and ML.
  5. De-duplicated. You don't pay twice for the same posting appearing on two boards.
  6. Honest and maintainable. Public developer APIs + the public web archive don't change their locks weekly the way an anti-bot vendor does.

📊 What data can you extract

Every row — regardless of source or mode — is normalized to this unified schema:

FieldTypeDescription
jobIdstringStable id (source slug / id, or Indeed job key in archive mode).
titlestringJob title.
companystringHiring company name.
companyLogostring | nullCompany logo URL when available.
locationstring | nullFull location string.
citystring | nullParsed city (best effort).
statestring | nullParsed state / region code (best effort).
countrystring | nullParsed country (best effort).
remotebooleanWhether the role is remote.
salaryMinnumber | nullLower bound of advertised pay.
salaryMaxnumber | nullUpper bound of advertised pay.
salaryCurrencystring | nullCurrency code (e.g. USD).
salaryPeriodstring | nullyear / month / hour etc.
salaryTextstring | nullHuman-readable pay string.
jobTypestring[]Employment type(s): full-time, contract, …
tagsstring[]Skill / topic tags (source-dependent).
categoriesstring[]Industry / category labels.
senioritystring | nullSeniority / experience level.
industrystring | nullPrimary industry.
snippetstring | nullShort plain-text preview.
descriptionTextstring | nullFull description, plain text.
descriptionHtmlstring | nullFull description, original HTML.
datePostedstring | nullISO 8601 posting date.
applyUrlstring | nullDirect application URL.
jobUrlstring | nullCanonical posting URL.
sourcestringarbeitnow / remoteok / jobicy / himalayas / indeed-archive.
_modestringlive or indeedArchive.
scrapedAtstringISO 8601 timestamp of the scrape.

Real output example (live mode)

{
"jobId": "1135188",
"title": "Senior Backend Developer (Go)",
"company": "AlixPartners",
"companyLogo": "https://…/logo.png",
"location": "United States",
"city": null,
"state": null,
"country": "United States",
"remote": true,
"salaryMin": 120000,
"salaryMax": 160000,
"salaryCurrency": "USD",
"salaryPeriod": "year",
"salaryText": "$120,000 - $160,000",
"jobType": ["Full-Time"],
"tags": ["golang", "backend", "engineer", "senior"],
"categories": ["Software Development"],
"seniority": "Senior",
"industry": "Software Development",
"snippet": "We are hiring a senior Go engineer to scale our data platform…",
"descriptionText": "We are hiring a senior Go engineer…",
"descriptionHtml": "<p>We are hiring a senior Go engineer…</p>",
"datePosted": "2026-07-22T08:00:18.000Z",
"applyUrl": "https://remoteok.com/remote-jobs/1135188",
"jobUrl": "https://remoteok.com/remote-jobs/1135188",
"source": "remoteok",
"_mode": "live",
"scrapedAt": "2026-07-23T09:15:04.000Z"
}

🚀 How to use (3 steps)

  1. Leave everything empty and click Start for the broadest feed (500+ fresh jobs from all live sources) — or add a keyword and/or location to narrow it.
  2. (Optional) tune the filters — remote-only, job type, minimum salary, date posted, or restrict to a single source. Switch mode to indeedArchive for real Indeed postings from the web archive.
  3. Run & export — download as JSON, CSV, Excel, HTML, RSS or JSON Lines, or pull results via the Apify API / MCP.

Option A — Apify Console (no code)

Open the Actor, fill the input form (or leave it empty), press Start, then use the Export button on the dataset.

Option B — API / CLI

Start a run and read the dataset via the Apify API (see API usage below), or run it from the Apify CLI.

📥 Input parameters

Every field is optional. Empty input returns a broad, useful feed.

FieldTypeDefaultDescription
modeselectlivelive (aggregate public feeds) or indeedArchive (Indeed from web archive).
querystringKeyword: job title, skill, technology or role. Matched against title, company, tags, description.
locationstringCity, region, country, or remote.
remotebooleanfalseKeep only remote jobs.
sourceselectallall (aggregate + dedupe) or a single board: arbeitnow / remoteok / jobicy / himalayas.
jobTypeselectfull-time / part-time / contract / temporary / internship.
datePostedselectanyany / 1 / 3 / 7 / 14 days.
salaryMinintegerMinimum advertised salary (drops jobs with no salary when set).
maxResultsinteger500Upper bound; drives how deep each source paginates.

Example — broad fresh feed (empty input)

{}

Example — remote developer jobs, decent pay

{
"mode": "live",
"query": "developer",
"remote": true,
"salaryMin": 90000,
"maxResults": 600
}

Example — full-time nursing jobs, aggregated

{
"mode": "live",
"query": "nurse",
"jobType": "fulltime",
"maxResults": 500
}

Example — real Indeed postings from the web archive

{
"mode": "indeedArchive",
"query": "software developer",
"location": "New York",
"maxResults": 200
}

📤 Output

Results stream to the Actor's default dataset, one row per job, in the unified schema above. Three ready-made views are included:

  • Overview — the common columns across every source and mode.
  • Live jobs — the full aggregated feed (best for live).
  • Indeed archive — archived Indeed postings (best for indeedArchive).

Export any view to JSON, CSV, Excel, HTML, RSS or JSON Lines from the Console, or via the API.

🧠 Tips for best results

  1. Empty input = maximum volume. Add filters only to narrow. Start broad, then tighten.
  2. Use maxResults to control cost and depth. Higher values paginate more pages per source.
  3. source: all de-duplicates — same job on two boards is merged. Pick a single source only if you specifically want that board.
  4. Keyword matches broadly — it checks title, company, tags and description, so python surfaces "Python", "Django/Python", etc.
  5. location accepts remote — combine with remote:true for a strict remote filter.
  6. salaryMin drops unpaid-listing rows — many postings omit salary; set this only when you truly need pay data.
  7. The live sources skew tech / remote — for warehouse, nursing or retail roles you'll still get hits, but volume is highest for software, marketing, sales and operations.
  8. indeedArchive is historical by nature — snapshots reflect when Indeed pages were captured, not this second. Use it for Indeed-branded data and back-testing.
  9. Schedule it — run daily and diff datasets to catch brand-new postings.
  10. Watch datePosted — filter to the last 1–7 days for a "what's new" feed.

🔌 Integrations

Send results anywhere Apify integrates: Zapier, Make, n8n, Slack, Google Sheets/Drive, GitHub, Airbyte, webhooks, or your own backend. Push job rows straight into a CRM, ATS, spreadsheet or data warehouse. Trigger runs on a schedule and pipe new rows to Slack or email.

🛠️ API usage

Start a run and fetch the dataset with the Apify API. Replace <TOKEN> with your Apify token.

cURL

# Start a run
curl -s -X POST "https://api.apify.com/v2/acts/logiover~indeed-jobs-scraper/runs?token=<TOKEN>" \
-H "Content-Type: application/json" \
-d '{"query":"developer","remote":true,"maxResults":600}'
# Fetch dataset items (after it finishes)
curl -s "https://api.apify.com/v2/acts/logiover~indeed-jobs-scraper/runs/last/dataset/items?token=<TOKEN>&clean=true&format=json"

JavaScript (apify-client)

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<TOKEN>' });
const run = await client.actor('logiover/indeed-jobs-scraper').call({
query: 'developer',
remote: true,
maxResults: 600,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, 'jobs');

Python (apify-client)

from apify_client import ApifyClient
client = ApifyClient("<TOKEN>")
run = client.actor("logiover/indeed-jobs-scraper").call(run_input={
"query": "developer",
"remote": True,
"maxResults": 600,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(len(items), "jobs")

🤖 MCP / AI agents

This Actor is a clean jobs data tool for AI agents. Because it's keyless and returns structured JSON, you can wire it into an LLM agent (via the Apify MCP server or a direct API call) to answer questions like "find remote Python jobs paying over $100k" or "list companies hiring data engineers this week". Every field is typed, so the model can filter, rank and summarize without scraping HTML itself.

❓ FAQ

Does this scrape indeed.com live?

No — and neither can any keyless scraper. Indeed's site is behind Cloudflare Turnstile and returns 403 to unauthenticated bots. This Actor instead aggregates keyless public job-board APIs (live) and parses real Indeed postings from the public web archive (indeedArchive). You get Indeed-style job data with no API key and no blocked requests.

Is there an Indeed job data API without an API key?

Yes — this Actor is that, in effect. It exposes a clean, keyless job-listings API you call through Apify: send a keyword/location, get back structured jobs. No Indeed key, no OAuth, no login.

How do I scrape Indeed jobs into a CSV?

Run the Actor (empty input or with a keyword), then click Export → CSV on the dataset, or call the API with format=csv. You can export Indeed-style job data to CSV, Excel or JSON in one click.

Where does the salary data come from?

From the sources that publish it (RemoteOK, Jobicy and Himalayas expose pay ranges; Indeed archive snapshots carry baseSalary in JSON-LD). Salary is stored as real numbers in salaryMin / salaryMax with salaryCurrency and salaryPeriod. Set salaryMin to keep only paid listings.

How many jobs can I get per run?

Hundreds to thousands. The default live mode aggregates four sources with real pagination — an empty run returns 500+, and maxResults can push it into the thousands.

Why do I see source: remoteok / jobicy and not indeed?

In live mode the data comes from those keyless job boards, tagged honestly with their source. Switch to mode: indeedArchive to get rows tagged indeed-archive sourced from real archived Indeed pages.

Does indeedArchive always return data?

It returns real Indeed postings when reachable, non-challenge snapshots exist for your query. Some archived captures are themselves Cloudflare "Just a moment" pages — the Actor detects and skips those rather than saving junk. For guaranteed volume, use the default live engine.

Can I get only remote jobs?

Yes — set remote: true (and/or location: remote). The live sources are remote-friendly, so remote volume is high.

Can I filter by job title or skill?

Yes — query matches against title, company, tags and description, so a skill like kubernetes or a role like product manager both work.

Is the data fresh?

The live sources update continuously (hourly on several boards) and are ordered newest-first, so you get current openings. Use datePosted to keep only the last N days.

Can I run this on a schedule?

Yes — use Apify Schedules to run it daily/hourly and pipe new rows to Slack, Sheets, a webhook or your database.

What if a source is temporarily down?

Each source is fetched independently with retries; if one is unavailable the others still deliver, so the run still returns data.

This Actor uses public developer APIs (Arbeitnow, RemoteOK, Jobicy, Himalayas — all of which publish these endpoints for third-party use) and the public web archive (archive.org). It does not bypass Indeed's authentication or anti-bot systems, and it collects only publicly available job-posting information — no personal data beyond what employers publish in a listing, and no login-gated content. You are responsible for complying with each source's terms and with applicable data-protection law (e.g. GDPR) when you store or process the results. When in doubt, consult your legal team.

Looking for more hiring & company data? Explore the rest of the logiover collection on Apify for company registries, lead-generation and business-data Actors that pair well with this jobs scraper.