# Google for Jobs Scraper (Salaries and Apply Links) (`locaihost/google-jobs`) Actor

Scrape Google Jobs (Google for Jobs) by date posted with no login: title, employer, location, source board, salary as numbers, job type, full description and every apply link, plus the employer's US H-1B/PERM filing record and UK sponsor licence. Only-new mode for alerts. $0.75 per 1,000 jobs.

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

## Pricing

from $0.41 / 1,000 jobs

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

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

## What's an Apify Actor?

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

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

## How to integrate an Actor?

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

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

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

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

# README

## Google for Jobs Scraper (Salaries and Apply Links)

Search Google Jobs in 21 countries the way you would in a browser and get one row per job with title, employer, location, the board it came from, salary as numbers, job type, the full description and every "Apply on" link, plus the employer's US H-1B/PERM filing record and UK sponsor licence. No login, no cookies.

- **Feed a job board:** Google Jobs already gathers postings from many boards and career sites; get them as one clean feed.
- **Research salaries:** salary ranges as numbers by title and city, with the period (hour, day, week, month or year).
- **Get a daily job alert:** schedule a saved search with `onlyNew` and receive only jobs you haven't seen.
- **Skip the redirects:** every apply link with its real URL, and `applyUrl` pointing to the first direct one.
- **Find jobs that can sponsor a visa:** see what the posting says about sponsorship and whether the employer actually files.

### Quick start

Paste this into the **JSON** tab of the input and click **Start**:

```json
{"queries": ["data analyst"], "location": "Chicago, IL", "maxResults": 10}
```

You get 10 jobs in about a minute: most of that is the run opening its Google session, after which pages come back in a few seconds each. `maxResults` is per search, and each search runs in every location you give.

### Filter by date posted

Set `datePosted` to `today` (past 24 hours), `3days`, `week` or `month`; the default `any` keeps every job. The run uses **Google's own "Date posted" filter**: it opens your search, then follows the link behind Google's "Date posted" chip for that window, exactly as clicking it in a browser would. If Google's page has no chip (rare), it searches with the chip's words instead ("… since yesterday"). Either way each job's age ("3 days ago") is checked again, so a job outside the window is dropped and never charged. A job whose card shows no age is kept, because Google's filter let it through.

**Past 24 hours is the exception.** Google's own "Yesterday" filter returns almost nothing for logged-out searches (one nurse job in Houston and no data analyst jobs in Chicago when we tested on 18 Oct 2026). So `today` uses Google's "Last 3 days" filter and keeps only the jobs whose age shows 24 hours or less. A job with no age shown is dropped, since it can't be shown to be that recent. The run's `SUMMARY` record says which way each search went (`dateFilter.searchesViaGoogleChip`) and counts `droppedOlder` and `keptWithoutDate`.

```json
{"queries": ["registered nurse"], "location": "Austin, TX", "datePosted": "3days", "maxResults": 20}
```

### What data can I get?

| Group | Fields |
|---|---|
| Job | `jobId` (stable across runs), `title`, `companyName`, `location`, `via` (the board Google found it on), `postedAgo`, `postedDate` (approximate), `googleJobsUrl` |
| Salary | `salaryText`, `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod` |
| Type | `employmentType`, `jobTypes`, `remote`, `qualification`, `tags` (such as "Health insurance", "Work from home") |
| Apply | `applyLinks` (every site, with its real URL and whether Google marks it "Apply directly"), `applyUrl` (the first direct one, else the first) |
| Description | `description`, `descriptionIsPreview`, `highlights`, and the same highlights as flat lists: `qualifications`, `responsibilities`, `benefits` |
| What the posting says | `postingSponsorship` (`offers` or `declines`) with the sentence in `postingSponsorshipText` |
| US sponsorship | `sponsorSignal` (`strong`, `some`, `none`), `sponsorMatch`, `h1bEmployer`, `h1bCertifiedLatestFY`, `h1bCertifiedTotal`, `permCertifiedTotal`, `similarFiledTitle`, `similarTitleFilings`, `similarTitleMedianWage` + currency and period |
| UK sponsorship | `ukLicensed`, `ukSponsorName`, `ukRating`, `ukRoutes`, `ukMatchBasis`, `possibleMatches` |
| Plain English | `sponsorNote`: one sentence you can show a candidate |
| Run | `searchQuery`, `searchLocation`, `searchCountry`, `scrapedAt` |

**How the sponsorship flag works.** US evidence is the employer's certified H-1B (and H-1B1/E-3) Labor Condition Applications and PERM cases from the US Department of Labor's public disclosure files, FY2024 to date; `similarFiledTitle` is the employer's filed title closest to this job, with its median filed wage. UK evidence is the Home Office register of licensed sponsors; `ukMatchBasis` is `exact`, `trading-name`, `brand-map` (a reviewed brand to legal-entity list) or `unconfirmed` (only similar names, listed in `possibleMatches`). When nothing is found the note says *"no filings found under this name"*, never "doesn't sponsor". The flag is evidence, not legal advice.

One real row (run on 2026-10-18, shortened):

```json
{
  "jobId": "VhkQmYW-CckTwmfsAAAAAA==",
  "title": "Finance Data Analyst",
  "companyName": "GEICO",
  "location": "Chicago, IL",
  "via": "ZipRecruiter",
  "salaryText": "$86,100–$133,250 a year",
  "salaryMin": 86100,
  "salaryMax": 133250,
  "salaryCurrency": "USD",
  "salaryPeriod": "year",
  "employmentType": "Full-time",
  "remote": false,
  "applyUrl": "https://www.careerbuilder.com/job-details/finance-data-analyst-chicago-il--255f67ad-d082-4c11-915a-55a1b4cd5668?utm_campaign=google_jobs_apply&utm_source=google_jobs_apply&utm_medium=organic",
  "applyLinks": [
    {"name": "ZipRecruiter", "url": "https://www.ziprecruiter.com/c/Geico/Job/Finance-Data-Analyst/-in-Chicago,IL?jid=24948ba39a4f07b1&utm_campaign=google_jobs_apply&utm_source=google_jobs_apply&utm_medium=organic", "direct": false},
    {"name": "CareerBuilder", "url": "https://www.careerbuilder.com/job-details/finance-data-analyst-chicago-il--255f67ad-d082-4c11-915a-55a1b4cd5668?utm_campaign=google_jobs_apply&utm_source=google_jobs_apply&utm_medium=organic", "direct": true}
  ],
  "descriptionIsPreview": false,
  "postingSponsorship": "declines",
  "postingSponsorshipText": "At this time, GEICO will not sponsor a new applicant for employment authorization for this position.",
  "sponsorSignal": "none",
  "sponsorNote": "No H-1B/PERM filings (FY2024–FY2026) or UK sponsor licence found under this name. The employer may file under a different legal name."
}
```

The dataset has four views (**Overview**, **Visa sponsorship**, **Salary**, **Qualifications, duties, benefits**) and exports to JSON, CSV, Excel or HTML. The run's `SUMMARY` record lists the searches run, jobs skipped and why.

### How much does it cost?

You pay per job returned, with descriptions, apply links and sponsorship flags included. There is no charge for Apify platform usage on top.

| Row | Free and Starter | Scale | Business |
|---|---|---|---|
| Job | $0.75 per 1,000 | $0.56 per 1,000 | $0.41 per 1,000 |

Plus $0.00005 per run start. **Apify's free $5 monthly credit covers about 6,600 jobs.** Free-plan runs stop at 500 jobs each; any paid Apify plan removes the cap.

**What's free:** a job found by two of your searches or locations (returned and charged once), jobs that fail your date, job type or remote filters (every filter is checked again on each row, so a job Google lets through anyway is dropped), jobs dropped by `sponsorship: only-with-evidence`, jobs skipped by `onlyNew`, and runs that find nothing. To cap a run's spend, set **Maximum cost per run** in the run options.

### Limits, stated up front

- **Logged-out only.** It reads the Google Jobs results any visitor sees. It never signs in and never asks for your cookies.
- **Google shows a few hundred jobs per search at most** (about 200 for "registered nurse in Texas"). For more, split by city with `locations` or add related searches.
- **Google sometimes asks for a traffic check;** the run handles it. On the rare run where it can't, you get the first 10 jobs of each search and the status message says so.
- **Salary** appears only when the posting has one. When Google prints no currency symbol, the currency of the country you chose is used.
- **Dates are approximate:** Google shows "3 days ago", not a timestamp, and some cards show no date. `datePosted` windows follow Google's own filter (see above).
- **In the EU, Google shows only a short preview** of each description; `descriptionIsPreview` says so, and the apply links lead to the full text.
- **Google Jobs isn't offered everywhere.** Australia, New Zealand, Ireland, the Nordics and Poland get web results instead of a Jobs list, so they aren't in the country list.
- **Outside English-speaking countries, write the city the way locals do** ("München", not "Munich"). When the first wording finds nothing, the run tries looser ones and keeps their jobs only if they are about your search.
- **`radiusKm`** is Google's own radius setting, which Google treats as a guide, so a job a little further out can still appear.
- Field labels are read in English; descriptions stay in the posting's own language. US filing data is refreshed quarterly; the latest fiscal year is partial.
- **Time limit:** if a run nears its timeout, it stops, keeps what it found and says so in the status message.

### Only new since last run, and schedules

Turn on `onlyNew` in a saved task and schedule it daily: each run returns only jobs that no earlier run of the same search returned, so you get a clean job alert and never pay twice for the same job. Skipped jobs cost nothing. Set up a schedule under **Schedules** in Apify Console.

### Integrations: API, n8n, Make and AI agents

**API.** Run it and get the rows back in one call:

```bash
curl -X POST "https://api.apify.com/v2/acts/locaihost~google-jobs/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"queries": ["registered nurse"], "locations": ["Austin, TX", "Dallas, TX"], "datePosted": "week", "maxResults": 50}'
```

Apify's API clients for Python and JavaScript work the same way.

**n8n, Make, Zapier, Google Sheets, Slack, webhooks.** Apify's built-in integrations send each run's dataset wherever you need it.

**AI agents (MCP).** Add this Actor to Cursor or any other MCP client with `https://mcp.apify.com/?tools=locaihost/google-jobs`, then ask something like *"Find remote Python developer jobs posted in the past 3 days that list a salary, and give me the direct apply links."*

### FAQ

#### How much does it cost to scrape Google Jobs?

$0.75 per 1,000 jobs on the Free and Starter plans, descriptions, apply links and sponsorship flags included, and less on Scale and Business. Apify's free $5 monthly credit covers about 6,600 jobs.

#### Can I use it through the API or from Python?

Yes. Use the `run-sync-get-dataset-items` call above, or Apify's Python and JavaScript clients. Every run's data is also available as JSON, CSV or Excel from its dataset.

#### Can I use it from an AI agent?

Yes. Through the Apify MCP server (`https://mcp.apify.com/?tools=locaihost/google-jobs`) any MCP client can run a search and read the jobs back.

#### Is it legal to scrape Google Jobs?

The Actor reads only the job listings Google shows to any logged-out visitor, plus public US Department of Labor files and the UK sponsor register. It never signs in. Google's terms restrict automated access, so weigh that for your use. Email addresses, phone numbers and profile links in descriptions are replaced, and a name that follows a recruiter cue ("Recruiter: ...") becomes "\[name removed]". Use the data for job search, job-board aggregation and labour-market research, and respect Google's and each source board's terms when you republish postings, plus the privacy laws that apply to you.

#### Which countries can I search?

21: the US, UK, Canada, India, Germany, France, Spain, Italy, Switzerland, Singapore, Malaysia, the Philippines, Indonesia, Hong Kong, the UAE, Saudi Arabia, South Africa, Nigeria, Kenya, Mexico and Brazil.

#### Why are some fields empty?

Salary appears only when the posting has one, some cards show no date or job type, highlights lists are empty when Google shows none, and sponsorship fields are `null` when no filing matched the employer's name.

### More from locaihost data

- [LinkedIn Jobs Scraper](https://apify.com/locaihost/linkedin-jobs): LinkedIn jobs with the same visa sponsorship flags.
- [Indeed Jobs Scraper](https://apify.com/locaihost/indeed-jobs): Indeed jobs in 51 countries, salaries as yearly USD.
- [Careers Page Jobs Scraper](https://apify.com/locaihost/careers-jobs): every open role straight from company career pages.
- [H1B and UK Visa Sponsor Lookup](https://apify.com/locaihost/visa-sponsors): check a list of employers' sponsorship records directly.

### Did it help?

If this saved you time, a quick rating on the Store helps other people find it.

### Support

Something not working, or a field you need? Open an issue on the **Issues** tab: we answer issues within 24 hours.

# Changelog

This Actor's version history is a separate document: https://apify.com/locaihost/google-jobs/changelog.md

# Actor input Schema

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

What you'd type into Google, e.g. "data analyst", "registered nurse", "python developer". Each search runs in the location below.

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

A city, region or country as you'd write it, e.g. "Chicago, IL", "London", "Bangalore". Leave empty to search the whole country below.

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

The Google country to search from. Google Jobs isn't offered in every country (not in Australia, New Zealand, Ireland or the Nordics, for example), so only countries where it works are listed. The country also decides the currency of salaries Google shows without a symbol.

## `maxResults` (type: `integer`):

Per search. Google shows a few hundred jobs for one search at most; for more, add searches or locations.

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

Only jobs posted in this window, using Google's own Date posted filter. Each job's age is checked again: older jobs are dropped and never charged.

## `jobType` (type: `string`):

Only this kind of job. Leave on "Any" for all.

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

Keep only jobs Google marks as work from home, or whose location or title says remote.

## `sponsorship` (type: `string`):

"Flag" adds each employer's US H-1B/PERM filing record and UK sponsor licence to every job. "Only with evidence" keeps only jobs whose employer has filed for this kind of role, holds a UK licence, or whose posting says it sponsors (postings that say they don't are left out). "Off" skips the check.

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

Optional. Several cities, regions or countries: every search runs in each one (and in Location above, when that is filled in too). A job found in two places is returned and charged once.

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

Optional. How far around each location Google should look, in kilometres (Google's own radius setting). Google treats it as a guide rather than a hard limit, so a job a little further out can still appear. Leave empty for Google's default.

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

The full description and Google's job highlights (qualifications, benefits, responsibilities). Turn off for smaller rows.

## `onlyNew` (type: `boolean`):

Remembers what this saved task already returned, so a daily schedule becomes a job alert. Off by default so the first run returns everything.

## Actor input object example

```json
{
  "queries": [
    "data analyst",
    "software engineer"
  ],
  "location": "Austin, TX",
  "country": "US",
  "maxResults": 10,
  "datePosted": "any",
  "jobType": "any",
  "remoteOnly": false,
  "sponsorship": "flag",
  "locations": [
    "Austin, TX",
    "Dallas, TX"
  ],
  "radiusKm": 50,
  "includeDescription": true,
  "onlyNew": false
}
```

# Actor output Schema

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

One record per job posting with salary, apply links and sponsorship evidence.

## `summary` (type: `string`):

Jobs returned and skipped, per-search counts, data dates and measured cost per 1,000.

# 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": [
        "data analyst"
    ],
    "location": "Chicago, IL",
    "maxResults": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("locaihost/google-jobs").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": ["data analyst"],
    "location": "Chicago, IL",
    "maxResults": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("locaihost/google-jobs").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": [
    "data analyst"
  ],
  "location": "Chicago, IL",
  "maxResults": 10
}' |
apify call locaihost/google-jobs --silent --output-dataset

```

## MCP server setup

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

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/ijhDH7SwHBDMiB5lQ/builds/btWgXmjTcaQE0VOYu/openapi.json
