Indeed Scraper - Job Search & Browse Jobs avatar

Indeed Scraper - Job Search & Browse Jobs

Pricing

from $1.50 / 1,000 jobs

Go to Apify Store
Indeed Scraper - Job Search & Browse Jobs

Indeed Scraper - Job Search & Browse Jobs

Collect Indeed job listings from over 60 configured country sites. Search by keyword or Browse Jobs category, with optional descriptions. Pay per delivered job row plus a start fee.

Pricing

from $1.50 / 1,000 jobs

Rating

0.0

(0)

Developer

kane liu

kane liu

Maintained by Community

Actor stats

0

Bookmarked

6

Total users

2

Monthly active users

2 days ago

Last modified

Security

Limited permissions

Share

Indeed Scraper

Get Indeed job titles, employers, locations, salaries and optional descriptions from supported country sites as rows you can export.

  • Search by job title, skill or company, with location and job filters.
  • Discover jobs through Browse Jobs categories.
  • Select one country site or up to 10 countries in one run.
  • Keep job links, hashed job IDs and collection timestamps for comparison.
  • Pay only for the rows you receive: $2.00 per 1,000 rows on the Free plan, plus a small start fee.

What does Indeed Scraper do?

Indeed Scraper collects job listings from Indeed country sites, including www.indeed.com, uk.indeed.com and ca.indeed.com. Each row represents one job. Use the rows for recruiting research, salary comparisons or tracking employers' advertised roles.

  • Search: enter keyword, optionally narrow it with location, and use the available filters.
  • Browse Jobs: set scrapeMode to browse, optionally choosing browseCategory.
  • Country selection: choose from more than 60 configured country sites. Availability and filter support vary by market; a configured country is not a guarantee of results.
  • Optional details: scrapeDetails is off by default. Turn it on to request job descriptions and available employer information. These fields enrich the job row, rather than creating extra rows.

What data can you extract from Indeed?

Values depend on what Indeed publishes and whether details are requested. These are illustrative values, not a live sample.

FieldDescriptionExample
jobKeyStable hashed job identity9f9f5111f7b27a781f1f1ddde5ebc2dd
job_idSame hashed identity as jobKey9f9f5111f7b27a781f1f1ddde5ebc2dd
titleJob title as publishedPharmacist
companyEmployer nameExample Company
location_textDisplayed job locationPhoenix, AZ
cityCity when availablePhoenix
stateState or region when availableAZ
countrySelected country code (uppercase ISO2)US
hostIndeed country domainwww.indeed.com
salary_textPublished salary wording$60 - $65 an hour
salary_minLower bound of a published salary range, or null60000
salary_maxUpper bound of a published salary range, or null65000
salary_periodSalary pay period when publishedYEARLY
salary_currencySalary currency code when publishedUSD
job_typesPublished employment types["Full-time"]
remote_typeRemote or hybrid information when shownremote
benefitsPublished benefit labels, or null["Health insurance"]
descriptionJob description when details are availableExample job description.
company_ratingEmployer rating when shown3.9
company_review_countEmployer review count when shown120
posted_relativeDisplayed age of the listing2 days ago
posted_timestampPosting timestamp when availablenull
sponsoredWhether the listing is marked sponsoredfalse
indeed_apply_enabledWhether Indeed Apply is availabletrue
browse_categoryCategory associated with a browsed jobHealthcare
urlPublic link to the listinghttps://www.indeed.com/viewjob?jk=0123456789abcdef
apply_urlExternal apply link when publishedhttps://example-ats.example/apply/123
apply_redirect_urlIndeed apply redirect link when shown, or nullhttps://www.indeed.com/applystart?jk=0123456789abcdef
company_keyEmployer identifier used for dossier lookups1f9a6328e6e785f3
captured_atCollection time2026-10-24T00:00:00+00:00
addressEmployer headquarters, not the job location{"locality": "Phoenix"}
ldp_addressJob location address when publishednull
webAvailable employer website and social links{"website": "https://example.com", "socials": []}
leadAbsencesReasons that employer information is missing{}

jobKey, job_id and job_id_hash contain the same truncated SHA-256 identity. The public url still contains Indeed's original jk parameter, so hashing the ID fields does not anonymize the link.

How to scrape Indeed

  1. Open Indeed Scraper in Apify Console. A free Apify account is enough to try it.
  2. Enter a keyword, such as pharmacist, and optionally a location.
  3. Set maxResults to 5 for a small first run.
  4. Click Start and wait for completion. Check the status message for warnings.
  5. Download the dataset as JSON, CSV or Excel, or read it through the API.

An empty input starts the example search for pharmacist in Phoenix, AZ, with at most 3 rows. Example rows are billed at the same rate as other rows. Entering only keyword selects search mode and searches the whole selected country site. A category alone does not select browse mode: set scrapeMode explicitly.

Search jobs

Fill keyword with a title, skill or company. Use location for a city, region, postal code or Remote. Select the matching country; us is the default. For UK jobs use gb, which selects uk.indeed.com.

Browse Jobs

Set scrapeMode to browse. No keyword is needed. Use browseCategory, such as Healthcare, to narrow the categories, or leave it empty to explore up to maxCategories. location can narrow the job searches within those categories.

What to fill in

FieldWhat to enterDefault
keywordJob title, skill or company for search modeEmpty; example prefill pharmacist
locationCity, region, postal code or Remote; empty means country-wideEmpty; example prefill Phoenix, AZ
countryTwo-letter code from the country selectorus
countriesUp to 10 country codes; replaces country when populated[]
scrapeModesearch or browsesearch
maxResultsMaximum job rows for this search or browse input, from 1 to 1,00070; form prefill 3
browseCategoryCategory name for browse modeEmpty
maxCategoriesMaximum categories to follow, from 1 to 10020
sortrelevance or daterelevance
datePosted1, 3, 7 or 14 days; empty means any ageEmpty
jobTypeEmployment type, such as fulltime, parttime or contractEmpty
experienceLevelentry_level, mid_level or senior_levelEmpty
educationhigh_school, associate, bachelor, master or doctoralEmpty
remoteTyperemote or hybridEmpty
radiusSearch radius: 0, 5, 10, 15, 25, 35, 50 or 100Empty
encouragedToApplyfairchance, no_degree or military_encouragedEmpty
indeedApplyOnlyRequest listings with Indeed Applyfalse
scExtraAdvanced Indeed filter fragment, only if you know its valueEmpty
maxPagesPage limit for each search, from 1 to 1001
scrapeDetailsRequest job descriptions and available employer detailsfalse
detailConcurrencyNumber of detail pages requested together, from 1 to 51

Search with details:

{
"keyword": "pharmacist",
"location": "Phoenix, AZ",
"country": "us",
"maxResults": 5,
"scrapeDetails": true
}

Browse one category:

{
"scrapeMode": "browse",
"country": "us",
"browseCategory": "Healthcare",
"maxCategories": 1,
"maxResults": 5
}

Search several countries with one shared row limit:

{
"keyword": "nurse",
"countries": ["gb", "ie", "au"],
"maxResults": 6
}
  • maxItems and limit are aliases for maxResults. query, searchTerm and jobTitle are aliases for keyword; city is an alias for location.
  • Unknown fields do not fail the run. Close misspellings can be corrected; other unknown fields are ignored with a note.
  • Unsupported filter values are ignored with a warning. An unknown single country falls back to us; invalid entries in countries are skipped.
  • Invalid input stops before any job row is charged, with a message such as INVALID_INPUT: maxPages: out of range. The start fee is separate.
  • The INPUT_REPORT record in the run's key-value store records fields filled, corrected or ignored. It also identifies an example run.

Output example

This illustrative row shows a job with details available. Fields can be null or empty when the source does not provide them.

{
"source": "indeed",
"jobKey": "9f9f5111f7b27a781f1f1ddde5ebc2dd",
"job_id": "9f9f5111f7b27a781f1f1ddde5ebc2dd",
"title": "Pharmacist",
"company": "Example Company",
"location_text": "Phoenix, AZ",
"country": "US",
"host": "www.indeed.com",
"salary_text": "$60 - $65 an hour",
"job_types": ["Full-time"],
"remote_type": null,
"benefits": ["Health insurance"],
"description": "Example job description.",
"url": "https://www.indeed.com/viewjob?jk=0123456789abcdef",
"captured_at": "2026-10-24T00:00:00+00:00"
}

You can export the dataset as JSON, CSV, Excel, XML, RSS or an HTML table. RUN_SUMMARY provides counts and warnings; INPUT_ECHO records the interpreted settings. Employer phone and email fields may be empty: the Actor does not invent contact details.

Why use this Indeed scraper?

  • Pay per row. The row charge applies to jobs written to the dataset, not pages attempted. A start fee also applies.
  • Usable partial rows. When job details cannot be fetched, available listing rows can still be delivered. Check the status message for missing descriptions. Rows already saved remain available after a stop; this does not guarantee delivery of unfinished work.
  • Clear input feedback. Input errors name the field, while INPUT_REPORT records corrections.
  • Source values stay recognizable. Missing salaries and benefits stay empty. Published titles are preserved, including occasional Jobs for you titles.
  • Multiple markets. Select several countries for the same keyword without preparing separate inputs.
  • No proxy setup. You do not need to set up proxies or supply an Indeed account or API key.

How much does it cost to scrape Indeed?

The Actor uses pay-per-event pricing. The start event costs $0.005 per GB of Actor memory, with a minimum of one event. At the configured default of 512 MB, that is $0.005 per start, plus the row charges below.

Apify planPrice per rowPrice per 1,000 rows
Free$0.002$2.00
Starter$0.002$2.00
Scale$0.002$2.00
Business$0.0015$1.50
  • maxResults applies to the keyword/location or Browse Jobs input. Countries, categories and pages share that limit; it is not a separate allowance for each country.
  • The default is 70 rows. Larger requests are collected in parts of 70, subject to available jobs and other limits. The input allows up to 1,000.
  • Free Apify plan users are limited to 200 rows per run and 10 runs of this Actor. These are limits set by the Actor developer. Paid plans remove the 10-run limit, not the input or spending limits.
  • Set Maximum cost per run in the run options (maxTotalChargeUsd in the API) to cap spending for the whole run.

Example: a Free-plan run delivering 150 rows at the default memory costs 150 × $0.002 + $0.005 = $0.305. Returning fewer rows costs less. A three-row example costs $0.011, including one start event.

What happens when the run timeout is too short

Some Indeed collections, such as several countries, a high maxPages or maxResults, or scrapeDetails: true, can take longer than the run timeout you chose. In that case the run does not fail. It ends early with the status message "Queued on the collection backend; this run will resume automatically when results are ready (about N s)." and shows as ABORTED for a while.

When the results are ready, the same run starts again by itself, reports "Resumed: delivering N rows.", writes the rows to the same dataset and finishes as SUCCEEDED. Rows that were already delivered are skipped, so no row is delivered or charged twice. You do not need to start another run.

  • This can happen at most 3 times per run. To avoid it, keep the default timeout of 3600 seconds.
  • The synchronous API endpoints (run-sync, run-sync-get-dataset-items) wait at most 300 seconds and can return an empty dataset while the run is paused. For larger jobs, start the run asynchronously and read the dataset after the run reaches SUCCEEDED, or use a webhook on the "succeeded" event.

Use with AI agents and the API

Apify MCP server (Claude, ChatGPT, Cursor, VS Code)

Add this Actor as a tool in an MCP client that supports remote servers:

https://mcp.apify.com?tools=lentic_clockss/indeed-jobs-scraper

Sign in with Apify when asked using OAuth, or send Authorization: Bearer <YOUR_APIFY_TOKEN>. The tool starts a run and returns the run and dataset IDs. The agent then reads rows with get-dataset-items.

Clients without remote MCP support can run npx @apify/actors-mcp-server --tools lentic_clockss/indeed-jobs-scraper with the APIFY_TOKEN environment variable.

Example prompt: "Find up to five pharmacist jobs in Phoenix, AZ, on Indeed's US site. Return the title, company, salary and job link."

Apify API

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("lentic_clockss/indeed-jobs-scraper").call(
run_input={"keyword": "pharmacist", "location": "Phoenix, AZ", "maxResults": 5}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('lentic_clockss/indeed-jobs-scraper').call({
keyword: 'pharmacist', location: 'Phoenix, AZ', maxResults: 5
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Over HTTP, send POST https://api.apify.com/v2/acts/lentic_clockss~indeed-jobs-scraper/runs with the input JSON and an Authorization: Bearer <YOUR_APIFY_TOKEN> header. After the run finishes, read GET https://api.apify.com/v2/datasets/<datasetId>/items?format=json using its dataset ID.

Integrations

Use the Actor's Integrations tab to connect results to Google Sheets, Make, Zapier, n8n, Slack, Airtable or your own webhook. Use Apify Schedules for recurring runs.

FAQ

Public access is not automatic permission for every use. You are responsible for complying with Indeed's terms and applicable data protection law. Processing personal data requires a lawful basis. Collect only what you need and assess your intended use before running the Actor.

Why did my run end as ABORTED?

The run stopped before normal completion. Read its status message and log for the reason; do not assume that all requested rows were delivered or that it will restart automatically. Check the dataset for saved rows and include the run ID when asking for help.

How many results can I get?

maxResults accepts 1 to 1,000 for one search or browse input. Matching listings, maxPages, spending limits and free-plan limits can reduce the delivered count. Selecting three countries does not triple the row allowance.

Why are some fields empty?

Indeed does not publish every field for every job. Descriptions generally need scrapeDetails: true, and a failed detail request can leave them empty. benefits stays null when no readable benefit labels are available. Employer headquarters in address is separate from the job location in ldp_address.

Can I scrape remote jobs only?

Use remoteType: "remote", or hybrid for hybrid roles, and optionally location: "Remote". Remote and education filters have their strongest support on us, ca, gb, au and ie; check the returned rows rather than assuming identical filtering in every country.

Does Browse Jobs require a keyword?

No. Set scrapeMode: "browse" and optionally browseCategory. The category and page limits still apply, and not every country site exposes the same categories.

Why does a row have the title Jobs for you?

Indeed sometimes publishes that text instead of a role name. The Actor keeps it rather than guessing. RUN_SUMMARY.placeholderTitleCount counts those rows so you can identify them when reviewing output.

Why did my free-plan run stop with a limit message?

The Actor allows Free-plan users 10 runs and at most 200 rows per run. Read the status message to see which limit applied. A paid Apify plan removes the developer's free-plan run restriction.

Limitations

  • Search results change over time. This is not a complete archive of all Indeed jobs, and a requested row count is not a promise of that many matches.
  • The default maxPages is 1. Increase it for broader searches, while keeping maxResults and the spending cap appropriate.
  • Country sites, categories and filters differ. A country listed in the form may be unavailable, and narrow filters can return no matches.
  • Job details and employer information are optional and may be unavailable even when a listing row is returned. Phone numbers, emails and full addresses are not guaranteed.
  • The public input supports keyword search and Browse Jobs, not a list of individual job URLs. It does not submit applications.

More job board and freelance marketplace scrapers from the same publisher:

Browse all of our scrapers at apify.com/lentic_clockss.

Support

Found a problem or need another field? Open an issue in the Issues tab of this Actor's page and include the run ID and the input you used.