# Google Jobs Scraper: New Job Alerts, Salaries & Apply Links (`scrapebench/google-jobs-scraper`) Actor

Google Jobs listings for many roles in many US cities in one run — salary, highlights, full description and direct apply links — with a new-jobs-only mode for daily alerts.

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

## Pricing

$0.0025 / job listing

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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: New Job Alerts, Salaries & Apply Links

### Pain points

- Google Jobs shows ten listings per search and loads the rest only in a browser, so one search for 'nurse jobs in Chicago' is a thin slice of what is there.
- Covering five roles in ten cities by hand is fifty searches, each with its own overlap to remove.
- A daily job feed built on posting dates re-sends listings Google re-dates and misses ones it shows undated; what you want is 'jobs I have not seen'.
- The apply buttons are Google redirect links, not the posting itself.

### What we solve

- Many roles × many US cities in one run, de-duplicated on Google's own job ID.
- Depth per role and city: nearby cities and job-type variants are searched automatically until your cap is met — on 2026-10-31 one run returned 173 software-engineer jobs around Austin and 354 registered-nurse jobs around Chicago.
- 'Only jobs not sent before' remembers what each monitor delivered and returns only new listings — run twice in a row on 2026-10-31, the second run returned 100 different jobs with none repeated.
- Every apply option comes with the real posting URL Google holds for it, tracking parameters removed: 4,583 of 4,617 options across 1,113 jobs on 2026-10-31.
- Salary as Google shows it plus parsed min / max / period; 'Posted within' and 'Remote only' filters applied before anything is billed.
- A search Google answers with nothing, or a run that hits a wall, returns a free marker row saying which — never a silent zero.

### Summary

Give it the roles you hire or sell for — 'registered nurse', 'python developer' — and the US cities you care about, and it returns the job listings Google Jobs shows for every combination in one dataset. Google shows 10 jobs per search, so for each role and city the Actor also searches the largest nearby cities and the entry-level, remote, contract, internship, part-time and senior variants, until it has the number of jobs you asked for; a job found by two searches is returned once, keyed on Google's own job ID. Each row carries the title, employer, location, the salary Google shows as text and as numbers, schedule, work-from-home and no-degree flags, Google's qualifications / responsibilities / benefits highlights, the full description, and every apply option with its real posting URL — LinkedIn, Indeed, the employer's careers site — with tracking parameters removed. Turn on 'Only jobs not sent before' and schedule it: each run returns, and bills, only listings it has not delivered to you before.

### Who it's for

- Recruiters and staffing agencies watching new openings for the roles they place
- Sales teams that sell to employers who are hiring (staffing, HR software, relocation, benefits)
- Job boards and newsletters that publish curated local or niche listings
- Labour-market and salary researchers comparing roles and cities

### How to use

Set the input, run the actor, and collect results from the run's dataset (export to JSON/CSV/Excel, or pull via the Apify API). Example input:

```json
{
  "queries": [
    "software engineer",
    "registered nurse"
  ],
  "locations": [
    "Austin, TX"
  ],
  "maxJobsPerSearch": 50,
  "onlyNewJobs": true,
  "monitorName": "austin-tech-and-nursing"
}
```

See **Inputs** below for every available field.

### What you get

One row per record:

| Field | Description |
|---|---|
| `job_id` | Google's own ID for the listing — stable, so it de-duplicates across runs |
| `title / company / location` | As Google Jobs shows them; other_locations_count says how many more places the same job is posted in |
| `via` | The site Google found the listing on, e.g. LinkedIn or the employer's careers site |
| `salary_text` | Google's pay wording, verbatim, e.g. '164K–205K a year' |
| `salary_min / salary_max / salary_period` | The same range as numbers, and year, hour, month, week or day. salary_currency only when Google prints a symbol |
| `schedule_types` | Full-time, Part-time, Contractor, Internship… |
| `work_from_home / no_degree_mentioned` | True when Google tags the listing that way |
| `benefit_tags` | Benefit tags Google shows, e.g. Health insurance, Paid time off |
| `qualifications / responsibilities / benefits` | Google's 'Job highlights' lists |
| `description` | The full posting text (switch off for a lighter dataset) |
| `apply_options` | Every place to apply: source name, real posting URL, and whether it is a job board |
| `apply_url` | The first apply option's URL |
| `employer_apply_url` | An apply URL on the employer's own site or applicant-tracking system, only when one is listed and clearly theirs |
| `search_query / search_location / matched_search` | Which of your roles and places found the job, and the exact search (with any nearby city or job-type word) |
| `source_url` | The Google Jobs search page the listing was read from |

Sample:

```json
{
  "job_id": "ZrBruAaEW4Eb97eJAAAAAA==",
  "title": "Sr Software Engineer",
  "company": "Charles Schwab",
  "location": "Austin, TX",
  "other_locations_count": 2,
  "via": "Schwab Jobs",
  "salary_text": "164K\u2013205K a year",
  "salary_min": 164000,
  "salary_max": 205000,
  "salary_period": "year",
  "salary_currency": null,
  "schedule_types": [
    "Full-time"
  ],
  "work_from_home": false,
  "no_degree_mentioned": true,
  "benefit_tags": [
    "Dental insurance",
    "Health insurance",
    "Paid time off"
  ],
  "qualifications": [
    "8+ years of software engineering experience"
  ],
  "responsibilities": [
    "Design, develop, and maintain software solutions using modern engineering practices"
  ],
  "benefits": [
    "In addition to the salary range, this role is also eligible for bonus or incentive opportunities"
  ],
  "description": "Your opportunity\nAt Schwab, you\u2019re empowered to make an impact on your career\u2026",
  "apply_url": "https://www.schwabjobs.com/job/austin/sr-software-engineer/33727/101909398560",
  "employer_apply_url": "https://www.schwabjobs.com/job/austin/sr-software-engineer/33727/101909398560",
  "apply_options": [
    {
      "source": "Schwab Jobs",
      "url": "https://www.schwabjobs.com/job/austin/sr-software-engineer/33727/101909398560",
      "is_job_board": false
    },
    {
      "source": "CareerBuilder",
      "url": "https://www.careerbuilder.com/job-details/sr-software-engineer-blockchain-ann-arbor-mi--34192420-ab6d-446d-b589-b215d70fe39c",
      "is_job_board": true
    }
  ],
  "search_query": "software engineer",
  "search_location": "Austin, TX",
  "matched_search": "software engineer jobs in Austin, TX",
  "source_url": "https://www.google.com/search?q=software%20engineer%20jobs%20in%20Austin%2C%20TX&udm=8&hl=en&gl=us"
}
```

### Inputs

| Field | Required | Type | Default | Description |
|---|---|---|---|---|
| `query` | no | string | — | A role or keywords, e.g. 'registered nurse' or 'python developer'. Kept forever alongside 'Jobs to search for' — saved tasks and API callers send it. |
| `queries` | no | array | `["registered nurse"]` | One or many roles in ONE run, e.g. 'registered nurse', 'medical assistant'. Every role is searched in every location below, and a job found by two searches is returned once. |
| `location` | no | string | — | A US city as 'City, ST', e.g. 'Chicago, IL'. Kept forever alongside 'Locations'. |
| `locations` | no | array | `["Chicago, IL"]` | One or many US cities as 'City, ST' (e.g. 'Chicago, IL', 'Austin, TX'). Leave empty to search without a place. A city is what lets the Actor add nearby cities; a state or 'Remote' is searched as written, without them. |
| `maxJobsPerSearch` | no | integer | `30` | Cap PER role-and-location pair, not per run. Google shows 10 jobs per search, so the Actor runs more searches (nearby cities, then job types) until it has this many new jobs or runs out of searches. 10 costs one search. |
| `postedWithin` | no | string | `"any"` | Keep only jobs Google shows as posted within this window. Applied before billing. Jobs Google shows no age for are kept, so nothing disappears unexplained. The age itself is never included in the output. |
| `onlyNewJobs` | no | boolean | `false` | Remember every job this monitor has delivered and return (and bill) only jobs it has not sent before. Schedule the Actor daily with this on for a new-jobs feed. The memory is kept in your own Apify account (key-value store 'google-jobs-seen'). |
| `monitorName` | no | string | — | Optional name for the 'only new jobs' memory, e.g. 'nurses-chicago'. Leave empty and the memory is tied to the exact roles and locations you search. Use the same name to share one memory across differently configured runs. |
| `remoteOnly` | no | boolean | `false` | Keep only jobs Google marks 'Work from home'. Applied before billing. |
| `expandNearbyCities` | no | boolean | `true` | Also search the largest cities around each US location (Round Rock and Georgetown around Austin). Each nearby city added 8–10 new jobs per search when tested. |
| `nearbyCities` | no | integer | `8` | How many nearby cities to add at most. They are only searched while the cap above is not yet reached. |
| `nearbyRadiusMiles` | no | integer | `25` | How far from each location a nearby city may be. |
| `expandJobTypes` | no | boolean | `true` | Also search entry level, remote, contract, internship, part time and senior variants of each role. Each added 4–10 new jobs per search when tested. |
| `includeDescription` | no | boolean | `true` | The full posting text (median ~4,000 characters). Turn off for a lighter dataset; highlights stay either way. |

### Pricing (Pay Per Event)

You pay per result (`job-listing`) — **no charge for empty runs**. Example: **1000 job listings** at *$0.0025/result* ≈ **$2.50**.

You pay per job returned, never per search — the extra nearby-city and job-type searches that find those jobs are included, as are compute and proxy.

### Use cases

- Daily new-openings alert — schedule 'registered nurse' and 'travel nurse' in five metros with 'Only jobs not sent before' on, and pipe each run's rows into Slack or a sheet.
- Hiring-signal prospecting — list who is hiring software engineers in Austin this week and reach them through the employer's own careers link.
- Niche job board feed — pull 'remote' plus your niche's roles every morning and publish only what is new.
- Salary snapshot — collect the pay ranges Google shows for one role across ten cities and compare them.
- Staffing pipeline — every warehouse, CDL and forklift opening within 25 miles of each of your branches, in one run.

### Why this actor

- New-jobs-only monitoring built in: the Actor remembers delivered job IDs per monitor (kept in your own Apify account), so a scheduled run bills only for listings you have not seen.
- Many roles and many cities in one run, with nearby-city and job-type searches added for you and every job returned once.
- Real apply URLs, not Google redirect links, plus an employer_apply_url only when a link is on that employer's own site — never a guess.
- Rows carry no dates; 'Posted within' still filters on Google's posted age before billing.
- $2.50 per 1,000 jobs, charged per job returned after filters. The 531-user leader in this lane charges $0.09 per page of up to 10 jobs on the free plan and $0.035–0.045 on paid plans (Apify Store, 2026-10-31).

### Limitations & updates

Reads what Google Jobs shows on its US site in English, 10 listings per search; the Actor reaches more by running more searches, so depth depends on how many distinct listings Google has for the role around that place. Nearby cities are added only for US cities given as 'City, ST'. Rows carry no dates, by design. Apply links are the ones Google lists, including the near-duplicate postings it groups under one job. Salaries appear only where Google shows them, and employer_apply_url only where a link is clearly the employer's own.

### FAQ

**How many jobs can I get for one role in one city?**

As many as Google has across the searches the Actor runs for it. Google shows 10 jobs per search and will not page further without a browser, so the Actor adds the largest nearby cities (up to 30, within the radius you set) and six job-type variants. On 2026-10-31, with 30 nearby cities and a 30-mile radius, one run returned 173 software-engineer jobs around Austin (33 searches), 305 around Chicago (37), and 281 and 354 registered-nurse jobs around Austin and Chicago. Set 'Maximum jobs per role and location' to stop sooner; 10 costs one search.

**How does 'Only jobs not sent before' work?**

Each run remembers the Google job IDs it delivered, in a key-value store named 'google-jobs-seen' in your own Apify account, under a key for this monitor — your 'Monitor name', or one derived from the roles and places you search. The next run skips those jobs before billing and searches further to fill your cap with new ones. Run twice back to back on 2026-10-31, the second run returned 100 different jobs. When nothing new exists you get one free row saying so. Delete the store to start over.

**Why are there no posting dates in the rows?**

Google shows an age ('3 days ago'), not a date, and our rows carry no dates. 'Posted within' still uses that age to filter before billing; listings Google shows no age for are kept rather than silently dropped. For a daily feed, 'Only jobs not sent before' is the more exact tool: it compares job IDs, not dates.

**Are the apply links the real postings?**

Yes. Google's apply buttons are redirect links; the Actor ships the posting URL Google holds for each button instead, with tracking parameters removed. Across 1,113 jobs on 2026-10-31, 4,583 of 4,617 apply options carried a URL and 1,107 jobs had at least one. Google sometimes groups a near-identical posting from another city or employer under one job, and those links are passed on exactly as Google lists them.

**What is employer_apply_url?**

An apply link on the employer's own careers site or applicant-tracking system, filled only when a distinctive word of the employer's name appears in that link's source or address. Many listings are on job boards only, so it was filled for 169 of 1,113 jobs on 2026-10-31; when no link is clearly the employer's it stays empty rather than guessed.

**How often is a salary shown?**

When Google shows one: 482 of 1,113 jobs on 2026-10-31. You get Google's wording plus min, max and period. Most US listings print no currency symbol, so salary_currency is set only when one appears.

**Which locations work?**

US cities written as 'City, ST' get nearby cities added from the US postal place list. Anything else — a state, 'Remote', or a non-US place — is searched exactly as written, without nearby cities. Searches run on Google's US site in English; other countries were not tested.

**What happens when Google does not answer?**

Each search is retried once. A role and place whose searches all fail returns one free 'blocked' row; a search Google answers with no listings returns a free 'no_results' row. Nothing is billed for either.

**Do I pay for the extra searches?**

No. You pay per job returned after filters, at $2.50 per 1,000. A run that needs 30 searches to find 100 new jobs costs the same as one that needs 10.

### Which actor to choose

Other Actors in the portfolio that pair with this one:

- **Greenhouse, Lever, Ashby & Workday Jobs Scraper with Salaries** — You already know the employers and want every open role straight from their own applicant-tracking system.
- **Business Email, Phone & Contact Details Scraper** — You found who is hiring and now need contact details to reach them.

### Guides & use cases

Written up on **[scrapebench.dev](https://scrapebench.dev)** — the bench that runs and verifies this actor against the live source every night:

- **How-to:** [How to run Google Jobs Scraper: New Job Alerts, Salaries & Apply Links](https://scrapebench.dev/guides/how-to-google-jobs-scraper/)
- **Use case:** [Registered Nurse Jobs Across Several US Cities](https://scrapebench.dev/use-cases/nurse-jobs-in-several-cities/)

More actors, coverage and nightly verification results: **[scrapebench.dev](https://scrapebench.dev)**

### Works with AI assistants (MCP)

Callable as an MCP tool, so Claude, Cursor, VS Code Copilot and other MCP clients can run it directly. Grab the config from the [MCP tab](https://apify.com/scrapebench/google-jobs-scraper/api/mcp) on this page — Apify hosts the server and keeps that snippet current, and OAuth signs you in on first connect, so no API token goes in your config file.

Then just ask:

> "Find software engineer and registered nurse jobs around Austin, TX — up to 50 of each — with salary and the employer's own apply link where there is one."

Run 2026-10-31 with queries \['software engineer', 'registered nurse'], locations \['Austin, TX'] and maxJobsPerSearch 50: 100 jobs from 12 searches, 99 with an apply link. Runs started this way bill exactly like any other run.

### Data & lawful use

This actor collects publicly available information that Google (Google Jobs), which gathers postings from employers and job boards publishes for public
lookup — licence records, business listings and the contact details professionals list there.
Some of it identifies individuals (sole proprietors, licence holders, agents), so treat any
names, phone numbers and emails in your results as personal data.

When you run this actor, you decide what is collected and what it is used for, so you are the
controller of that data and we act only as your processor (Apify Standard Actor Contract).
You need a lawful basis for your use, must honour opt-out and deletion requests, and must
follow the marketing rules that apply to you (CAN-SPAM, TCPA, GDPR, CCPA and similar).
Don't use the output for unsolicited bulk messaging, for screening covered by the FCRA, or
for anything the source's own terms forbid.

Your results are stored in your own Apify account. We don't keep a copy of your results and
don't sell or share them.

### Disclaimer

This is an independent tool. It is not affiliated with, endorsed by or sponsored by
Google (Google Jobs), which gathers postings from employers and job boards. Names and marks are used only to describe the data source. Records are
provided as published by the source and may be out of date or incomplete. For anything
consequential (hiring, a permit, a legal decision), confirm the record with the issuing
agency. You are responsible for making sure your use complies with applicable law and the
source's terms.

### Need help?

Open an issue on this actor's **Issues** tab and we'll respond there. Bug reports, missing
fields and feature requests are all welcome. Guides and examples: [scrapebench.dev](https://scrapebench.dev).

If you are a person named in this data and want your record removed from our copy, email
apify-help@scrapebench.dev; the source agency remains the official record.

Your run may be used to improve our services. If something looks off, or you want this actor to fit your use better, please share your run data with us: [Apify Console → Settings → Security → Share run data with developers](https://console.apify.com/settings/security). It lets us see exactly what went wrong and keep improving the actor.

# Actor input Schema

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

A role or keywords, e.g. 'registered nurse' or 'python developer'. Kept forever alongside 'Jobs to search for' — saved tasks and API callers send it.

## `queries` (type: `array`):

One or many roles in ONE run, e.g. 'registered nurse', 'medical assistant'. Every role is searched in every location below, and a job found by two searches is returned once.

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

A US city as 'City, ST', e.g. 'Chicago, IL'. Kept forever alongside 'Locations'.

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

One or many US cities as 'City, ST' (e.g. 'Chicago, IL', 'Austin, TX'). Leave empty to search without a place. A city is what lets the Actor add nearby cities; a state or 'Remote' is searched as written, without them.

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

Cap PER role-and-location pair, not per run. Google shows 10 jobs per search, so the Actor runs more searches (nearby cities, then job types) until it has this many new jobs or runs out of searches. 10 costs one search.

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

Keep only jobs Google shows as posted within this window. Applied before billing. Jobs Google shows no age for are kept, so nothing disappears unexplained. The age itself is never included in the output.

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

Remember every job this monitor has delivered and return (and bill) only jobs it has not sent before. Schedule the Actor daily with this on for a new-jobs feed. The memory is kept in your own Apify account (key-value store 'google-jobs-seen').

## `monitorName` (type: `string`):

Optional name for the 'only new jobs' memory, e.g. 'nurses-chicago'. Leave empty and the memory is tied to the exact roles and locations you search. Use the same name to share one memory across differently configured runs.

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

Keep only jobs Google marks 'Work from home'. Applied before billing.

## `expandNearbyCities` (type: `boolean`):

Also search the largest cities around each US location (Round Rock and Georgetown around Austin). Each nearby city added 8–10 new jobs per search when tested.

## `nearbyCities` (type: `integer`):

How many nearby cities to add at most. They are only searched while the cap above is not yet reached.

## `nearbyRadiusMiles` (type: `integer`):

How far from each location a nearby city may be.

## `expandJobTypes` (type: `boolean`):

Also search entry level, remote, contract, internship, part time and senior variants of each role. Each added 4–10 new jobs per search when tested.

## `includeDescription` (type: `boolean`):

The full posting text (median ~4,000 characters). Turn off for a lighter dataset; highlights stay either way.

## Actor input object example

```json
{
  "queries": [
    "registered nurse"
  ],
  "locations": [
    "Chicago, IL"
  ],
  "maxJobsPerSearch": 30,
  "postedWithin": "any",
  "onlyNewJobs": false,
  "remoteOnly": false,
  "expandNearbyCities": true,
  "nearbyCities": 8,
  "nearbyRadiusMiles": 25,
  "expandJobTypes": true,
  "includeDescription": true
}
```

# Actor output Schema

## `results` (type: `string`):

Every job found: title, employer, location, salary, highlights and the direct apply link.

# 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 = {
    "queries": [
        "registered nurse"
    ],
    "locations": [
        "Chicago, IL"
    ],
    "maxJobsPerSearch": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapebench/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 = {
    "queries": ["registered nurse"],
    "locations": ["Chicago, IL"],
    "maxJobsPerSearch": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapebench/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 '{
  "queries": [
    "registered nurse"
  ],
  "locations": [
    "Chicago, IL"
  ],
  "maxJobsPerSearch": 30
}' |
apify call scrapebench/google-jobs-scraper --silent --output-dataset

```

## MCP server setup

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