Indeed Scraper
Pricing
$4.00 / 1,000 results
Indeed Scraper
Scrape public Indeed job search results by keyword or URL. Export titles, employers, locations, pay, posting dates, tags, snippets, and application links.
Pricing
$4.00 / 1,000 results
Rating
0.0
(0)
Developer
MLG Data
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
18 hours ago
Last modified
Categories
Share
Scrape Indeed job search results by keyword, location, country, or public search URL. Export Indeed jobs to JSON, CSV, or spreadsheet files with titles, employers, locations, pay, posting dates, search snippets, and application links. This actor provides a practical Indeed API alternative for collecting public listings without an account.
The actor reads data already embedded in public result pages. It returns one record per job and stops at your requested row limit. The verified New York data analyst search returned 40 jobs, with every required title, employer, location, snippet, job link, and posting date present.
What data can you extract from Indeed?
Every result is a flat record. Fields that a listing does not publish are null or an empty array. The result table below describes the complete output; pay details and search position are small objects inside the record.
| Field | Description | Example |
|---|---|---|
jobKey | Stable identifier carried by the public job card | 1255dc741de28018 |
jobUrl | Direct job page link | https://www.indeed.com/viewjob?jk=1255dc741de28018 |
title | Job title | Data Analyst |
displayTitle | Title displayed in the result card | Data Analyst |
normalizedTitle | Normalized title when supplied | Data Analyst |
companyName | Employer name shown in results | Redacted in this example |
companyUrl | Employer profile link when embedded | A public profile URL |
companyRating | Employer rating where available | 4.3 |
companyReviewCount | Published employer review count | 4221 |
companyLogoUrl | Employer logo link when embedded | An image URL |
location | Formatted job location | New York, NY 10016 |
city | City or location label | New York |
countryCode | Job country | US |
remoteType | Remote or hybrid label | Hybrid work |
isRemote | Whether the label explicitly says remote | false |
jobType | Job type labels | ["Full-time"] |
salary | Pay text, range, period, currency, source | See example below |
benefits | Public benefit labels | ["Wellness program"] |
shiftAndSchedule | Published shift and schedule labels | [] |
attributes | Other job tags exposed in card data | [] |
snippetText | Plain-text search result excerpt | Producing data analysis... |
snippetHtml | Search result excerpt with markup | <ul>...</ul> |
descriptionText | Full text when the page embeds selected-job detail | A longer job description |
descriptionHtml | Full description markup when available | <div>...</div> |
age | Relative age shown in search | 30+ days ago |
datePublished | UTC timestamp from the public card | 2026-07-24T05:00:00Z |
isSponsored | Sponsored result flag | false |
isEasyApply | Direct application flag on the card | false |
applyUrl | Application-start link when supplied | A public URL |
expired | Expired job flag | false |
isUrgentHire | Urgent-hiring flag | false |
isHighVolumeHiring | High-volume hiring flag | false |
source | Posting source shown in detail, otherwise employer | Redacted in this example |
language | Job language when embedded in detail data | en |
locale | Country domain used for search | us |
scrapingInfo | Search page, rank, and original input URL | {"page":1,"index":1,...} |
scrapedAt | UTC collection timestamp | 2026-09-26T14:30:57Z |
The salary object has salaryText, salaryMin, salaryMax, salaryType, salaryCurrency, and salarySource. Pay can be an extracted estimate or a value from the listing, so use the source and original text when comparing compensation. Salary periods vary by listing and country; do not compare an hourly figure with a yearly figure without conversion.
How to scrape Indeed
- Enter a job query such as
data analystand choose a country. Add a location if you need a city or region search. Alternatively, paste a public search result URL inurls. - Set
maxRowsfor keyword mode ormaxRowsPerUrlfor URL mode. Start with 30 to 100 jobs when checking a new market. - Add filters such as job type, recent posting window, or date sort if the public site offers those results. Keep the query broad enough to return the number you need.
- Run the actor. Open the dataset when it finishes to inspect records and export them as JSON, CSV, or a spreadsheet file.
- For repeated collection, schedule the same input and compare
jobKeyvalues across runs. A repeated key represents the same public job card, even if its relative age changes.
Input
Provide either a keyword search or URLs. When urls is nonempty, the actor uses those URLs and ignores the keyword filters. Search URLs must be public /jobs pages; public /cmp/.../jobs URLs are accepted, although company pages can expose different data or require sign-in. A URL outside Indeed is rejected.
| Parameter | Type | Default | Description |
|---|---|---|---|
query | string | data analyst prefill | Search terms for keyword mode; required unless URLs are given |
country | string | us | Two-letter country-domain code, such as us, uk, ca, de, or fr |
location | string | New York, NY prefill | City, region, postal code, or location text |
radius | integer | unset | Distance around the location in the country's local unit |
jobType | string | any | Full time, part time, contract, internship, temporary, or permanent |
level | string | any | Entry, mid, or senior level where offered by the country site |
sort | string | relevance | Relevance or newest-first order |
fromDays | integer | unset | Jobs published within the supplied number of days |
remote | string | any | Remote or hybrid filter where supported |
maxRows | integer | 100 | Maximum jobs for a keyword search |
urls | string array | empty | Public search or company-jobs URLs; activates URL mode |
maxRowsPerUrl | integer | 100 | Limit for each URL in URL mode |
enableUniqueJobs | boolean | true | Deduplicate job keys within each input URL |
proxyConfiguration | object | enabled | Connection settings for public-page access |
Example keyword search:
{"query": "data analyst","country": "us","location": "New York, NY","maxRows": 40}
Example URL search:
{"urls": ["https://www.indeed.com/jobs?q=data+analyst&l=New+York%2C+NY"],"maxRowsPerUrl": 40,"enableUniqueJobs": true}
The country code chooses the search domain: us uses www.indeed.com, uk uses uk.indeed.com, and other two-letter codes use the corresponding subdomain. Country support depends on what each public domain currently serves. Filters can also differ by country; if a filter yields no public results, remove it and run a broader search.
Output example
This shortened record comes from the verified 40-result search. The employer identity, long description, markup, and application tracking URL are removed from the example. Actual dataset records retain values when the source publishes them.
{"jobKey": "1255dc741de28018","jobUrl": "https://www.indeed.com/viewjob?jk=1255dc741de28018","title": "Data Analyst","displayTitle": "Data Analyst","normalizedTitle": "Data Analyst","companyName": "[redacted]","location": "New York, NY 10016","city": "New York","countryCode": "US","remoteType": "Hybrid work","isRemote": false,"salary": {"salaryText": "$70,481.60 - $83,475.00 a year","salaryMin": 70481.6,"salaryMax": 83475,"salaryType": "yearly","salaryCurrency": "USD","salarySource": "EXTRACTION"},"benefits": ["Wellness program"],"snippetText": "Producing data analysis for and providing feedback on data visualizations and descriptions in communications materials...","datePublished": "2026-07-24T05:00:00Z","isSponsored": false,"isEasyApply": false,"expired": false,"locale": "us","scrapingInfo": {"page": 1,"index": 1,"inputUrl": "https://www.indeed.com/jobs?q=data+analyst&l=New+York%2C+NY"}}
The example's descriptionText is omitted because it is long. The verified page embedded a full description for its selected job, while other cards on that page supplied snippets. Do not assume every result includes full detail. The actor preserves the original HTML snippet and supplies a cleaned text version for simpler filtering.
Use cases
- Labor-market monitoring: Track the number and mix of public postings for a job family across cities or countries. Store the query and collection date with each export so comparisons are reproducible.
- Salary research: Collect pay text and numeric ranges for listings that publish compensation. Filter by
salaryTypeandsalaryCurrencybefore calculating summaries. - Recruiting research: Identify public openings, employer names, locations, and links for a specific skill or occupation. Use job keys to avoid reviewing the same posting twice.
- Location analysis: Compare remote, hybrid, and place-based listings. Check
remoteTypeand the original location text together because job cards use varied labels. - Career research: Build a shortlist of current openings and review their snippets, pay, benefits, and application links. Follow the source link for the full posting before making a decision.
- Trend reports: Schedule a stable keyword and location search, then compare new and disappeared keys over time. A missing key from one run is not proof that the vacancy closed, because search order and access can change.
How much does it cost to scrape Indeed?
The configured result charge is $4 per 1,000 delivered jobs, or $0.004 per record. Charges follow the number of records actually written to the dataset, subject to the account's spending limit. Platform usage is included in this result price.
| Delivered jobs | Result charge |
|---|---|
| 40 | $0.16 |
| 250 | $1.00 |
| 1,000 | $4.00 |
A requested maximum is a cap, not a promise of that many jobs. If the public search yields fewer unique records or requires sign-in for deeper pages, fewer records are delivered and the result charge reflects that lower count. A run that cannot collect any jobs fails with an error instead of reporting an empty success.
Tips for best results
Start with the broadest relevant query and a specific location. Search pages can contain more job cards than the visible page-number step suggests: the verified first page carried enough public records to satisfy a 40-row request. For larger collections, use separate searches by occupation, geography, job type, or posting window and combine exports by jobKey.
Keep enableUniqueJobs on when using several page variants. The actor tries the next public search page and, when needed, alternate public first-page filters. Those result sets can overlap. If you turn deduplication off, repeated cards can count toward the row cap.
Use sort: "date" with a frequent schedule to focus on newer results. Use fromDays when you need a recent window, but keep enough time for the market you are studying: a very narrow window may have fewer than 30 listings. If location is blank, searches may reflect the domain's default geography.
Use salary.salaryText as the original statement of pay. Numeric bounds can be extracted from posting text and may be absent, estimated, or expressed for different time units. Check salary.salarySource, salary.salaryType, and salary.salaryCurrency before aggregating values. Use datePublished for a consistent timestamp and age for the wording shown on the page.
For URL mode, paste the exact search URL that produces the desired public results in your browser. Parameters in that URL take precedence over keyword fields. This is useful for site filters that are not exposed as separate actor inputs. Test a modest row cap first to confirm that the URL serves public job cards.
Limits
Indeed can block automated requests, vary results by network location, or redirect later pages to sign-in. The actor rotates connections and can escalate to residential access. In verification, the first run received 403 responses and delivered no jobs; a second run succeeded with 40 jobs. Availability therefore varies between runs. The actor never enters credentials or collects pages behind sign-in.
Pagination is especially limited. Public page-one searches returned structured job cards, while tested later pages redirected to a sign-in screen or were blocked. Filter slices can expose additional public records, but they cannot guarantee complete coverage of every search result or a requested maximum. Company-jobs URLs are accepted as inputs but may not expose the same card data as ordinary search pages; verify them with a small run.
Most cards include a snippet, not a complete job description. Only the job selected in a search page's embedded detail data may provide descriptionText and descriptionHtml. Company profile links, logos, ratings, pay, benefits, job types, language, and application links are also optional. A missing field means the visited public page did not provide that value in the data the actor reads. It does not imply the employer has no such information.
The actor records public job cards at collection time. Search placement, sponsorship, pay text, dates, and application links can change or expire. The direct job link is the best place to verify a listing before applying, contacting an employer, or publishing analysis. No guarantee is made that every link remains live after the run.
Use in automated workflows
The input names and field descriptions allow a workflow to construct a focused search and consume a stable dataset. For example: “Collect up to 40 data analyst jobs in New York, then group them by pay period and remote label.” Another example: “Read the supplied public search URL, save unique job keys, and list postings first seen in this week's export.”
Keep the row limit explicit in automated runs. When building recurring comparisons, store the original input, collection time, and job key. Treat a failed run as an access problem requiring review rather than as evidence that there are no openings.
FAQ
Is it legal to collect these listings?
The actor reads publicly visible job search data. Review the site's terms and the rules that apply to your jurisdiction and intended use. Avoid collecting or using personal information from descriptions for purposes unrelated to the posting.
Do I need to configure a proxy?
The default configuration uses proxy access and can escalate when a cheaper connection is blocked. The verified successful run used public search data through that connection path. Access can still fail during a block or network outage.
How fast is a run?
The verified 40-job run finished in about half a minute. Time varies with blocks, retries, requested rows, and the number of search variants. Large runs can take longer and may stop before the cap if public pages run out.
Can I schedule and monitor it?
Yes. Run the same input on a schedule and inspect run status, record count, and the dataset. Alert on failures or an unexpected drop in results; search ranking and access can change independently of hiring demand.
Can I export to a spreadsheet?
Yes. Download the dataset as CSV or a spreadsheet file. Pay and search-position objects may appear as structured values; expand those columns after export if your analysis needs separate numeric fields.
Why is a field empty?
Fields are populated from the public card or the selected-job detail embedded in the page. Many jobs do not publish pay, benefits, ratings, or complete descriptions there. Use the direct jobUrl to check the current posting.
Why did a search return fewer rows than requested?
The maximum is a stop condition. Public results can be shorter than the cap, repeat across filters, redirect to sign-in, or be blocked. Broaden the query, use a different public search URL, or split a large collection into several distinct searches.
Integrations
The dataset can be read through the platform API, delivered by a webhook, exported to JSON or CSV, and loaded into a spreadsheet or reporting system. A schedule can run the same search repeatedly. For monitoring, compare job keys across dated exports and retain each run's input URL so changes in scope are clear.
Support
Open an issue on the Issues tab; we reply within 24h and add fields on request.