# Google Jobs Scraper — Salary, Apply Links & Filters (`cheapapi/google-jobs-scraper`) Actor

Scrape Google Jobs listings by keyword and location: job title, company, salary, employment type, posted date, apply links. Filters, remote, no login.

- **URL**: https://apify.com/cheapapi/google-jobs-scraper.md
- **Developed by:** [CheapAPI](https://apify.com/cheapapi) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event + usage

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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

## Google Jobs Scraper — Salary, Apply Links & Filters

Scrape job listings from Google Jobs by keyword and location and get clean, flat rows with job title, employer, location, salary (parsed into min/max/currency/period), employment type, posted date and the link to apply. No login, no browser, no setup.

**Why this Actor**

- **$2.10 per 1,000 jobs** on every plan, no start fee. Normal searches pay only for delivered jobs. A search that delivers fewer jobs than the 10-job result pages it fetched (Google has no jobs, or your filters / "only new jobs" removed them) pays **$0.0018 per uncovered page** instead. Apify platform usage is billed separately by Apify (at the default 256 MB a small run typically uses about $0.001–$0.005).
- **Up to 200 jobs per search term**, any number of search terms per run, in 230+ countries and thousands of cities.
- **Several locations in one run:** list cities, regions or countries and every search term runs in each of them; every row says which location it came from (`searchLocation`).
- **24 fields per job**, including a stable row `id`, salary parsed into numbers (`salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod`) and a remote flag.
- **Filters:** employment type, search radius (1–300 km), remote, posted within (24 h / 3 days / 7 days / 31 days), only jobs with salary.
- **Only new jobs (monitoring mode):** scheduled runs deliver only jobs you have not received before. Repeats are skipped and never charged as jobs; a search with nothing new costs $0.0018 per result page checked.
- **Live data:** every run searches Google Jobs at run time, nothing is served from a cache. Large runs switch to economy processing automatically at the same price.

### Compared with alternatives

Typical run: **1,000 Google Jobs listings**. "—" means the Store listing does not state it.

| Option | Price for 1,000 jobs | Billing | Full description | Parsed salary min/max | Countries |
|---|---|---|---|---|---|
| Most-used Google Jobs Actor (~3,800 users) | ≈ $3.50–$9.00 | $0.035 (Gold and above) to $0.09 (Free) per results page (estimate assumes ~10 jobs per page) | ✓ | — | — |
| Per-job Google Jobs Actor with start fee (~2,800 users) | $150–$200 | $0.15–$0.20 per job + $0.14–$0.20 per run start | — | — | — |
| Flat-price Google Jobs Actor (~1,300 users) | $3.00 | $0.003 per job | — | — | 9 listed |
| Google Jobs Actor with descriptions (~400 users) | $3.00 **+ platform usage** | $0.003 per job, you also pay compute | ✓ | ✓ | — |
| Pay-per-result Google Jobs API Actor (~450 users) | $10–$15 | $0.01 (Bronze and above) to $0.015 (Free) per job | — | — | — |
| Tiered Google Jobs Actor with optional details (~340 users) | $2.40–$6.00 + start fee | $0.006 (Free), $0.0039 (Gold), $0.003 (Platinum), $0.0024 (Diamond) per job + $0.018–$0.035 per run start | optional | — | — |
| **This Actor** | **$2.10 + platform usage** | $0.0021 per delivered job, no start fee; $0.0018 per result page that delivered no job; Apify platform usage billed separately | ✗ | ✓ | 230+ |

Prices from public Apify Store listings, checked September 2026. The table is not exhaustive: it lists the most-used Google Jobs Actors plus notable cheaper ones; Actors with fewer users are left out. For this Actor, Apify platform usage is billed separately by Apify (at the default 256 MB a small run typically uses about $0.001–$0.005) on top of the price shown. This Actor is the lowest price per 1,000 jobs in this comparison on every plan (the closest is the tiered Actor at $2.40 + start fee, on Apify's Diamond plan only), but three alternatives can return the **full job description** and we do not. If you need the description text, one of those is the better fit; if you need titles, employers, salaries and apply links at the lowest price, with "only new jobs" monitoring, this one is.

### Not included

- **Full job descriptions**, qualifications and benefits bullets. Google Jobs result lists do not contain them; use `applyUrl` to open the original posting.
- **Direct LinkedIn, Indeed or Glassdoor scraping.** Google Jobs aggregates listings from many boards (LinkedIn, Indeed, Glassdoor, ZipRecruiter, company career pages and more, shown in `applyVia`), but we only read what Google Jobs shows. Jobs that exist only on a board Google has not indexed are not returned, and board-specific fields (applicant counts, Easy Apply, recruiter names) are not included.
- **GPS coordinates and company logos** (not in Google Jobs result lists).
- **Regular Google web results** for a job query: use [Google SERP Scraper](https://apify.com/cheapapi/google-serp-scraper).
- **Employer details** such as address, phone, rating and reviews: use [Google Maps Scraper Plus](https://apify.com/cheapapi/google-maps-scraper-plus) with the employer name.

### What data you get

| Field | Type | Example |
|---|---|---|
| `id` | string | `870af54819d97b92` (stable: same job, same id in every run) |
| `searchTerm` | string | `devops` |
| `position` | number | `2` |
| `jobId` | string | `-V-GEAqDGeZ8J05xAAAAAA==` |
| `title` | string | `Cloud and DevOps Engineer (5–8 yrs)` |
| `employerName` | string | `Advanced Space` |
| `employerWebsite` | string / null | `null` (Google Jobs lists usually omit it; always present as a key, `null` when Google shows no website) |
| `location` | string | `Westminster, CO` |
| `isRemote` | boolean | `false` |
| `salary` | string / null | `116K–150K a year` |
| `salaryMin` | number / null | `116000` |
| `salaryMax` | number / null | `150000` |
| `salaryCurrency` | string / null | `USD` |
| `salaryPeriod` | string / null | `year` (`hour`, `day`, `week`, `month`, `year`) |
| `employmentType` | string / null | `Full-time` |
| `postedAt` | ISO date / null | `2026-09-24T22:28:53.000Z` |
| `postedAgo` | string / null | `1 day ago` |
| `applyUrl` | string | `https://www.clearancejobs.com/jobs/9190535/...` |
| `applyVia` | string | `Clearance Jobs` |
| `googleSearchUrl` | string | Google Jobs search page these results come from |
| `searchCountry` | string | `US` |
| `searchLocation` | string | `US` (the location this job was searched in: the country code when the whole country is searched, or the matched location name such as `Austin,Texas,United States` for a city; with several locations, tells you which one returned it) |
| `language` | string | `en` |
| `scrapedAt` | ISO date | `2026-09-25T22:29:10.412Z` |

The dataset has three views: **Jobs** (the overview), **Salaries** (parsed salary columns) and **All fields**. A `RUN_SUMMARY` record in the key-value store lists how many jobs were found, filtered, de-duplicated and delivered, plus the searched locations and any problems per search term and location (and, in monitoring mode, how many jobs were skipped as already seen).

### How to use

1. Open the Actor in Apify Console and click **Try for free**.
2. Enter one or more **Job search terms** (e.g. `software engineer`, `nurse`, `warehouse associate`).
3. Set the **Country** (e.g. `US`, `GB`, `DE`) and, optionally, a **City or region** (e.g. `Austin, Texas`). For several cities in one run, use **Several locations** in the advanced section.
4. Choose **Maximum jobs per search term** (default 20, up to 200).
5. Click **Start**. Download the results as JSON, CSV, Excel or HTML, or read them through the API.

Ready-to-paste input:

```json
{
    "searchTerms": ["software engineer", "data analyst"],
    "country": "US",
    "location": "Austin, Texas",
    "language": "en",
    "maxJobsPerSearch": 50,
    "employmentTypes": ["fullTime"],
    "postedWithin": "week"
}
```

Several cities in one run (2 terms × 3 locations = 6 searches, each row tagged with its `searchLocation`):

```json
{
    "searchTerms": ["registered nurse", "medical assistant"],
    "country": "US",
    "locations": ["Austin, Texas", "Denver, Colorado", "London, United Kingdom"],
    "maxJobsPerSearch": 50,
    "radiusKm": 40
}
```

**API — curl**

```bash
curl -X POST "https://api.apify.com/v2/acts/cheapapi~google-jobs-scraper/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"searchTerms":["software engineer"],"country":"US","maxJobsPerSearch":20}'
```

**API — JavaScript (`apify-client`)**

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

const client = new ApifyClient({ token: '<YOUR_TOKEN>' });
const run = await client.actor('cheapapi/google-jobs-scraper').call({
    searchTerms: ['software engineer'],
    country: 'US',
    location: 'New York',
    maxJobsPerSearch: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, items[0]);
```

**API — Python (`apify-client`)**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_TOKEN>")
run = client.actor("cheapapi/google-jobs-scraper").call(run_input={
    "searchTerms": ["software engineer"],
    "country": "GB",
    "location": "London",
    "maxJobsPerSearch": 50,
})
for job in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(job["title"], "|", job["employerName"], "|", job["salary"])
```

### Use cases

- **Job boards and aggregators:** fill your board with fresh listings for any role and city, with direct apply links.
- **Salary research:** collect advertised salary ranges per role and city from the parsed `salaryMin`/`salaryMax` columns.
- **Recruiting and sales leads:** find companies that are hiring for a role right now (hiring = budget).
- **Labor-market analytics:** track demand for skills, remote share and contract types over time with scheduled runs.
- **Job alerts:** schedule daily runs with **Only new jobs** and push each new job to Slack, email or a sheet exactly once.
- **Competitor monitoring:** watch which roles competitors are hiring for and where.

### Advanced options

| Option | Default | Meaning |
|---|---|---|
| Several locations (`locations`) | — | Cities, regions, countries or numeric location codes, one per line (up to 100). Every search term runs in every location; **City or region**, if set, is added to the list. Cities without a country are looked up in **Country**. |
| Employment type (`employmentTypes`) | all | `fullTime`, `partTime`, `contractor`, `internship`. Google Jobs filters full-time, contractor and internship; when `partTime` is selected, all selected types are matched by us against the job's employment type text instead (removed jobs are not charged as jobs; result pages left without a delivered job cost $0.0018 each). |
| Search radius (`radiusKm`) | anywhere | Only jobs within 1–300 km of the location (miles × 1.609). |
| Remote jobs (`remoteOnly`) | `false` | Adds "remote" to each search so Google focuses on remote positions. Every row also has `isRemote`. |
| Posted within (`postedWithin`) | `any` | `today` (24 h), `3days`, `week`, `month` (31 days). |
| Only jobs with salary (`onlyWithSalary`) | `false` | Keep only jobs that show a salary. |
| Remove duplicate jobs (`deduplicate`) | `true` | A job returned by several search terms or locations is delivered and charged once (a search left with only duplicates pays $0.0018 per result page). |
| Location code (`locationCode`) | — | Numeric Google location code (e.g. `2840` United States, `1023191` New York). Overrides country, city and several locations. |
| Exact location name (`locationName`) | — | Full name like `London,England,United Kingdom`. Overrides country, city and several locations. |
| Language name (`languageName`) | — | E.g. `German`. Overrides the language code. |
| Processing speed (`processingSpeed`) | `auto` | `auto` = fast for up to 25 search terms, economy above; `fast` (1–2 min); `economy` (up to ~45 min). Same price. |
| Maximum wait (`maxWaitMinutes`) | `60` | Stop waiting for unfinished searches after this many minutes. They were already processed, so each is charged as checked result pages ($0.0018 per requested page). |
| Only new jobs since the last run (`onlyNewJobs`) | `false` | Monitoring mode: skip jobs that earlier runs of the same search already delivered. Skipped repeats are not charged as jobs; a search with fewer new jobs than result pages fetched pays $0.0018 per uncovered page. |
| Monitoring store name (`monitoringStoreName`) | `google-jobs-monitor` | Named key-value store in your Apify account that keeps the job history. Use different names for separate alerts. |

#### Only new jobs (monitoring mode)

Turn on **Only new jobs since the last run** and schedule the Actor (e.g. every morning). For every search, the Actor keeps the ids of the jobs it has delivered in a named key-value store in **your** Apify account (`google-jobs-monitor` by default, up to 5,000 ids per search):

1. The first run delivers all matching jobs and starts the history.
2. Later runs deliver only jobs that are not in the history. Repeats are counted as `jobsAlreadySeen` in `RUN_SUMMARY` and are **not charged as jobs**. Each delivered new job covers one fetched result page; pages left uncovered cost $0.0018 (a search of 20 jobs with nothing new: 2 pages, $0.0036).
3. A "search" is the combination of search term, location (each entry of **Several locations** has its own history), language, employment types, radius and remote setting. Change any of these and it gets its own history.
4. Jobs cut off by your spending limit are not remembered, so they still arrive as new next time.
5. To start over, delete the store in **Storage → Key-value stores**, or pick a new **Monitoring store name**.

```json
{
    "searchTerms": ["registered nurse", "nurse practitioner"],
    "country": "US",
    "location": "Chicago, Illinois",
    "onlyNewJobs": true,
    "monitoringStoreName": "chicago-nurse-alerts"
}
```

### Output example

Example output (one row from a whole-country US search for `devops`):

```json
{
    "id": "870af54819d97b92",
    "searchTerm": "devops",
    "position": 2,
    "jobId": "-V-GEAqDGeZ8J05xAAAAAA==",
    "title": "Cloud and DevOps Engineer (5–8 yrs)",
    "employerName": "Advanced Space",
    "employerWebsite": null,
    "location": "Westminster, CO",
    "isRemote": false,
    "salary": "116K–150K a year",
    "salaryMin": 116000,
    "salaryMax": 150000,
    "salaryCurrency": "USD",
    "salaryPeriod": "year",
    "employmentType": "Full-time",
    "postedAt": "2026-09-24T22:28:53.000Z",
    "postedAgo": "1 day ago",
    "applyUrl": "https://www.clearancejobs.com/jobs/9190535/cloud-and-devops-engineer-5-8-yrs",
    "applyVia": "Clearance Jobs",
    "googleSearchUrl": "https://www.google.com/search?q=devops&udm=8&hl=en&gl=US&gws_rd=cr&ie=UTF-8&oe=UTF-8",
    "searchCountry": "US",
    "searchLocation": "US",
    "language": "en",
    "scrapedAt": "2026-09-25T22:29:10.412Z"
}
```

### Pricing

**Typical cost: $0.0021 per job ($2.10 per 1,000 jobs), on every plan, no start fee.** Apify platform usage is billed separately by Apify.

**Apify Free plan:** Apify does not pay developers for usage on its Free plan, so on the Free plan this Actor can be used for up to **$0.25 of results per calendar month** — enough to try it on a small input. When the allowance is used up, the run ends with a clear message (not an error). Any paid Apify plan removes the limit; prices are the same.

Pay per event, same price on every plan (Free, Bronze, Silver, Gold, Platinum and Diamond). No start fee, no subscription.

| Event | Price | When it is charged |
|---|---|---|
| Job listing (`job`) | **$0.0021** ($2.10 per 1,000) | Each job delivered to your dataset. |
| Result page checked (`page-checked`) | **$0.0018** | Only for a search that delivers fewer jobs than the 10-job result pages it fetched: each fetched page not covered by a delivered job. Also charged per requested page for a search that got no answer or did not finish within **Maximum wait** (it may already have been processed), and once for a search the data source answered with "no data". |

Each delivered job covers one fetched result page, so a normal search never pays `page-checked`. Google fetches jobs in pages of 10: asking for 20 jobs fetches up to 2 pages, asking for 200 up to 20. When Google returns fewer jobs, only the pages that came back count (1 page for 0–9 jobs, 2 for 10–19, …). Those pages are fetched and paid for with our data provider whether or not a job survives your filters, which is why the fee exists.

Apify platform usage is billed separately by Apify (at the default 256 MB a small run typically uses about $0.001–$0.005); the prices and examples here are event fees only.

Worked examples:

- **1,000 jobs** (e.g. 50 search terms × 20 jobs) cost **$2.10**.
- **A daily alert** with 10 search terms × 20 jobs and **Only new jobs** on: say 6 searches deliver 5–20 new jobs (70 jobs, $0.147) and 4 have nothing new (4 × 2 pages × $0.0018 = $0.0144): **$0.16 per day**, about **$4.84 per month**.
- **A search for a rare job title** that Google has no jobs for: 1 page × $0.0018 = **$0.0018**.
- **10,000 jobs** (e.g. 50 cities × 200 jobs) cost **$21.00**.

Sample `RUN_SUMMARY` (key-value store) for 2 search terms × 20 jobs in Austin, posted within a week — 35 jobs delivered, 0 result pages charged, event cost 35 × $0.0021 = **$0.0735**:

```json
{
    "searchTerms": 2,
    "searches": 2,
    "searchesCompleted": 2,
    "searchesWithoutJobs": 0,
    "searchesFailed": 0,
    "searchesSkippedByLimit": 0,
    "resultPagesChecked": 0,
    "jobsFound": 40,
    "jobsFilteredOut": 3,
    "duplicatesRemoved": 2,
    "onlyNewJobs": false,
    "jobsAlreadySeen": 0,
    "jobsDelivered": 35,
    "location": "Austin,Texas,United States",
    "processingSpeed": "fast",
    "stoppedAtSpendingLimit": false,
    "problems": [],
    "locations": ["Austin,Texas,United States"],
    "country": "US",
    "finishedAt": "2026-09-25T22:30:02.118Z"
}
```

Set **Maximum cost per run** in the run options: the Actor only starts searches your limit can pay for (at least their result-page fee) and stops delivering exactly at the limit.

### Integrations

- **Make, Zapier, n8n:** use the Apify app to start runs and get dataset items.
- **Google Sheets:** export the dataset directly or with the Apify Google Sheets integration.
- **Webhooks:** get notified when a run finishes and pull the jobs into your system.
- **Scheduling:** run daily or hourly with Apify Schedules; combine with **Only new jobs** for alerts without repeats.
- **API and MCP:** start runs and read datasets through the Apify REST API, the `apify-client` libraries (JavaScript, Python) or the Apify MCP server, so AI agents and assistants (e.g. Claude, ChatGPT, Cursor) can call this Actor as a tool.

### FAQ

**Is there a limit on the Apify Free plan?** Yes: up to $0.25 of this Actor's results per calendar month, enough to try it. Apify pays developers nothing for Free-plan usage while our data costs are real, so this keeps the Actor sustainable. Runs that reach the allowance stop cleanly and keep everything collected so far; the allowance resets on the 1st of the month. Any paid Apify plan has no limit.

**Is it legal to scrape Google Jobs?**
The Actor collects publicly visible job listings only, without logging in. Job listings are business information; make sure your use complies with the applicable laws (such as GDPR) and the terms of the job sites you link to. If in doubt, consult a lawyer.

**How fresh is the data?**
Every run searches Google Jobs live at run time; nothing is served from an old cache. Each row has `scrapedAt` (when it was collected) and `postedAt`. `postedAt` is derived from Google's "posted X days ago" label, so it is accurate to the hour/day Google shows.

**Why did I get fewer results than "Maximum jobs per search term"?**
Google Jobs often shows fewer jobs than requested for narrow terms or small locations. Filters (posted within, only with salary, part-time), duplicate removal and **Only new jobs** also reduce the count. You are charged per delivered job; only when a search delivers fewer jobs than the result pages it fetched is each uncovered page charged $0.0018. `RUN_SUMMARY` shows found, filtered, duplicate, already-seen, delivered and `resultPagesChecked` counts.

**Why was I charged "Result page checked" ($0.0018)?**
Google Jobs is read in pages of 10 jobs, and every fetched page costs us money even when no job on it reaches your dataset. You see this fee only when a search delivered fewer jobs than pages fetched: Google had no jobs for it, your filters (posted within, only with salary, part-time) or **Only new jobs** removed them, all were duplicates of another search, or the search got no answer / did not finish within **Maximum wait**. Example: 20 jobs asked, 20 returned, all already delivered yesterday → 2 pages × $0.0018 = $0.0036. `RUN_SUMMARY` → `problems` names each search and how many pages were charged. Tip: a lower **Maximum jobs per search term** in monitoring runs keeps this fee small.

**Do you include the full job description?**
No. Google Jobs result lists do not include the full description, qualifications, benefits, GPS coordinates or logos. Use `applyUrl` to open the original posting.

**How do I control my budget?**
Set **Maximum cost per run** in the run options. The Actor only starts the searches your limit can pay for and stops delivering exactly at the limit. At $2.10 per 1,000 jobs, a $1 limit gets about 476 jobs (a little less when some searches pay result-page fees). Apify platform usage (compute) is not included in the limit's event fees and is billed separately by Apify: at the default 256 MB a small run typically uses about $0.001–$0.005; long economy runs that wait for results use more.

**How do I get only new jobs every day?**
Turn on **Only new jobs since the last run** and create an Apify Schedule (Console → Schedules). Each run delivers and charges only jobs that earlier runs of the same search have not delivered (plus $0.0018 per result page for searches with fewer new jobs than pages fetched). See "Only new jobs (monitoring mode)" above.

**Which export formats are supported?**
JSON, CSV, Excel, XML, HTML table and RSS from the dataset page or the API, plus direct export to Google Sheets and other tools via integrations.

**Can I search a specific city, or several cities and countries in one run?**
Yes. For one city, put it in **City or region** (e.g. `Austin, Texas` or `London, United Kingdom`); for exact control use **Exact location name** or **Location code** in the advanced section. For several, list them in **Several locations** (e.g. `Austin, Texas`, `Denver, Colorado`, `Germany`). Each search term runs in each location, so 5 terms × 10 cities = 50 searches, and every row has `searchLocation` and `searchCountry`. You pay per delivered job as usual; with **Remove duplicate jobs** on, a job found in two nearby cities is delivered and charged once.

**Why is the salary currency sometimes guessed?**
Google often shows salaries without a currency sign (e.g. "116K–150K a year"). In that case `salaryCurrency` is the local currency of the searched country. The original text is always in `salary`.

**Something is not working. How do I get support?**
Open an issue in the Actor's **Issues** tab with your run ID. We read every issue and reply there. Feature requests are welcome too.

### Limitations

- Up to 200 jobs per search (term × location) (Google Jobs limit). Split large searches by city or role to get more.
- With several locations, language, radius, employment type and the other filters are shared by all locations; run the Actor separately if a city needs different filters. Up to 100 locations per run.
- When the spending limit cannot pay for every search, searches are started in input order (all terms for the first location, then the next location), so the last locations are the ones skipped.
- A location name with a country hint (e.g. `London, United Kingdom`) is matched best; a bare city name is matched within **Country**, and an ambiguous name that is also a country falls back to that country if no city matches.
- No full job description, qualifications, benefits or GPS coordinates (not part of Google Jobs result lists).
- One apply link per job (the source Google shows first).
- "Posted within" and "Only jobs with salary" are applied after collection, so heavily filtered runs return fewer rows than requested.
- Salary parsing is best-effort; unusual formats keep the text in `salary` and leave the numeric fields empty.
- Company logos are not included.
- "Only new jobs" remembers up to 5,000 job ids per search; very old ids are forgotten first.

### Privacy and personal data

The Actor collects job listings, which are business information (job titles, company names, locations, salaries, links). It does not collect applicant data, recruiter profiles, emails or phone numbers. Your job history for **Only new jobs** is stored only in a key-value store in your own Apify account. If a listing contains personal data, you are responsible for processing it lawfully (e.g. under GDPR/CCPA).

# Actor input Schema

## `searchTerms` (type: `array`):

Job titles or keywords to search on Google Jobs, one per line (e.g. "software engineer", "nurse", "barista"). Each term is one search.

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

Country to search jobs in. Pick one from the list, or type any other two-letter country code (e.g. "KR", "AR") or country name (e.g. "Portugal"); 230+ countries are supported.

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

Narrow the search to a city or region in the selected country, e.g. "New York", "Austin, Texas" or "London, United Kingdom". Leave empty to search the whole country. To search several cities in one run, use "Several locations" in the advanced section.

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

Language of the Google Jobs interface, as a two-letter code: "en" (English), "de" (German), "fr" (French), "es" (Spanish), "pt-BR" (Portuguese, Brazil) and so on. Pick one from the list or type another code. It affects the language of labels such as salary and "posted" texts; use the local language (e.g. "de" for Germany) to get the most local listings.

## `maxJobsPerSearch` (type: `integer`):

How many jobs to collect for each search term (Google Jobs shows up to 200, in pages of 10). You pay $0.0021 per delivered job; each delivered job covers one fetched page, and pages left uncovered (no jobs, or all removed by filters / only new jobs) cost $0.0018 each.

## `locations` (type: `array`):

Cities, regions or countries, one per line, e.g. "Austin, Texas", "London, United Kingdom", "Germany" or a numeric location code. Cities without a country are looked up in the selected "Country". Every search term is searched in every location (up to 100 locations); "City or region" above, if set, is added to this list. Filters, language and radius below apply to every location. Leave empty to use a single location.

## `employmentTypes` (type: `array`):

Only return jobs with these contract types. Google Jobs filters full-time, contractor and internship; with part-time selected, the selected types are matched against each job's employment type after collection (removed jobs are not charged as jobs). A search that delivers fewer jobs than the 10-job result pages it fetched pays $0.0018 per uncovered page ("Result page checked"). Leave empty for all types.

## `radiusKm` (type: `integer`):

Only jobs within this distance of the location (1–300 km; for miles multiply by 1.609), e.g. 50. Works best with a city. Leave empty to search anywhere in the location.

## `remoteOnly` (type: `boolean`):

Adds "remote" to every search so Google Jobs focuses on remote and work-from-home positions. Every row also has an "isRemote" flag.

## `postedWithin` (type: `string`):

Keep only jobs posted within this period (based on the posting date Google shows). Removed jobs are not charged as jobs. A search that delivers fewer jobs than the 10-job result pages it fetched pays $0.0018 per uncovered page ("Result page checked").

## `onlyWithSalary` (type: `boolean`):

Keep only jobs where Google shows a salary. Removed jobs are not charged as jobs. A search that delivers fewer jobs than the 10-job result pages it fetched pays $0.0018 per uncovered page ("Result page checked").

## `deduplicate` (type: `boolean`):

When several search terms or locations return the same job, keep it only once (you are charged once). A search that delivers fewer jobs than the 10-job result pages it fetched pays $0.0018 per uncovered page ("Result page checked").

## `onlyNewJobs` (type: `boolean`):

Deliver only jobs that earlier runs of the same search (same term, location, language and Google filters) have not delivered yet. The first run delivers everything and starts the history. Repeats are skipped and not charged as jobs; a search with fewer new jobs than result pages fetched pays $0.0018 per uncovered page (e.g. 20 jobs asked, nothing new: $0.0036). Ideal with an Apify Schedule.

## `monitoringStoreName` (type: `string`):

Name of the key-value store in your Apify account that keeps the job history (lowercase letters, digits and hyphens). Use a different name to keep separate histories, e.g. one per client or alert. Delete the store to start over.

## `locationCode` (type: `integer`):

Numeric Google location code (e.g. 2840 = United States, 1023191 = New York, NY). Overrides country and city. Also overrides "Several locations".

## `locationName` (type: `string`):

Full Google location name in the form "City,Region,Country", e.g. "London,England,United Kingdom" or "Austin,Texas,United States". Overrides country and city. Also overrides "Several locations".

## `languageName` (type: `string`):

Full language name (e.g. "English", "German") instead of the two-letter code. Overrides "Language".

## `processingSpeed` (type: `string`):

Auto: fast processing for up to 25 search terms, economy for larger runs. Fast: results usually within 1–2 minutes. Economy: can take up to ~45 minutes. The price per job is the same.

## `maxWaitMinutes` (type: `integer`):

Stop waiting for searches that are not ready after this many minutes. Unfinished searches are reported in the run summary; they were already processed, so each is charged $0.0018 per requested result page.

## Actor input object example

```json
{
  "searchTerms": [
    "software engineer",
    "data analyst"
  ],
  "country": "US",
  "location": "New York",
  "language": "en",
  "maxJobsPerSearch": 20,
  "locations": [
    "Austin, Texas",
    "Denver, Colorado",
    "London, United Kingdom"
  ],
  "employmentTypes": [],
  "radiusKm": 50,
  "remoteOnly": false,
  "postedWithin": "any",
  "onlyWithSalary": false,
  "deduplicate": true,
  "onlyNewJobs": false,
  "monitoringStoreName": "google-jobs-monitor",
  "processingSpeed": "auto",
  "maxWaitMinutes": 60
}
```

# Actor output Schema

## `jobs` (type: `string`):

No description

## `salaries` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

# 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 = {
    "searchTerms": [
        "software engineer"
    ],
    "country": "US",
    "language": "en",
    "maxJobsPerSearch": 20,
    "postedWithin": "any",
    "monitoringStoreName": "google-jobs-monitor"
};

// Run the Actor and wait for it to finish
const run = await client.actor("cheapapi/google-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 = {
    "searchTerms": ["software engineer"],
    "country": "US",
    "language": "en",
    "maxJobsPerSearch": 20,
    "postedWithin": "any",
    "monitoringStoreName": "google-jobs-monitor",
}

# Run the Actor and wait for it to finish
run = client.actor("cheapapi/google-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 '{
  "searchTerms": [
    "software engineer"
  ],
  "country": "US",
  "language": "en",
  "maxJobsPerSearch": 20,
  "postedWithin": "any",
  "monitoringStoreName": "google-jobs-monitor"
}' |
apify call cheapapi/google-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cheapapi/google-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/KKdzyROjfFYtCM337/builds/bqW6V9yS9vuDE5W2e/openapi.json
