# Jobs Search API — Indeed, LinkedIn & Glassdoor Aggregator (`sian.agency/jsearch-jobs-scraper`) Actor

Aggregate job postings from every major board — Indeed, LinkedIn, Glassdoor, ZipRecruiter and company career pages — in one run via Google for Jobs. 4 operations: job search, full job details with required skills and seniority, salary estimates by title and per company. Clean JSON, pay per result.

- **URL**: https://apify.com/sian.agency/jsearch-jobs-scraper.md
- **Developed by:** [SIÁN OÜ](https://apify.com/sian.agency) (community)
- **Categories:** Jobs, Business, AI
- **Stats:** 139 total users, 22 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 job search results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Jobs Search API — Indeed, LinkedIn & Glassdoor in One Run 🧲

[![SIÁN Agency Store](https://img.shields.io/badge/Store-SI%C3%81N%20Agency-1AE392)](https://apify.com/sian.agency?fpr=sian) [![Store-Glassdoor Scraper](https://img.shields.io/badge/Store-Glassdoor%20Scraper-0CAA41)](https://apify.com/sian.agency/glassdoor-data-scraper?fpr=sian) [![Store-Trustpilot Reviews](https://img.shields.io/badge/Store-Trustpilot%20Reviews-00B67A)](https://apify.com/sian.agency/trustpilot-reviews-scraper?fpr=sian) [![Store-Instagram AI Transcript](https://img.shields.io/badge/Store-Instagram%20AI%20Transcript-E4405F)](https://apify.com/sian.agency/instagram-ai-transcript-extractor?fpr=sian)

#### 🎉 Every major job board in one run — Indeed, LinkedIn, Glassdoor & ZipRecruiter aggregated and deduped via Google for Jobs, no API key required

##### Built for recruiters, sourcing tools, job-board founders, labor-market analysts, and HR-tech teams who need clean, structured job data on a schedule

### 📋 Overview

**One query, every board.** Most job scrapers on the Store cover a single source — LinkedIn *or* Indeed *or* Glassdoor — so you run several actors and dedupe by hand. This actor wraps **Google for Jobs**, which already aggregates Indeed, LinkedIn, Glassdoor, ZipRecruiter and company career pages into one deduped feed. Type a query, click Run, get clean JSON back. No API key, no developer registration, no proxy setup.

It bundles **4 operations** behind a single dropdown: keyword **Job Search** across every board, deep **Job Details** with recruiting-intelligence columns (seniority, required tech stack, experience years, visa & relocation), **Estimated Salary** by title and location, and **Company Salary** for a specific employer. Pick one operation per run, get one tidy dataset out.

**Why thousands of professionals choose us:**

- ✅ **All boards in one run**: Indeed, LinkedIn, Glassdoor, ZipRecruiter and career pages aggregated and **deduped by Google for Jobs** — no more running one scraper per board
- ⚡ **4 operations in one actor**: Job Search · Job Details · Estimated Salary · Company Salary, picked from one dropdown
- 🎯 **The column nobody else returns**: Job Details enriches each posting with `seniorityLevel`, `requiredTechnologies`, `requiredExperienceYears`, `visaSponsorship`, `relocationAssistance`, `aiMlInvolved`, `industry` and `jobFunction` — a recruiting-intelligence set single-board scrapers don't expose
- 💰 **Pay only for successful rows**: failed lookups land as `status:"error"` rows at **$0** — you're never billed for a hiccup
- 💎 **Salary estimation built in**: estimated pay by title + location and per company, with base and additional pay across hourly, monthly and yearly periods — no separate actor to buy
- ✨ **No API key, zero setup**: no Indeed API key, no LinkedIn developer account, no Google for Jobs approval — paste an input and run

### ✨ Features

- 🔍 **Job Search**: free-form keyword search across every board via Google for Jobs, cursor-paginated (~10 jobs/page), with date, employment-type, remote, and experience filters
- 📄 **Job Details**: deep single-job enrichment — required and preferred technologies, seniority, experience years, visa sponsorship, relocation, education, work arrangement, industry and salary range, by Job ID
- 💵 **Estimated Salary**: estimate pay for any title + location, broken down into base and additional pay across hourly, monthly and yearly periods, with a confidence score
- 🏢 **Company Salary**: benchmark estimated pay for a title inside a specific employer (e.g. `software engineer` at `Google`)
- 🌍 **40+ countries**: query any market with a simple ISO country code (`us`, `gb`, `ca`, `de`, `in`, …)
- 🧑‍💼 **Native Filters**: date posted, employment type (`FULLTIME`/`CONTRACTOR`/`PARTTIME`/`INTERN`), remote-only, experience and education requirements, publisher exclusions
- 📍 **Geo-Ready Rows**: every job carries `city`, `state`, `country`, `latitude` and `longitude` — plot postings on a map out of the box
- 🔗 **Direct Apply Links**: `applyLink`, `applyIsDirect` and all `applyOptions` so you can route candidates straight to the source
- 🖼️ **Employer Logos & Sites**: `employerName`, `employerLogo` and `employerWebsite` on every posting for branded feeds
- 📊 **Single Clean Dataset Shape**: one flat row per item, filterable by `_operation` and `status` — the same export pipeline works across all four operations

### 🎬 Quick Start

So simple, no training needed! Pick an operation, fill the matching input, click Run.

```bash
## Or use the API — one line
curl -X POST https://api.apify.com/v2/acts/sian.agency~jsearch-jobs-scraper/runs?token=YOUR_TOKEN \
-d '{"operation":"jobSearch","query":"software engineer in new york","maxPages":3}'
```

### 🚀 Getting Started (3 Simple Steps)

#### Step 1: Pick an Operation

Choose one of four operations from the dropdown: **Job Search**, **Job Details**, **Estimated Salary**, or **Company Salary**. One run = one operation.

#### Step 2: Fill the Matching Input

- **Job Search** → a `query` (e.g. `software engineer in new york`)
- **Job Details** → a `jobId` from any search result
- **Estimated Salary** → a `jobTitle` + `location`
- **Company Salary** → a `jobTitle` + `company`

Optionally set `country`, `datePosted`, `employmentTypes`, `workFromHome`, and `maxPages`.

#### Step 3: Click Run

One click and we search, flatten, normalize, and push clean rows to your dataset. An HTML run report lands in the key-value store. Export to JSON, CSV, or Excel from the Apify console — or pull via API.

**That's it! In seconds, you'll have:**

- Clean flat rows from any of four operations — same shape, ready to export
- Jobs aggregated across Indeed, LinkedIn, Glassdoor and ZipRecruiter, already deduped
- Apply links, employer logos, geo-coordinates and salary ranges on every posting
- Recruiting-intelligence fields (seniority, required tech, experience) from Job Details
- Error rows for failed inputs — never billed

### 📥 Input Configuration

One operation per run. Each operation has its own required field (validated before charging). The remaining filters apply to Job Search and the salary operations where relevant.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| operation | enum | Yes | One of: `jobSearch`, `jobDetails`, `estimatedSalary`, `companySalary` |
| query | string | jobSearch | Free-form search (e.g. `software engineer in new york`) |
| jobId | string | jobDetails | Job ID from a search row (e.g. `22jWL_JNHtSxAieXAAAAAA==`) |
| jobTitle | string | estimatedSalary, companySalary | Title to estimate pay for (e.g. `software engineer`) |
| location | string | estimatedSalary | Location to estimate pay for (e.g. `United States`) |
| company | string | companySalary | Company to benchmark in-company pay (e.g. `Google`) |
| country | string | No | ISO country code for search/details (`us` default, `gb`, `ca`, `de`, `in`…) |
| datePosted | enum | No (search) | `all`, `today`, `3days`, `week`, `month` |
| employmentTypes | string | No (search) | Comma-separated: `FULLTIME`, `CONTRACTOR`, `PARTTIME`, `INTERN` |
| workFromHome | boolean | No (search) | Return only remote / work-from-home jobs |
| jobRequirements | string | No (search) | Experience/education filters (e.g. `more_than_3_years_experience`) |
| locationType / yearsOfExperience | enum | No (salary) | Scope and experience bracket for salary estimates |
| maxPages | integer | No (search) | 1–20, ~10 jobs/page (default 3) |

**Example — Job Search:**

```json
{
  "operation": "jobSearch",
  "query": "software engineer in new york",
  "datePosted": "week",
  "employmentTypes": "FULLTIME",
  "maxPages": 3
}
```

**Example — Job Details (single posting):**

```json
{
  "operation": "jobDetails",
  "jobId": "22jWL_JNHtSxAieXAAAAAA=="
}
```

**Example — Estimated Salary:**

```json
{
  "operation": "estimatedSalary",
  "jobTitle": "registered nurse",
  "location": "United States"
}
```

**Example — Company Salary:**

```json
{
  "operation": "companySalary",
  "jobTitle": "software engineer",
  "company": "Google"
}
```

💡 **Workflow tip:** Run Job Search to discover Job IDs, then loop Job Details per posting to enrich each one with required skills, seniority and experience.

### 📤 Output

One flat row per item, saved to the Apify dataset. Search and details rows carry job fields; salary rows carry pay fields. Curated camelCase aliases land on every row alongside the raw upstream data. Filter by `_operation` to split modes, or by `status` to separate success from error rows.

| Field | Type | Description |
|-------|------|-------------|
| jobId | string | Stable Job ID (use with Job Details) |
| jobTitle | string | Job title |
| employerName / employerLogo / employerWebsite | string | Employer identity |
| jobPublisher | string | Source board (Indeed, LinkedIn, Glassdoor…) |
| employmentType | string | `Full-time`, `Contractor`, etc. |
| applyLink / applyIsDirect / applyOptions | string / boolean / array | Apply destinations |
| isRemote | boolean | Remote / work-from-home flag |
| location / city / state / country | string | Location breakdown |
| latitude / longitude | number | Geo-coordinates |
| postedAt / postedAtTimestamp / postedAtUtc | string / integer | When the job was posted |
| salaryString / minSalary / maxSalary / medianSalary | string / number | Pay range on the posting |
| seniorityLevel / requiredExperienceYears | string / number | Recruiting-intelligence (Job Details) |
| requiredTechnologies / preferredTechnologies | array | Tech-stack mapping (Job Details) |
| visaSponsorship / relocationAssistance / aiMlInvolved | boolean | Enrichment flags (Job Details) |
| industry / jobFunction / educationRequired | string | Role classification (Job Details) |
| minBaseSalary / medianBaseSalary / maxBaseSalary | number | Salary estimate breakdown |
| minAdditionalPay / medianAdditionalPay / maxAdditionalPay | number | Bonus / additional pay |
| salaryPeriod / salaryCurrency / confidence | string | Salary metadata (Estimated / Company Salary) |
| \_operation / \_fetchedAt / \_page / status | metadata | Always-present row metadata |

All three examples below are **real captured output** (June 2026; trimmed to the most useful fields):

**Example — Job Search row:**

```json
{
  "_operation": "jobSearch",
  "jobId": "22jWL_JNHtSxAieXAAAAAA==",
  "jobTitle": "Software Engineer, Full Stack",
  "employerName": "Plaid",
  "jobPublisher": "Plaid",
  "employmentType": "Full-time",
  "isRemote": false,
  "location": "New York, NY",
  "applyLink": "https://plaid.com/careers/openings/engineering/new-york-city-office/...",
  "applyIsDirect": true,
  "status": "success"
}
```

**Example — Job Details row (recruiting-intelligence enrichment):**

```json
{
  "_operation": "jobDetails",
  "jobId": "22jWL_JNHtSxAieXAAAAAA==",
  "jobTitle": "Software Engineer, Full Stack",
  "employerName": "Plaid",
  "seniorityLevel": "mid",
  "requiredExperienceYears": 2,
  "requiredTechnologies": ["HTML", "CSS", "JavaScript", "MySQL"],
  "preferredTechnologies": [],
  "workArrangement": "On-site",
  "visaSponsorship": false,
  "relocationAssistance": false,
  "aiMlInvolved": false,
  "industry": "Financial Services",
  "jobFunction": "Engineering",
  "minSalary": 176000,
  "maxSalary": 227000,
  "status": "success"
}
```

**Example — Estimated Salary row:**

```json
{
  "_operation": "estimatedSalary",
  "jobTitle": "Registered Nurse",
  "location": "United States",
  "minSalary": 85518.83,
  "medianSalary": 100960.41,
  "maxSalary": 120101.77,
  "salaryPeriod": "YEAR",
  "salaryCurrency": "USD",
  "confidence": "CONFIDENT",
  "status": "success"
}
```

### 💼 Use Cases & Examples

#### 1. Multi-Board Job Aggregation — One Deduped Feed

**For job-board founders and aggregator apps that need every board without running one scraper per source.**

**Input:** Schedule `jobSearch` on your target queries on a daily cron
**Output:** Postings from Indeed, LinkedIn, Glassdoor, ZipRecruiter and career pages — already deduped by Google for Jobs — with apply links, logos and geo-coordinates
**Use:** Power a niche job board or sourcing tool with fresh, structured listings, without scraping each source site directly.

#### 2. Recruitment Market Intelligence — Quantify Hiring Demand

**For labor-market analysts and HR-tech teams measuring hiring demand by role and region.**

**Input:** `jobSearch` paginated across roles and locations, filtered by `datePosted`
**Output:** Hundreds of postings with employer, location, employment type, remote flag and posting date
**Use:** Track which employers are hiring, how fast postings turn over, and how demand shifts by geography — feed structured rows straight into dashboards and reports.

#### 3. Required-Skills & Tech-Stack Mapping

**For technical recruiters and competitive-intelligence teams mapping the skills landscape for a role.**

**Input:** `jobDetails` looped over Job IDs collected from a search run
**Output:** `requiredTechnologies`, `preferredTechnologies`, `seniorityLevel`, `requiredExperienceYears`, `educationRequired` and the `aiMlInvolved` flag per posting
**Use:** Build a skills map for any role, compare your own job specs against the market, and spot which technologies are trending in your sector.

#### 4. Salary Benchmarking — Title & Company

**For compensation teams, salary tools and offer-letter builders that need pay benchmarks.**

**Input:** `estimatedSalary` by title + location, plus `companySalary` for specific employers
**Output:** Base and additional pay (min / median / max) across hourly, monthly and yearly periods, with a confidence score
**Use:** Power compensation calculators, salary guides and offer letters with defensible, location-aware pay estimates.

#### 5. Job-Board & ATS Product Feeds

**For product teams building a job aggregator, sourcing tool or applicant-tracking integration.**

**Input:** `jobSearch` on a schedule, enriched with `jobDetails` per posting
**Output:** Apply links, employer logos, location coordinates, benefits and full job descriptions in one clean shape
**Use:** Feed your product with fresh, structured postings — including direct apply routing — without maintaining a scraper for each source.

#### 6. Remote-Work Trend Research

**For researchers and remote-work platforms tracking the remote hiring market.**

**Input:** `jobSearch` with `workFromHome: true` across roles and weeks
**Output:** Remote-only postings with employer, salary range, employment type and posting date
**Use:** Quantify remote hiring trends, surface remote-friendly employers, and benchmark remote pay against on-site roles.

### 🔌 Integration Examples

#### JavaScript/Node.js

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });

// Search jobs, then enrich the first posting with full details
const search = await client.actor('sian.agency/jsearch-jobs-scraper').call({
  operation: 'jobSearch',
  query: 'software engineer in new york',
  maxPages: 2
});

const { items } = await client.dataset(search.defaultDatasetId).listItems();
const ids = items.filter(i => i.status === 'success').map(i => i.jobId);
console.log(`${ids.length} jobs found`);
```

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')

## Estimate salary for a title and location
run = client.actor('sian.agency/jsearch-jobs-scraper').call(
    run_input={'operation': 'estimatedSalary', 'jobTitle': 'registered nurse', 'location': 'United States'}
)

for item in client.dataset(run['defaultDatasetId']).iterate_items():
    if item.get('status') == 'success':
        print(f"{item['jobTitle']} — median {item['medianSalary']} {item['salaryCurrency']}/{item['salaryPeriod']}")
```

#### cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/sian.agency~jsearch-jobs-scraper/runs?token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"operation":"jobDetails","jobId":"22jWL_JNHtSxAieXAAAAAA=="}'
```

#### Automation Workflows (N8N / Zapier / Make)

1. **Trigger**: Schedule (daily job refresh) or webhook (new search saved by a user)
2. **HTTP Request**: Call the actor API with `operation` and the per-op input fields
3. **Process**: Dedupe against yesterday's `jobId` set, filter on `isRemote`, or map `requiredTechnologies`
4. **Action**: Push new postings to Slack, sync rows to Google Sheets, or load them into your job database

### 📈 Performance & Pricing

Transparent **pay-per-event** — you're charged only for **successful rows**, plus a small one-time start fee per run. Failed lookups land as `status:"error"` rows and cost **$0**. Higher Apify plans get automatic volume discounts on every event.

#### FREE Tier (Try It Now)

- **Multi-board Job Search is free and unlimited** — run the aggregator across Indeed, LinkedIn, Glassdoor and ZipRecruiter at no cost
- Same data quality, deduped feed — evaluate coverage before you scale
- No credit card required
- Job Details, Estimated Salary and Company Salary are paid features (free runs return an upgrade notice row at **$0** — no charge)

#### PAID Tier (Production Ready)

- Unlimited jobs, details, and salary estimates per run
- Pay-per-result: only charged for successful rows
- Job Search is priced as a loss-leader so bulk aggregation stays cheap

💰 **Best price on the market for a multi-board aggregator** — one run replaces several single-board scrapers, with no Indeed or LinkedIn API approval to wait on.

🔗 [View current pricing](https://apify.com/sian.agency/jsearch-jobs-scraper?fpr=sian)

### ❓ Frequently Asked Questions

**Q: Which job boards does this cover?**
A: It wraps **Google for Jobs**, which aggregates Indeed, LinkedIn, Glassdoor, ZipRecruiter and company career pages into one deduped feed. One query returns postings from all of them at once.

**Q: Do I need an Indeed, LinkedIn, or Google for Jobs API key?**
A: No. This actor requires **no API key, no developer registration, and no approval** — just an Apify token. Paste your input, click Run, get structured data back.

**Q: What does Job Details return that a search row doesn't?**
A: A recruiting-intelligence column set: `seniorityLevel`, `requiredExperienceYears`, `requiredTechnologies`, `preferredTechnologies`, `visaSponsorship`, `relocationAssistance`, `aiMlInvolved`, `educationRequired`, `workArrangement`, `industry` and `jobFunction` — fields single-board scrapers don't expose. Run Job Search first to collect Job IDs, then loop Job Details.

**Q: How does salary estimation work?**
A: **Estimated Salary** returns min / median / max base and additional pay for a title + location; **Company Salary** does the same scoped to a specific employer. Both include a `confidence` score. Broad titles and locations return the most reliable estimates.

**Q: Which countries are supported?**
A: 40+ markets — set `country` to any ISO 3166-1 alpha-2 code (`us`, `gb`, `ca`, `de`, `in`, …). Default is `us`.

**Q: How do I get remote-only jobs?**
A: Enable the `workFromHome` toggle on Job Search to return only remote / work-from-home postings.

**Q: What output formats are available?**
A: JSON, CSV, and Excel — export directly from the Apify dataset console, or pull via API.

**Q: How am I billed, and what about failed lookups?**
A: Pay-per-event — only successful rows are charged, plus a one-time start fee. Failed lookups (no salary data, unknown Job ID) land as `status:"error"` rows at **$0**.

### 🐛 Troubleshooting

**A run returns `status:"error"` with "temporarily unavailable"**

- The data source hit a transient hiccup. The actor retries automatically with backoff. Re-run after a moment — error rows are never charged.

**Estimated Salary / Company Salary returns no row**

- Very niche titles or hyper-specific locations may have no salary estimate. Broaden the `jobTitle` (e.g. `software engineer` not `senior staff platform engineer III`) and use a broader `location` (a metro, state, or country).

**Job Details returns "not found"**

- Confirm the `jobId` came from a recent Job Search row (the `jobId` field, e.g. `22jWL_JNHtSxAieXAAAAAA==`). Job IDs can expire as postings are removed — re-run the search to refresh them.

**Job Search returns fewer rows than expected**

- Thin coverage for a query returns fewer than ~10 rows/page. Broaden the query, relax `datePosted` and `employmentTypes` filters, or paginate deeper with `maxPages`.

**Results are for the wrong country**

- Set `country` to the right ISO code (e.g. `gb` for the UK) and include the location in your `query`.

### 🧰 More by SIÁN Agency

- [Glassdoor Scraper](https://apify.com/sian.agency/glassdoor-data-scraper?fpr=sian) — Reviews, salaries, jobs & interviews
- [Trustpilot Reviews Scraper](https://apify.com/sian.agency/trustpilot-reviews-scraper?fpr=sian) — Company reputation & consumer reviews
- [Instagram AI Transcript Extractor](https://apify.com/sian.agency/instagram-ai-transcript-extractor?fpr=sian) — Reels & video transcripts
- [Browse all SIÁN actors →](https://apify.com/sian.agency?fpr=sian)

### ⚠️ Trademark Disclaimer

This actor is an independent tool and is **not affiliated with, endorsed by, or sponsored by Google LLC, Indeed, LinkedIn, Glassdoor, ZipRecruiter, or any job board.** "Google for Jobs", "Indeed", "LinkedIn", "Glassdoor", "ZipRecruiter" and related marks are trademarks of their respective owners and are used here only to describe the data this tool helps you collect. Use this actor responsibly and in compliance with applicable laws, each platform's terms of service, and data-protection regulations (including GDPR and CCPA where applicable). You are responsible for how you use the data you extract.

### ⚖️ Is it legal to scrape data?

Our actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what employers and job boards have chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.

However, you should be aware that your results could contain personal data. Personal data is protected by the **GDPR** in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

You can also read Apify's blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

***

### 🤝 Support

**Join our active support community**

- For issues or feature requests, open an issue in the actor's repository or use the **Issues** tab on the actor page
- Check [SIÁN Agency Store](https://apify.com/sian.agency?fpr=sian) for more automation tools
- 📧 <apify@sian-agency.online>
- ⭐ If this saves you time, a 5-star review helps us ship more features.

***

**Built by [SIÁN Agency](https://www.sian-agency.online)** | **[More Tools](https://apify.com/sian.agency?fpr=sian)**

# Changelog

This Actor's version history is a separate document: https://apify.com/sian.agency/jsearch-jobs-scraper/changelog.md

# Actor input Schema

## `operation` (type: `string`):

🎯 **PICK ONE OPERATION PER RUN.** Each run produces one clean dataset matching the chosen mode.

- **🔍 Job Search** — search every job board at once via Google for Jobs, paginated (~10 jobs/page)
- **📄 Job Details** — deep details for one job (required skills, seniority, experience, visa, salary) — by Job ID
- **💵 Estimated Salary** — estimated pay for a title + location, by hourly/monthly/yearly period
- **🏢 Company Salary** — estimated pay for a title inside a specific company

💡 **TIP:** Run Job Search first to discover Job IDs, then drill into Job Details per posting.

## `query` (type: `string`):

🔍 **Required for `Job Search` operation.**

A free-form job search query — exactly what you would type into Google for Jobs.

- `software engineer in new york`
- `remote marketing manager`
- `registered nurse chicago`

💡 **TIP:** Include the location in the query for best results, or use the `Work from home` toggle for remote-only.

⚠️ **Ignored** for all other operations.

## `jobId` (type: `string`):

📄 **Required for `Job Details` operation.**

The Job ID from a Job Search result row (the `jobId` field, e.g. `22jWL_JNHtSxAieXAAAAAA==`).

💡 **TIP:** Run `Job Search` first, collect the `jobId` values, then loop through Job Details to enrich each posting with required skills, seniority, and experience.

⚠️ **Ignored** for all other operations.

## `jobTitle` (type: `string`):

💼 **Required for `Estimated Salary` and `Company Salary`.**

The job title to estimate pay for.

- `nurse`
- `software engineer`
- `data analyst`

💡 **TIP:** Common, broad titles return the most reliable salary data. Very niche titles may return no estimate.

⚠️ **Ignored** for Job Search and Job Details.

## `location` (type: `string`):

📍 **Required for `Estimated Salary`** (optional for `Company Salary`).

The location to estimate pay for.

- `United States`
- `New York, NY`
- `San Francisco, CA`

💡 **TIP:** Broad locations (`United States`, a state, or a metro) return the most reliable estimates. A very specific address may return no data.

⚠️ **Ignored** for Job Search and Job Details.

## `company` (type: `string`):

🏢 **Required for `Company Salary` operation.**

The company name to estimate in-company pay for.

- `Google`
- `Amazon`
- `Microsoft`

⚠️ **Ignored** for all other operations.

## `country` (type: `string`):

🌍 ISO 3166-1 alpha-2 country code for Job Search / Job Details (e.g. `us`, `gb`, `ca`, `de`, `in`). Default `us`.

## `datePosted` (type: `string`):

Filter Job Search results by how recently the job was posted.

- `all` (default)
- `today`
- `3days`
- `week`
- `month`

Ignored for all other operations.

## `employmentTypes` (type: `string`):

Optional. Comma-separated employment types to filter Job Search.

Valid values: `FULLTIME`, `CONTRACTOR`, `PARTTIME`, `INTERN`. Example: `FULLTIME,CONTRACTOR`.

Ignored for all other operations.

## `workFromHome` (type: `boolean`):

Optional. For `Job Search` — return only remote / work-from-home jobs when enabled.

## `jobRequirements` (type: `string`):

Optional. Comma-separated experience/education filters for Job Search.

Valid values: `under_3_years_experience`, `more_than_3_years_experience`, `no_experience`, `no_degree`.

Ignored for all other operations.

## `radius` (type: `integer`):

Optional. Search/salary radius in kilometres from the location in the query. For Job Search and Estimated Salary.

## `excludeJobPublishers` (type: `string`):

Optional. Comma-separated publisher names to exclude from Job Search results (e.g. `BeeBe,Dice`).

## `locationType` (type: `string`):

Optional. For `Estimated Salary` / `Company Salary` — scope of the location.

- `ANY` (default)
- `CITY`
- `STATE`
- `COUNTRY`

## `yearsOfExperience` (type: `string`):

Optional. For `Estimated Salary` / `Company Salary` — experience bracket.

- `ALL` (default)
- `LESS_THAN_ONE`
- `ONE_TO_THREE`
- `FOUR_TO_SIX`
- `SEVEN_TO_NINE`
- `TEN_TO_FOURTEEN`
- `ABOVE_FIFTEEN`

## `language` (type: `string`):

Optional. ISO 639 language code for Job Search results (e.g. `en`, `es`, `de`).

## `maxPages` (type: `integer`):

📄 **Applies to `Job Search` only** (~10 jobs per page). Ignored for single-record operations.

💡 **TIP:** Start small (1–3 pages) to preview results before scaling up. Pagination stops automatically when Google for Jobs reports no more results.

⚠️ Hard cap: 20 pages (~200 jobs) to prevent runaway runs.

## Actor input object example

```json
{
  "operation": "jobSearch",
  "query": "software engineer in new york",
  "jobId": "22jWL_JNHtSxAieXAAAAAA==",
  "jobTitle": "software engineer",
  "location": "United States",
  "company": "Google",
  "country": "us",
  "datePosted": "all",
  "employmentTypes": "FULLTIME",
  "workFromHome": false,
  "jobRequirements": "",
  "excludeJobPublishers": "",
  "locationType": "ANY",
  "yearsOfExperience": "ALL",
  "language": "",
  "maxPages": 3
}
```

# Actor output Schema

## `output` (type: `string`):

Per-row results — one flat row per job or salary estimate with curated camelCase aliases (jobId, jobTitle, employerName, location, salaryString, requiredTechnologies, seniorityLevel, …) plus the raw upstream fields spread alongside.

## `report` (type: `string`):

HTML report with run status, success/error row counts, success rate, pages fetched, duration, and the inputs used — written even on fatal crash.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "query": "software engineer in new york",
    "jobId": "",
    "jobTitle": "software engineer",
    "location": "United States",
    "company": "Google",
    "country": "us",
    "employmentTypes": "",
    "jobRequirements": "",
    "excludeJobPublishers": "",
    "language": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("sian.agency/jsearch-jobs-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "query": "software engineer in new york",
    "jobId": "",
    "jobTitle": "software engineer",
    "location": "United States",
    "company": "Google",
    "country": "us",
    "employmentTypes": "",
    "jobRequirements": "",
    "excludeJobPublishers": "",
    "language": "",
}

# Run the Actor and wait for it to finish
run = client.actor("sian.agency/jsearch-jobs-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "query": "software engineer in new york",
  "jobId": "",
  "jobTitle": "software engineer",
  "location": "United States",
  "company": "Google",
  "country": "us",
  "employmentTypes": "",
  "jobRequirements": "",
  "excludeJobPublishers": "",
  "language": ""
}' |
apify call sian.agency/jsearch-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sian.agency/jsearch-jobs-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/rMnGL28A2g7cKwS4X/builds/dG4sVDbZcOP7WoOoC/openapi.json
