# 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:** 4 total users, 2 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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# 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

[![Telegram Support](https://img.shields.io/badge/Telegram-Support%20Group-0088cc?logo=telegram)](https://t.me/+vyh1sRE08sAxMGRi)

**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)**

# 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,
  "locationType": "ANY",
  "yearsOfExperience": "ALL",
  "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("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=sian.agency/jsearch-jobs-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Jobs Search API — Indeed, LinkedIn & Glassdoor Aggregator",
        "description": "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.",
        "version": "1.0",
        "x-build-id": "NM4vowFR7xC4vLu5x"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/sian.agency~jsearch-jobs-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-sian.agency-jsearch-jobs-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/sian.agency~jsearch-jobs-scraper/runs": {
            "post": {
                "operationId": "runs-sync-sian.agency-jsearch-jobs-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/sian.agency~jsearch-jobs-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-sian.agency-jsearch-jobs-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "operation"
                ],
                "properties": {
                    "operation": {
                        "title": "🎯 Operation — what do you want to scrape?",
                        "enum": [
                            "jobSearch",
                            "jobDetails",
                            "estimatedSalary",
                            "companySalary"
                        ],
                        "type": "string",
                        "description": "🎯 **PICK ONE OPERATION PER RUN.** Each run produces one clean dataset matching the chosen mode.\n\n- **🔍 Job Search** — search every job board at once via Google for Jobs, paginated (~10 jobs/page)\n- **📄 Job Details** — deep details for one job (required skills, seniority, experience, visa, salary) — by Job ID\n- **💵 Estimated Salary** — estimated pay for a title + location, by hourly/monthly/yearly period\n- **🏢 Company Salary** — estimated pay for a title inside a specific company\n\n💡 **TIP:** Run Job Search first to discover Job IDs, then drill into Job Details per posting.",
                        "default": "jobSearch"
                    },
                    "query": {
                        "title": "🔍 Search Query (for Job Search)",
                        "type": "string",
                        "description": "🔍 **Required for `Job Search` operation.**\n\nA free-form job search query — exactly what you would type into Google for Jobs.\n- `software engineer in new york`\n- `remote marketing manager`\n- `registered nurse chicago`\n\n💡 **TIP:** Include the location in the query for best results, or use the `Work from home` toggle for remote-only.\n\n⚠️ **Ignored** for all other operations."
                    },
                    "jobId": {
                        "title": "📄 Job ID (for Job Details)",
                        "type": "string",
                        "description": "📄 **Required for `Job Details` operation.**\n\nThe Job ID from a Job Search result row (the `jobId` field, e.g. `22jWL_JNHtSxAieXAAAAAA==`).\n\n💡 **TIP:** Run `Job Search` first, collect the `jobId` values, then loop through Job Details to enrich each posting with required skills, seniority, and experience.\n\n⚠️ **Ignored** for all other operations."
                    },
                    "jobTitle": {
                        "title": "💼 Job Title (for Salary operations)",
                        "type": "string",
                        "description": "💼 **Required for `Estimated Salary` and `Company Salary`.**\n\nThe job title to estimate pay for.\n- `nurse`\n- `software engineer`\n- `data analyst`\n\n💡 **TIP:** Common, broad titles return the most reliable salary data. Very niche titles may return no estimate.\n\n⚠️ **Ignored** for Job Search and Job Details."
                    },
                    "location": {
                        "title": "📍 Location (for Estimated Salary)",
                        "type": "string",
                        "description": "📍 **Required for `Estimated Salary`** (optional for `Company Salary`).\n\nThe location to estimate pay for.\n- `United States`\n- `New York, NY`\n- `San Francisco, CA`\n\n💡 **TIP:** Broad locations (`United States`, a state, or a metro) return the most reliable estimates. A very specific address may return no data.\n\n⚠️ **Ignored** for Job Search and Job Details."
                    },
                    "company": {
                        "title": "🏢 Company (for Company Salary)",
                        "type": "string",
                        "description": "🏢 **Required for `Company Salary` operation.**\n\nThe company name to estimate in-company pay for.\n- `Google`\n- `Amazon`\n- `Microsoft`\n\n⚠️ **Ignored** for all other operations."
                    },
                    "country": {
                        "title": "🌍 Country",
                        "type": "string",
                        "description": "🌍 ISO 3166-1 alpha-2 country code for Job Search / Job Details (e.g. `us`, `gb`, `ca`, `de`, `in`). Default `us`."
                    },
                    "datePosted": {
                        "title": "📅 Date Posted (for Job Search)",
                        "enum": [
                            "all",
                            "today",
                            "3days",
                            "week",
                            "month"
                        ],
                        "type": "string",
                        "description": "Filter Job Search results by how recently the job was posted.\n\n- `all` (default)\n- `today`\n- `3days`\n- `week`\n- `month`\n\nIgnored for all other operations.",
                        "default": "all"
                    },
                    "employmentTypes": {
                        "title": "🧑‍💼 Employment Types (for Job Search)",
                        "type": "string",
                        "description": "Optional. Comma-separated employment types to filter Job Search.\n\nValid values: `FULLTIME`, `CONTRACTOR`, `PARTTIME`, `INTERN`. Example: `FULLTIME,CONTRACTOR`.\n\nIgnored for all other operations."
                    },
                    "workFromHome": {
                        "title": "🏠 Work From Home / Remote only",
                        "type": "boolean",
                        "description": "Optional. For `Job Search` — return only remote / work-from-home jobs when enabled.",
                        "default": false
                    },
                    "jobRequirements": {
                        "title": "🎓 Job Requirements (for Job Search)",
                        "type": "string",
                        "description": "Optional. Comma-separated experience/education filters for Job Search.\n\nValid values: `under_3_years_experience`, `more_than_3_years_experience`, `no_experience`, `no_degree`.\n\nIgnored for all other operations."
                    },
                    "radius": {
                        "title": "📏 Radius (km)",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Optional. Search/salary radius in kilometres from the location in the query. For Job Search and Estimated Salary."
                    },
                    "excludeJobPublishers": {
                        "title": "🚫 Exclude Publishers (for Job Search)",
                        "type": "string",
                        "description": "Optional. Comma-separated publisher names to exclude from Job Search results (e.g. `BeeBe,Dice`)."
                    },
                    "locationType": {
                        "title": "🗺️ Salary Location Type",
                        "enum": [
                            "ANY",
                            "CITY",
                            "STATE",
                            "COUNTRY"
                        ],
                        "type": "string",
                        "description": "Optional. For `Estimated Salary` / `Company Salary` — scope of the location.\n\n- `ANY` (default)\n- `CITY`\n- `STATE`\n- `COUNTRY`",
                        "default": "ANY"
                    },
                    "yearsOfExperience": {
                        "title": "🧮 Years of Experience (Salary)",
                        "enum": [
                            "ALL",
                            "LESS_THAN_ONE",
                            "ONE_TO_THREE",
                            "FOUR_TO_SIX",
                            "SEVEN_TO_NINE",
                            "TEN_TO_FOURTEEN",
                            "ABOVE_FIFTEEN"
                        ],
                        "type": "string",
                        "description": "Optional. For `Estimated Salary` / `Company Salary` — experience bracket.\n\n- `ALL` (default)\n- `LESS_THAN_ONE`\n- `ONE_TO_THREE`\n- `FOUR_TO_SIX`\n- `SEVEN_TO_NINE`\n- `TEN_TO_FOURTEEN`\n- `ABOVE_FIFTEEN`",
                        "default": "ALL"
                    },
                    "language": {
                        "title": "🗣️ Language (for Job Search)",
                        "type": "string",
                        "description": "Optional. ISO 639 language code for Job Search results (e.g. `en`, `es`, `de`)."
                    },
                    "maxPages": {
                        "title": "📄 Max pages to fetch",
                        "minimum": 1,
                        "maximum": 20,
                        "type": "integer",
                        "description": "📄 **Applies to `Job Search` only** (~10 jobs per page). Ignored for single-record operations.\n\n💡 **TIP:** Start small (1–3 pages) to preview results before scaling up. Pagination stops automatically when Google for Jobs reports no more results.\n\n⚠️ Hard cap: 20 pages (~200 jobs) to prevent runaway runs.",
                        "default": 3
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
