# Google Jobs Scraper (US & UK) (`daedal_quintuplet/google-jobs-scraper`) Actor

Scrape Google Jobs for US and UK searches: title, company, location, salary, job type, full description and apply links. Up to 10 jobs per query.

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

## Pricing

$2.50 / 1,000 job results

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 (US & UK)

**Google Jobs Scraper** turns any Google Jobs search into clean, structured data. Type a search such as `data analyst new york` or `nurse london`. For every job, the actor returns the title, company, location, the job board Google credits, the posting age, the salary (when the listing shows one), the job type, the **full job description** and **every apply link** Google lists.

People also look for this as a **Google Jobs API**, a **Google for Jobs scraper**, a **Google job search API** or a **Google Jobs results extractor**. It works for **United States** and **United Kingdom** searches, runs without a browser, and usually finishes in seconds.

This is an independent tool. It is not affiliated with, endorsed by or sponsored by Google. It reads the public job results that Google Search shows to anyone.

### What data you get

Every job is one row in the dataset. The fields below come from real test runs (US and UK) of the current build.

| Field | Type | What it holds | Example |
|---|---|---|---|
| `id` | string | Google's job ID, stable across runs (used for de-duplication) | `KtcS0tcEKLtsSxmKAAAAAA==` |
| `title` | string | Job title | `Practice Nurse` |
| `company` | string | Hiring company | `Pure Healthcare Group` |
| `location` | string or null | Location as Google shows it | `London` |
| `via` | string | The job board or site Google credits for the listing | `Built In NYC` |
| `postedAt` | string or null | Posting age as Google shows it | `6 days ago` |
| `salary` | string or null | Salary text, only when the listing shows one | `£41k–£50k a year` |
| `jobType` | string or null | Employment type when shown | `Full-time` |
| `description` | string | Full job description text, with line breaks kept | `We're recruiting a Band 6 Practice Nurse…` |
| `applyLinks` | array | Every apply option: `{name, url}` | `[{"name": "Nurses.co.uk", "url": "https://www.google.com/goto?url=…"}]` |
| `googleJobsUrl` | string | Link that opens this job in Google Jobs | `https://www.google.com/search?ibp=htl;jobs&htidocid=…` |
| `query` | string | The search that found the job | `nurse london` |
| `country` | string | `us` or `uk` | `uk` |
| `scrapedAt` | string | ISO timestamp of the scrape | `2026-11-08T20:41:56.677Z` |

**Field fill rates in testing (30 jobs, 3 searches, US and UK):** `title`, `company`, `via`, `description`, `applyLinks`, `googleJobsUrl` 100%; `location` 97%; `postedAt` 83%; `salary` 53%; `jobType` 47%. Salary and job type are empty when the original listing doesn't state them. The actor never guesses them.

### How to use it

1. Open the actor and click **Try for free** (or **Start**).
2. In **Search queries**, add one search per line, written the way you would type it into Google, e.g. `software engineer manchester`. Put the place in the query.
3. Pick the **Country**: `us` for United States results or `uk` for United Kingdom results.
4. Set **Max jobs** to the total number of jobs you want across all queries. The default is 10. Raise it when you add several queries.
5. Optional: turn on **Only new jobs** if you will run the actor on a schedule and only want jobs you haven't seen before.
6. Click **Start**. When the run finishes, open the **Output** tab and export the jobs as JSON, CSV, Excel, XML or HTML, or fetch them through the API.

Each query returns the jobs Google shows for one search: at most 10, and in our November 2026 tests usually only 3. To collect more jobs, add more specific queries: other cities, job titles, seniority levels or keywords (for example `junior data analyst brooklyn`, `senior data analyst manhattan`, `data analyst remote`). Duplicate jobs across queries are removed automatically within a run.

### Input examples

**1. A single US search (the default example)**

```json
{
  "queries": ["data analyst new york"],
  "country": "us",
  "maxItems": 10
}
```

**2. Several UK searches in one run**

```json
{
  "queries": ["nurse london", "software engineer manchester"],
  "country": "uk",
  "maxItems": 20
}
```

**3. A daily feed of new jobs only (for schedules)**

```json
{
  "queries": ["product manager san francisco", "product manager remote", "product owner austin"],
  "country": "us",
  "maxItems": 30,
  "onlyNew": true
}
```

**4. Many role and city combinations**

```json
{
  "queries": [
    "registered nurse chicago",
    "registered nurse houston",
    "registered nurse phoenix",
    "travel nurse",
    "ICU nurse los angeles"
  ],
  "country": "us",
  "maxItems": 50
}
```

#### Input fields

| Field | Required | Default | Description |
|---|---|---|---|
| `queries` | yes | none | List of job searches in plain words, e.g. `["data analyst new york"]` |
| `country` | no | `us` | `us` or `uk` |
| `maxItems` | no | `10` | Total jobs to return across all queries (1 to 1000) |
| `onlyNew` | no | `false` | Skip jobs returned by earlier runs |
| `debug` | no | `false` | Save the raw search page HTML to the run's key-value store |

### Output example

A real row from a UK test run (description shortened, apply links trimmed to two):

```json
{
  "id": "KtcS0tcEKLtsSxmKAAAAAA==",
  "title": "Practice Nurse",
  "company": "Pure Healthcare Group",
  "location": "London",
  "via": "Pure Healthcare Group",
  "postedAt": "6 days ago",
  "salary": "£41k–£50k a year",
  "jobType": null,
  "description": "We're recruiting a Band 6 Practice Nurse for a permanent role in London, paying £41,000 to £50,000 per year, starting as soon as possible. Apply below or call our nursing team for the full details. …",
  "applyLinks": [
    { "name": "Pure Healthcare Group", "url": "https://www.google.com/goto?url=CAES1AEB…" },
    { "name": "Nurses.co.uk", "url": "https://www.google.com/goto?url=CAESvwEB…" }
  ],
  "googleJobsUrl": "https://www.google.com/search?ibp=htl;jobs&htidocid=KtcS0tcEKLtsSxmKAAAAAA%3D%3D",
  "query": "nurse london",
  "country": "uk",
  "scrapedAt": "2026-11-08T20:42:35.253Z"
}
```

And a US row (shortened):

```json
{
  "id": "93Ca3Nw89N0VnIw-AAAAAA==",
  "title": "Customer Data Analyst",
  "company": "L'Occitane En Provence",
  "location": "New York, NY",
  "via": "Built In NYC",
  "postedAt": "3 days ago",
  "salary": "75K–85K a year",
  "jobType": "Full-time",
  "description": "…",
  "applyLinks": [{ "name": "Built In NYC", "url": "https://www.google.com/goto?url=…" }],
  "query": "data analyst new york",
  "country": "us"
}
```

### Use cases

- **Job boards and aggregators:** fill a niche job board with fresh listings for chosen roles and cities, with full descriptions and apply links.
- **Recruiting and sourcing:** see which companies are hiring for a role in a city right now, and where each job is advertised.
- **Salary research:** collect salary ranges for a title across cities. About half of listings show a salary.
- **Labour-market analytics:** track demand for skills, titles or locations over time by running the same searches daily.
- **Sales prospecting:** companies that are hiring are growing. Use new postings as a signal for outreach about recruiting, HR or tooling.
- **Job alerts:** send yourself or your users a daily list of new jobs that match a search (see the next section).
- **AI agents and RAG:** give an assistant up-to-date job data with full descriptions it can summarise, match against a CV or classify.

### Run it on a schedule and get only new jobs

1. Save your input (for example example 3 above) as a **task** in Apify Console.
2. Turn on **Only new jobs** (`"onlyNew": true`). The actor remembers the IDs of jobs it has returned in a key-value store named `google-jobs-seen` in your own Apify account. Later runs skip those jobs, so each run returns only jobs you haven't seen.
3. Add a **schedule** to the task (for example every morning at 7:00).
4. Connect the output to where you need it: a webhook, Google Sheets, Slack, email via Make or Zapier, or your database through the API.

If a scheduled run finds nothing new, the dataset is simply empty and you are not charged. To start fresh, delete the `SEEN` record from the `google-jobs-seen` store.

### Integrations

**API (one call, returns the jobs):**

```
POST https://api.apify.com/v2/acts/daedal_quintuplet~google-jobs-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN
Content-Type: application/json

{"queries": ["data analyst new york"], "country": "us", "maxItems": 10}
```

**Python** (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("daedal_quintuplet/google-jobs-scraper").call(
    run_input={"queries": ["nurse london"], "country": "uk", "maxItems": 10}
)
for job in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(job["title"], "|", job["company"], "|", job.get("salary"))
```

**JavaScript / Node.js** (`npm install apify-client`):

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('daedal_quintuplet/google-jobs-scraper').call({
    queries: ['data analyst new york'],
    country: 'us',
    maxItems: 10,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((job) => console.log(job.title, '|', job.company, '|', job.location));
```

**No-code tools:**

- **n8n:** use the Apify node, choose *Run actor*, enter `daedal_quintuplet/google-jobs-scraper` and your input JSON, then read the dataset items.
- **Make:** use the Apify app's *Run an Actor* module, then *Get Dataset Items*.
- **Zapier:** use the Apify integration's *Run Actor* action, or trigger a Zap when a scheduled run finishes.
- **Google Sheets, Slack, webhooks:** connect them from the actor's **Integrations** tab in Apify Console.

**AI agents (MCP):** the actor is available through Apify's MCP server (`https://mcp.apify.com`). Add `daedal_quintuplet/google-jobs-scraper` as a tool, and Claude, Cursor or any MCP client can search jobs on request. Every input field has a plain description so the agent can fill it in.

### Pricing

Pay per result: **$2.50 per 1,000 jobs** ($0.0025 per job). Error rows and empty runs are free. A typical 10-job search costs $0.025.

### Limits and error items

- **Countries:** United States (`us`) and United Kingdom (`uk`). Other countries are not supported. Google doesn't show the jobs panel for many of them (Australia, for example).
- **Up to 10 jobs per query:** Google shows at most 10 jobs for one search (often only 3 since November 2026) and doesn't allow paging through more, so use more specific queries to collect more.
- **Apply links** are Google redirect links (`https://www.google.com/goto?url=…`) that open the employer's or job board's page.
- **`postedAt`** is relative text as Google shows it (`3 days ago`), not a date. Use `scrapedAt` to work out the approximate date.
- **Error rows:** bad input, a failed fetch or a search with no results returns a single row like `{"error": true, "query": "…", "message": "…"}` instead of crashing the run. Error rows are never charged. Filter them out with `error != true`.
- **Restarts are safe:** if Apify moves the run to another server mid-run, finished queries are skipped and jobs already returned are not pushed or charged twice.

### FAQ

**Is there an official Google Jobs API?**
No. Google doesn't offer a public API for the Google Jobs search panel. This actor gives you the same data as JSON.

**How many jobs does one search return?**
At most 10, and since November 2026 Google often shows only 3 for one search. Paging isn't possible. Add variations (other cities, titles or keywords). Duplicates across queries are removed.

**Does it work for Canada, Australia or India?**
No. Only US and UK searches are supported and tested.

**Why is `salary` sometimes null?**
Many employers don't publish a salary. The field is filled only when Google shows one for the listing (about half of jobs in testing).

**Do I need a proxy or a Google account?**
No. The actor handles access itself. You need no Google account, API key or proxy setup.

**How fast is it?**
A one-query run usually finishes in under a minute; if Google is slow the actor retries the page, which can take up to about 3 minutes.

**Is scraping Google Jobs legal?**
The actor collects publicly visible job postings, not personal data. Check the rules that apply to you and how you use the data.

### Related actors

- [Google Jobs Scraper (US & UK)](https://apify.com/daedal_quintuplet/google-jobs-scraper): this actor.
- [Seek AU Job Scraper](https://apify.com/daedal_quintuplet/seek-au-job-scraper): job listings from SEEK Australia, the main jobs site in Australia (where Google Jobs isn't available).
- [Seek NZ Job Scraper](https://apify.com/daedal_quintuplet/seek-nz-job-scraper): job listings from SEEK New Zealand.
- [Google Trends Scraper](https://apify.com/daedal_quintuplet/google-trends-scraper-all-widgets): interest over time, by region, and related topics and queries for up to 20 keywords. Useful for spotting rising skills and job titles.

Code examples for all our actors (Python, Node.js, n8n and Make) are in the public GitHub repo [thayneanderson18-maker/auto-actor](https://github.com/thayneanderson18-maker/auto-actor).

# Actor input Schema

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

Job searches, e.g. 'software engineer london'.

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

Google country (US or UK supported).

## `maxItems` (type: `integer`):

Stop after this many jobs in total.

## `debug` (type: `boolean`):

Save raw HTML for debugging.

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

Skip jobs already returned by earlier runs (remembered in the 'google-jobs-seen' store of your account).

## Actor input object example

```json
{
  "queries": [
    "data analyst new york"
  ],
  "country": "us",
  "maxItems": 10,
  "debug": false,
  "onlyNew": false
}
```

# Actor output Schema

## `jobs` (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 = {
    "queries": [
        "data analyst new york"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("daedal_quintuplet/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": ["data analyst new york"] }

# Run the Actor and wait for it to finish
run = client.actor("daedal_quintuplet/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": [
    "data analyst new york"
  ]
}' |
apify call daedal_quintuplet/google-jobs-scraper --silent --output-dataset

```

## MCP server setup

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