Career Site Scraper avatar

Career Site Scraper

Pricing

Pay per event

Go to Apify Store
Career Site Scraper

Career Site Scraper

Export normalized public Greenhouse and Lever career site jobs for recruiting feeds, monitoring, and analysis.

Pricing

Pay per event

Rating

0.0

(0)

Developer

Stas Persiianenko

Stas Persiianenko

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 days ago

Last modified

Categories

Share

Export normalized public Greenhouse and Lever career site jobs into one stable dataset.

Give the Actor one or more employer career-board URLs and receive job identity, title, company, location, team, employment type, timestamps, description, job URL, application URL, and native source identifiers.

The Actor is designed for recurring recruiting feeds, job monitoring, workforce research, and downstream APIs.

It uses the public Greenhouse and Lever job-board APIs directly.

No login, browser, or proxy is required.

What does Career Site Scraper do?

Career Site Scraper:

  • accepts public Greenhouse board URLs;
  • accepts public Lever site URLs;
  • detects the ATS from each URL;
  • fetches the current public jobs;
  • normalizes both ATS formats into one schema;
  • deduplicates jobs by ATS and native source ID;
  • applies keyword, location, team, and employment-type filters;
  • limits output across all supplied boards;
  • saves jobs to the default Apify dataset;
  • returns direct job and application links.

This focused two-ATS contract is useful when a pipeline needs predictable job identity and consistent fields rather than broad web crawling.

Who is it for?

Recruiting operations teams

Refresh employer job feeds on a schedule without maintaining separate Greenhouse and Lever clients.

Talent intelligence teams

Track hiring by company, location, or department and compare dataset snapshots over time.

Job boards and HR products

Import public employer postings into a normalized ingestion queue.

Sales and market researchers

Use openings as hiring signals for company research, territory planning, or account prioritization.

Developers and data engineers

Call one Actor API and receive the same output shape from two common ATS platforms.

Supported career sites

ATSAccepted URL examplesData route
Greenhousehttps://boards.greenhouse.io/airbnbPublic Greenhouse Boards API
Greenhousehttps://job-boards.greenhouse.io/airbnbPublic Greenhouse Boards API
Greenhousehttps://boards-api.greenhouse.io/v1/boards/airbnb/jobsPublic Greenhouse Boards API
Leverhttps://jobs.lever.co/veoPublic Lever postings API
Leverhttps://api.lever.co/v0/postings/veoPublic Lever postings API

The Actor does not claim to scrape arbitrary career-page software.

Use a supported public board URL, not a company's generic home page.

What job data can you extract?

FieldMeaning
recordIdStable ATS-prefixed identity such as greenhouse:123456
atsgreenhouse or lever
sourceIdNative ATS job identifier
sourceBoardBoard token or site handle
sourceUrlOriginal career-board URL from the input
titlePublished job title
companyBoard company name or supplied override
locationPublished location, when available
teamGreenhouse department or Lever team
employmentTypePublished commitment or employment type
workplaceTypeRemote, hybrid, or onsite value when available
publishedAtSource publication time when available
updatedAtSource update time when available
descriptionNormalized plain-text description when enabled
jobUrlHosted public job page
applicationUrlDirect application URL
scrapedAtTime the record was normalized

Missing optional source values are returned as null.

Get started

  1. Open the Actor input.
  2. Add one or more public Greenhouse or Lever career-board URLs.
  3. Optionally add a keyword or structured filters.
  4. Choose the maximum number of jobs.
  5. Click Start.
  6. Open the Jobs dataset view.
  7. Export the records as JSON, CSV, Excel, XML, or RSS.

The prefilled Airbnb Greenhouse URL is a working small-start example.

Input parameters

ParameterTypeDefaultDescription
startUrlsarrayrequiredOne to 50 Greenhouse or Lever board URLs
querystringemptyText required in searchable job fields
locationsstring arrayemptyKeep locations containing any supplied value
teamsstring arrayemptyKeep departments or teams containing any supplied value
employmentTypesstring arrayemptyKeep employment types containing any supplied value
maxItemsinteger1000Maximum jobs saved across every source
includeDescriptionbooleantrueInclude normalized plain-text descriptions

Filters are case-insensitive substring matches.

All active filters apply equally to Greenhouse and Lever records.

A source object may include companyName when the board handle is not the desired display name.

Example: search Airbnb engineering jobs

{
"startUrls": [
{ "url": "https://boards.greenhouse.io/airbnb" }
],
"query": "engineering",
"maxItems": 5,
"includeDescription": false
}

This input returned five current typed Greenhouse records in the final local test.

Example: export Palantir jobs in London

{
"startUrls": [
{
"url": "https://jobs.lever.co/palantir",
"companyName": "Palantir"
}
],
"locations": ["London"],
"maxItems": 5,
"includeDescription": false
}

This source-specific input returned five current Lever records in the final local test.

Example: build a recurring multi-ATS engineering feed

{
"startUrls": [
{ "url": "https://jobs.lever.co/veo", "companyName": "Veo" },
{ "url": "https://boards.greenhouse.io/airbnb" }
],
"teams": ["Engineering"],
"maxItems": 10,
"includeDescription": false
}

Schedule this input to refresh one normalized dataset from both ATS platforms.

The final local test returned ten records and exercised both Lever and Greenhouse.

Output example

A current local run produced this shape:

{
"recordId": "greenhouse:8074765",
"ats": "greenhouse",
"sourceId": "8074765",
"sourceBoard": "airbnb",
"sourceUrl": "https://boards.greenhouse.io/airbnb",
"title": "Engineering Manager, Cloud & Data Security",
"company": "Airbnb",
"location": "United States",
"team": "Software Engineering",
"employmentType": null,
"workplaceType": null,
"publishedAt": "2025-01-15T12:00:00.000Z",
"updatedAt": "2025-01-16T12:00:00.000Z",
"description": null,
"jobUrl": "https://boards.greenhouse.io/airbnb/jobs/8074765",
"applicationUrl": "https://boards.greenhouse.io/airbnb/jobs/8074765",
"scrapedAt": "2025-01-16T13:00:00.000Z"
}

Timestamps in the example illustrate the ISO format.

Live source timestamps and URLs vary with each posting.

How much does it cost to export career site jobs?

Career Site Scraper uses pay-per-event pricing:

  • one start event is charged when a run begins;
  • one item event is charged for each normalized job saved;
  • rejected, duplicate, failed, and filtered-out jobs do not incur an item charge.

The one-time start event costs $0.005 on every plan. Per-job prices are:

TierPrice per saved job
Free$0.0011201
Bronze$0.000974
Silver$0.00075972
Gold$0.0005844
Platinum$0.0003896
Diamond$0.00027272

Bronze-tier examples, including the start event:

Saved jobsTotal price
1$0.005974
10$0.01474
100$0.10240

Use a small maxItems value to test a new board before scheduling a larger feed.

Scheduling and change monitoring

Apify schedules can run the same input hourly, daily, or weekly.

For change monitoring:

  1. create a Task with stable source URLs and filters;
  2. schedule the Task;
  3. export or store each dataset snapshot;
  4. compare records by recordId;
  5. treat unseen IDs as new openings;
  6. treat missing IDs as potentially closed openings;
  7. compare updatedAt where the ATS supplies it.

The Actor returns snapshots.

It does not maintain historical state or send alerts itself.

Use webhooks, Make, Zapier, or your own data warehouse for downstream notifications.

Integration patterns

Recruiting feed

Send dataset items to an ATS ingestion service or internal search index.

Hiring-signal monitoring

Aggregate counts by company, team, and location, then compare scheduled snapshots.

Data warehouse refresh

Load JSON or CSV exports into BigQuery, Snowflake, PostgreSQL, or object storage.

Spreadsheet workflow

Connect the default dataset to Google Sheets through an Apify integration.

Webhook workflow

Trigger a webhook when the run succeeds, then fetch the default dataset by run ID.

Run with the Apify API using cURL

curl -X POST \
"https://api.apify.com/v2/acts/automation-lab~multi-ats-career-site-jobs-api/runs?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"startUrls": [{"url": "https://jobs.lever.co/veo", "companyName": "Veo"}],
"teams": ["Engineering"],
"maxItems": 10,
"includeDescription": false
}'

Poll the returned run ID or use the synchronous dataset endpoint for bounded workflows.

Run with JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/multi-ats-career-site-jobs-api').call({
startUrls: [{ url: 'https://boards.greenhouse.io/airbnb' }],
query: 'engineering',
maxItems: 25,
includeDescription: false,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Run with Python

import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("automation-lab/multi-ats-career-site-jobs-api").call(
run_input={
"startUrls": [{"url": "https://jobs.lever.co/palantir", "companyName": "Palantir"}],
"locations": ["London"],
"maxItems": 25,
"includeDescription": False,
}
)
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)

Use with MCP and AI agents

Add the Actor to Claude Code:

claude mcp add --transport http apify \
"https://mcp.apify.com?tools=automation-lab/multi-ats-career-site-jobs-api"

Claude Desktop

Use this MCP configuration:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=automation-lab/multi-ats-career-site-jobs-api"
}
}
}

Cursor

Add the same HTTP MCP server URL in Cursor Settings → MCP.

VS Code

Add the same HTTP MCP server URL to your VS Code MCP server configuration.

Example MCP prompts:

  • “Use the Career Site Scraper MCP tool to export engineering roles from this Airbnb Greenhouse board.”
  • “Call the Actor through MCP and find Palantir jobs in London from its Lever site.”
  • “Use MCP to build one normalized engineering feed from these Greenhouse and Lever URLs.”

Reliability and failure behavior

Requests use a 30-second timeout.

Transient HTTP statuses and network errors receive bounded retries with backoff.

Deterministic unsupported URLs and missing boards are not retried blindly.

If one source fails, other valid sources continue.

If every source fails, the run fails with a non-zero status and the source errors appear in logs.

A valid source with no matching jobs completes normally with an empty dataset.

No automatic browser, proxy, or residential fallback is enabled.

Limits and tips

  • Supply no more than 50 career-board URLs per run.
  • Set maxItems between 1 and 10,000.
  • Start small when testing an unfamiliar board.
  • Disable includeDescription when compact records are enough.
  • Use companyName for Lever handles that are not readable company names.
  • Use recordId as the stable snapshot comparison key.
  • Expect source fields to be null when the employer did not publish them.
  • Board APIs can change or rate-limit requests.
  • The Actor covers current public jobs, not expired-job history.
  • The Actor does not submit applications.

Responsible use and legality

This Actor accesses public job-board endpoints without login.

You are responsible for ensuring your collection and downstream use comply with applicable laws, contracts, privacy requirements, and source terms.

Do not use job data for unlawful discrimination, spam, impersonation, or deceptive recruiting.

Avoid republishing descriptions in ways that violate employer rights.

Collect only the fields needed for a legitimate purpose and apply appropriate retention controls.

Troubleshooting

Why is my URL rejected?

Confirm it is a public boards.greenhouse.io, job-boards.greenhouse.io, boards-api.greenhouse.io, jobs.lever.co, or api.lever.co URL.

Generic company career pages and unsupported ATS platforms fail closed.

Why did a board return HTTP 404?

The board handle may be misspelled, retired, private, or migrated to another ATS.

Open the supplied career-board URL and verify the current handle.

Why is the dataset empty?

The board may have no open jobs, or your keyword and structured filters may exclude every posting.

Remove filters and run with a small limit to inspect the source.

Why is a field null?

Greenhouse and Lever do not require employers to publish every normalized field.

Null values preserve this source truth rather than inventing data.

Why did only some sources finish?

The Actor isolates source failures.

Inspect logs for the failed URL while retaining useful records from successful boards.

Career Site Scraper is the focused choice for one normalized Greenhouse-and-Lever API contract.

FAQ

Does this Actor need an API key for Greenhouse or Lever?

No. It uses the public board APIs exposed for public postings.

Does it need a proxy?

No. The current implementation uses direct HTTP only and has no automatic proxy mode.

Can I process multiple companies?

Yes. Add up to 50 supported board URLs and use maxItems as the combined output limit.

Can I filter by several locations or teams?

Yes. A job is kept when its field contains any value in the corresponding filter list.

Filters across different fields are combined, so a job must satisfy each non-empty filter category.

Can I monitor new and removed jobs?

Yes, by scheduling snapshot runs and comparing the stable recordId field downstream.

The Actor itself does not persist history.

Are descriptions HTML?

No. When enabled, descriptions are normalized to plain text for consistent downstream use.

Are filtered jobs charged?

No item event is charged for filtered, duplicate, rejected, or failed records.

Can it scrape Workday or Ashby?

Not in this Actor.

Use the related Multi-ATS Company Jobs Scraper when those ATS platforms are required.