# Google Jobs Scraper: Fresh Listings, No Charge for Empty Runs (`opendata-apis/google-jobs-scraper`) Actor

Job listings from Google Jobs for any search and location: title, company, salary, posting age and apply links. Optionally only jobs you have not seen before.

- **URL**: https://apify.com/opendata-apis/google-jobs-scraper.md
- **Developed by:** [Sébastien Doom](https://apify.com/opendata-apis) (community)
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 jobs

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

Job listings from Google Jobs for any search and location: title, company, salary, posting age and apply links. Never charged for an empty run, optionally only the jobs you have not seen before, $0.003 per job.

- **Never charged for empty runs**: a search with no result, a search that could not be made, or a search refused costs nothing.
- **Only new jobs**: for a daily or weekly feed, skip the jobs already returned and pay for the new ones only.
- **$0.003 per job**, no start fee.

### What you get for each job

One row per job:

- **Listing**: `title`, `company`, `location` (the job's own), `via` (the site Google found it on), `description`, `scheduleType` (full-time, contractor...), `isRemote` (`true` when the listing is remote, otherwise `null`).
- **Pay and age**: `salary` when the posting states one, `postedAgo` (for example "3 days ago").
- **Apply links**: `applyLinks`, each with a `title` and a `url`.
- **Identity**: `jobKey`, a 32-character hash that identifies the job, used by "only new jobs".
- **Your search**: `searchQuery` and `searchLocation` (the query and location you gave) and `scrapedAt` (ISO timestamp).

Data comes from Google Jobs through a search API.

### Pricing

Pay per event, no start fee:

| Event | Price |
|---|---|
| Job | $0.003 |

A row is delivered to the dataset, then charged. Never charged:

- jobs skipped by "Only jobs not seen before";
- searches that return no job;
- searches skipped because of a bad search input or a temporary unavailability of the source;
- searches refused because of the monthly capacity or the run limit (see below).

Set a maximum charge for the run and the Actor stops cleanly when it is reached. If the service fails during a run, the message says how many jobs were delivered and billed before the failure.

### Scheduled feeds: only new jobs

Tick **Only jobs not seen before** and give the feed a **Feed name** (lowercase letters, digits and dashes). The Actor remembers the jobs it returned for that feed during the last 30 days and skips them. Runs left on the default feed name share one memory of seen jobs, so give separate feeds distinct feed names. Use one feed name per recurring task, then schedule the task daily or weekly.

Each search looks at its first N results (**Jobs per search**), so a run returns the new ones among those first N. Skipped jobs are not charged.

### Locations

Write locations in Google's canonical form "City, State, Country", for example "Austin, Texas, United States", "London, England, United Kingdom" or "Paris, Ile-de-France, France". Short forms such as "New York, NY" can resolve to the wrong place.

### Launch limits

- At most **20 result pages per run** during launch (up to 200 jobs). Each search uses one page per 10 jobs asked for; pages served from recent cache do not count. The input accepts up to 50 searches, but a run stops at its page limit and says so: the remaining searches are not made and not charged.
- A **monthly capacity** is shared by all users. When it is reached the run stops with the date searches resume, and is not charged for the refused searches.
- **Jobs per search**: 10 to 100, in whole pages of 10 (rounded up).

### Input

```json
{
  "searches": [
    { "query": "software engineer", "location": "Austin, Texas, United States" },
    { "query": "data analyst", "location": "London, England, United Kingdom" }
  ],
  "country": "us",
  "language": "en",
  "maxJobsPerSearch": 20,
  "onlyNewJobs": true,
  "feedName": "tech-jobs"
}
```

### Output

```json
{
  "jobKey": "9f2c4a7e1b3d58a60c7e2f41d9b8a35e",
  "title": "Software Engineer",
  "company": "Acme Corp",
  "location": "Austin, TX",
  "via": "LinkedIn",
  "description": "We are looking for...",
  "applyLinks": [{ "title": "Apply on LinkedIn", "url": "https://www.linkedin.com/jobs/view/123" }],
  "salary": "$120K-$150K a year",
  "postedAgo": "3 days ago",
  "scheduleType": "Full-time",
  "isRemote": null,
  "searchQuery": "software engineer",
  "searchLocation": "Austin, Texas, United States",
  "scrapedAt": "2026-11-05T09:00:00.000Z"
}
```

Fields the posting does not state are `null`.

### Limits

Google Jobs listings only, as Google shows them: no company reviews, no contact details, no applying on your behalf.

# Actor input Schema

## `searches` (type: `array`):

Each search is a job query and a location, for example {"query": "software engineer", "location": "Austin, Texas, United States"}. Write the location in Google's canonical form "City, State, Country" (e.g. "Austin, Texas, United States", "London, England, United Kingdom", "Paris, Ile-de-France, France"): short forms such as "New York, NY" can resolve to the wrong place. Up to 50 searches per run.

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

Two-letter country code of the Google domain to search, for example us, gb, fr.

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

Two-letter language code of the results, for example en, fr.

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

Jobs fetched per search, in whole pages of 10 (rounded up to a multiple of 10). Between 10 and 100.

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

Skip jobs this feed already returned in the last 30 days. Skipped jobs are not charged.

## `feedName` (type: `string`):

Name of the memory of seen jobs used by "Only jobs not seen before". Use one name per recurring monitoring task. Lowercase letters, digits and dashes.

## Actor input object example

```json
{
  "searches": [
    {
      "query": "software engineer",
      "location": "New York, New York, United States"
    }
  ],
  "country": "us",
  "language": "en",
  "maxJobsPerSearch": 10,
  "onlyNewJobs": false,
  "feedName": "default"
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `results` (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 = {
    "searches": [
        {
            "query": "software engineer",
            "location": "New York, New York, United States"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("opendata-apis/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 = { "searches": [{
            "query": "software engineer",
            "location": "New York, New York, United States",
        }] }

# Run the Actor and wait for it to finish
run = client.actor("opendata-apis/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 '{
  "searches": [
    {
      "query": "software engineer",
      "location": "New York, New York, United States"
    }
  ]
}' |
apify call opendata-apis/google-jobs-scraper --silent --output-dataset

```

## MCP server setup

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