John Cole

Jul 09, 2026 • 3 min read

How to Backfill a Job Board with Google Jobs Data

Launch with real inventory: structured job listings at $0.013 each, by API or MCP

How to Backfill a Job Board with Google Jobs Data

Job boards die empty. Before anyone posts a listing or searches your site, you need inventory: real, current job postings in your niche. Most builders either scrape one board (and inherit its gaps) or pay for an enterprise feed (and inherit its invoice). There is a third option that costs about a penny per listing.

[[I

MG1]]

Use Google Jobs as your source

Google Jobs is already the aggregator. It indexes LinkedIn, Indeed, ZipRecruiter, Snagajob, company career pages, and hundreds of niche boards, then deduplicates everything into one feed. The Google Jobs Scraper API - Pay Per Result turns that feed into structured JSON: one row per listing with title, company, location, full description, qualifications, benefits, apply links, and posting metadata.

Pricing is flat per result: $13.00 per 1,000 listings, which is $0.013 per job. A 5,000-listing backfill runs about $65, with no subscription or monthly rental.

The backfill workflow

One call per niche and metro. This input pulls 500 software engineering listings for Austin and drops anything from sources you already carry:

{
 "query": "Software Engineer",
 "location": "Austin, TX",
 "num_results": 500,
 "via_filter_list": ["Indeed", "ZipRecruiter"]
}

The via_filter_list parameter is the piece built for board operators. Every listing carries a via field naming its source board, and the filter drops sources at the API level, before they count against your bill. The company_filter_list parameter does the same for employers.

From dataset to your database

The Python client gets you from a query to rows in about a dozen lines:

from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor(
 "johnvc/google-jobs-scraper---pay-per-result"
).call(run_input={
 "query": "Registered Nurse",
 "location": "Remote",
 "num_results": 200,
})

for job in client.dataset(run.default_dataset_id).iterate_items():
 print(job["title"], job["company_name"], job["via"])

[[I

MG2]]

Or skip the code: run it from Claude via MCP

The Actor is MCP compatible. Add the server to your MCP client config and your agent can pull listings on demand:

https://mcp.apify.com/?actors=johnvc/google-jobs-scraper---pay-per-result

Then ask in plain language: find remote registered nurse roles, exclude Indeed, return 50 as a table. There are ready-made tasks for the common cases: backfill a job board, data scientist jobs in New York, remote nursing jobs, and export to CSV.

Keeping the board fresh

A backfill gets you to launch. After that, save your queries as tasks and put them on an Apify Schedule: daily runs append new listings to a named dataset, and your importer picks up the delta. Because billing is per result, a quiet niche costs almost nothing to keep current.

FAQ

How is this scraper different from the standard Google Jobs scraper?

Same engine, different billing. The standard version bills per event; this one bills a flat rate per listing delivered, which makes backfill budgeting exact.

Does the scraper cover countries outside the US?

Yes. Set google_domain to the local domain (google.de, google.fr), put a city in location, and use job-title style queries. If a location returns nothing, the Actor retries with the city folded into the query.

Why does the scraper return some listings without salary?

Google only surfaces salary and schedule data for some listings. When present, it arrives in detected_extensions; when absent, that object is empty. The API reflects what Google Jobs shows.

Can I run the scraper on a schedule from my agent?

Yes. Use it as an MCP tool on demand, or create an Apify Schedule for a saved task and let it append fresh listings daily.

Join John on Peerlist!

Join amazing folks like John and thousands of other builders on Peerlist.

peerlist.io/

It’s available... this username is available! 😃

Claim your username before it's too late!

This username is already taken, you’re a little late.😐

0

0

0