# AI/ML Jobs Scraper (`lissome_dancer/ai-ml-jobs-scraper`) Actor

Scrape AI/ML jobs from 150+ companies via Greenhouse, Lever, RemoteOK, WeWorkRemotely, and YC. Extracts skills, frameworks, salary, and experience. Optional AI enrichment. Change detection and webhook alerts.

- **URL**: https://apify.com/lissome\_dancer/ai-ml-jobs-scraper.md
- **Developed by:** [Rohith S](https://apify.com/lissome_dancer) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## AI/ML Job Scraper

Scrape AI and ML job listings from 200+ companies including OpenAI, Anthropic, Google, Meta, Stripe, and Vercel. This machine learning job tracker scrapes Greenhouse, Lever, RemoteOK, WeWorkRemotely, YC Work at a Startup, Otta, and Ashby in parallel. Get structured data with skills, frameworks, salary ranges, experience levels, and optional AI-powered enrichment — all in one run.

***

### How to Scrape AI and ML Job Listings

1. **Configure inputs** — select sources, add keyword filters, enable AI enrichment
2. **Run the actor** — scrapes all sources in parallel, classifies every job
3. **Get results** — structured JSON with company, title, skills, salary, apply URL
4. **Set up alerts** — webhook notifications for new matching jobs

***

### What You Get

- **200+ companies** — OpenAI, Anthropic, Google, Meta, Stripe, Vercel, and 200+ more
- **7 sources** — Greenhouse, Lever, RemoteOK, WeWorkRemotely, YC, Otta, Ashby
- **AI-powered classification** — skills, AI frameworks, LLM technologies, experience level, visa sponsorship
- **Change detection** — track new, updated, and removed jobs between runs
- **Webhook alerts** — get notified on Slack/Discord when matching jobs appear
- **Analytics summary** — top companies, skills, salary ranges, remote percentage

***

### Sample Output

```json
{
  "hash": "a1b2c3d4...",
  "source": "greenhouse",
  "company": "Anthropic",
  "companyWebsite": "https://anthropic.com",
  "title": "Research Engineer, Interpretability",
  "department": "Research",
  "location": "San Francisco, CA",
  "remote": false,
  "salaryMin": 200000,
  "salaryMax": 350000,
  "skills": ["Python", "PyTorch", "JAX"],
  "aiFrameworks": ["PyTorch", "JAX"],
  "llmTech": ["LLM", "fine-tuning", "embeddings"],
  "experienceLevel": "senior",
  "aiRelevanceScore": 88,
  "changeType": "created",
  "applyUrl": "https://boards.greenhouse.io/anthropic/jobs/12345"
}
```

***

### AI Job Market Data and Analytics

Every run generates an analytics summary stored in the key-value store:

```json
{
  "totalJobs": 1247,
  "topCompanies": [
    { "name": "OpenAI", "count": 45 },
    { "name": "Anthropic", "count": 32 },
    { "name": "Google", "count": 28 }
  ],
  "topSkills": [
    { "skill": "Python", "count": 890 },
    { "skill": "PyTorch", "count": 567 },
    { "skill": "TensorFlow", "count": 345 }
  ],
  "salaryRanges": { "min": 80000, "max": 450000, "median": 185000 },
  "remotePercentage": 62
}
```

***

### Track Machine Learning Engineer Salaries

The actor detects salary ranges from job descriptions and normalizes them to USD. Filter by minimum salary to find high-paying roles:

```json
{
  "alertMinSalary": 200000,
  "sources": ["greenhouse", "lever"],
  "webhookUrl": "https://hooks.slack.com/services/..."
}
```

***

### How Much Does It Cost?

**Pay per event pricing:**

| What You Pay For | Price |
|------------------|-------|
| **Per 1,000 jobs scraped** | $1.00 |
| **Per 1,000 AI-enriched jobs** | $2.00 |
| **Actor start** | $0.05 (infrequent) |

**Example:** Scraping 500 jobs with AI enrichment costs ~$1.50 total.

**Free tier includes:** 100 jobs, 2 sources (Greenhouse + RemoteOK), no AI enrichment.

***

### Input Configuration

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `sources` | `string[]` | All 5 | Which job boards to scrape |
| `keywords` | `string[]` | `[]` | Filter by keywords (e.g., "Python", "LLM") |
| `companies` | `string[]` | `[]` | Filter by company name |
| `classifyWithAI` | `boolean` | `false` | Enable LLM enrichment |
| `classificationMode` | `string` | `"hybrid"` | `deterministic`, `hybrid`, or `ai` |
| `tier` | `string` | `"starter"` | `free`, `starter`, `pro`, or `enterprise` |
| `maxItems` | `integer` | `1000` | Max jobs per run |
| `detectChanges` | `boolean` | `true` | Track changes between runs |
| `webhookUrl` | `string` | `""` | Slack/Discord webhook for alerts |

***

### Classification Modes

| Mode | API Calls | Speed | Best For |
|------|-----------|-------|----------|
| **Deterministic** | 0 | Fast | High-frequency scheduled runs |
| **Hybrid** | ~20-40% of jobs | Medium | Most use cases (recommended) |
| **AI** | Every job | Slow | Deep market analysis |

***

### What Data Gets Classified

- **Skills** — Python, TypeScript, PyTorch, TensorFlow, etc.
- **AI Frameworks** — PyTorch, JAX, Hugging Face, LangChain, etc.
- **LLM Technologies** — GPT, Claude, Llama, fine-tuning, RAG, etc.
- **Experience Level** — entry, mid, senior, lead, principal
- **Salary Range** — min/max in USD
- **Remote Status** — fully remote, hybrid, on-site
- **Visa Sponsorship** — detected from job descriptions

***

### Webhook Alerts

Set `webhookUrl` to get notified when new jobs match your criteria:

```json
{
  "sources": ["greenhouse", "lever"],
  "keywords": ["Python", "LLM"],
  "alertKeywords": ["senior", "staff"],
  "alertMinSalary": 200000,
  "webhookUrl": "https://hooks.slack.com/services/..."
}
```

**Supported:** Slack, Discord, or any HTTP endpoint accepting JSON.

***

### Use Cases

- **Job seekers** — find AI/ML roles across all major companies in one search
- **Recruiters** — monitor competitor hiring and track open positions
- **Market researchers** — analyze AI job trends, salary benchmarks, skill demand
- **AI teams** — track which companies are hiring for specific AI specializations

***

### Scheduling

Schedule recurring runs to track the AI job market:

| Use Case | Frequency | Tier |
|----------|-----------|------|
| Job seeker | Every 6 hours | Starter |
| Recruiter | Every 12 hours | Pro |
| Market researcher | Weekly | Enterprise |
| Real-time alerts | Every 1 hour | Enterprise |

***

### API Access

Every run generates a dataset accessible via the Apify API:

```bash
## Get results
curl "https://api.apify.com/v2/datasets/{DATASET_ID}/items?format=json"

## Get analytics
curl "https://api.apify.com/v2/key-value-stores/{KV_ID}/records/ANALYTICS"
```

***

### Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `GROQ_API_KEY` | Optional | For AI enrichment (fast, free tier available) |
| `OPENROUTER_API_KEY` | Optional | For AI enrichment (flexible model selection) |

***

### FAQ

**Is this legal?**
Yes. This actor only accesses publicly available job postings from official APIs (Greenhouse, Lever) and public job boards. No authentication or login is required.

**How fresh is the data?**
Each run scrapes the latest listings from all sources. For real-time tracking, schedule runs every 1-6 hours.

**Can I add my own companies?**
Yes. Use `customGreenhouseTokens` and `customLeverSlugs` to add companies not in the built-in list.

**What if a source fails?**
One source failing doesn't crash the actor. You'll get a warning in the logs and results from the remaining sources.

**How does AI enrichment work?**
When enabled, the actor sends each job description to an LLM (Groq or OpenRouter) which extracts structured data: skills, frameworks, experience level, salary normalization, and more. This adds ~$0.002 per job.

***

### Changelog

- **v2.1.0** (2026-09): Output schema, dataset schema, PPE monetization, SEO optimization
- **v2.0.0** (2026-09): AI enrichment, change detection, webhook alerts, batch processing
- **v1.0.0** (2026-08): Initial release with 5 sources, deterministic classification

***

### License

MIT

# Actor input Schema

## `sources` (type: `array`):

Which job boards to scrape. All five are enabled by default.

## `keywords` (type: `array`):

Only include jobs containing at least one of these keywords. Leave empty to include all AI-relevant jobs.

## `companies` (type: `array`):

Only include jobs from these companies (partial match). Leave empty to include all companies.

## `parseAllResults` (type: `boolean`):

Ignore the max output limit and scrape all available jobs from the selected sources.

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

Maximum number of job records to output per run. Ignored if 'Parse all results' is enabled.

## `classifyWithAI` (type: `boolean`):

Use an LLM to enrich jobs with structured metadata (skills, frameworks, experience level). Requires GROQ\_API\_KEY or OPENROUTER\_API\_KEY.

## `classificationMode` (type: `string`):

How to classify jobs. Deterministic is free and fast. Hybrid uses LLM only for uncertain jobs. AI classifies every job with LLM.

## `llmProvider` (type: `string`):

Which LLM to use for AI enrichment. Set the corresponding API key in environment variables.

## `tier` (type: `string`):

Controls output limits and features. Free tier includes 100 jobs from 2 sources.

## `detectChanges` (type: `boolean`):

Compare this run against the previous run to detect new, updated, and removed jobs.

## `proxy` (type: `boolean`):

Route requests through Apify Proxy to avoid rate limits. Recommended for large runs.

## `customGreenhouseTokens` (type: `array`):

Add custom Greenhouse company board tokens. Find tokens at boards.greenhouse.io/{token}.

## `customLeverSlugs` (type: `array`):

Add custom Lever company slugs. Find slugs at lever.co/{slug}.

## `alertKeywords` (type: `array`):

Send webhook when a new job matches these keywords. Requires webhook URL.

## `alertMinSalary` (type: `integer`):

Send webhook when a new job has salary above this threshold. Set to 0 to disable.

## `webhookUrl` (type: `string`):

Slack, Discord, or custom webhook URL for job alerts. Leave empty to disable.

## Actor input object example

```json
{
  "sources": [
    "greenhouse",
    "lever",
    "remoteok",
    "weworkremotely",
    "yc"
  ],
  "keywords": [
    "Python",
    "PyTorch",
    "LLM",
    "machine learning"
  ],
  "companies": [
    "OpenAI",
    "Anthropic",
    "Google",
    "Meta"
  ],
  "parseAllResults": false,
  "maxItems": 1000,
  "classifyWithAI": false,
  "classificationMode": "hybrid",
  "llmProvider": "groq",
  "tier": "starter",
  "detectChanges": true,
  "proxy": false,
  "customGreenhouseTokens": [],
  "customLeverSlugs": [],
  "alertKeywords": [],
  "alertMinSalary": 0,
  "webhookUrl": ""
}
```

# 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 = {
    "sources": [
        "greenhouse",
        "lever",
        "remoteok",
        "weworkremotely",
        "yc"
    ],
    "keywords": [
        "Python",
        "PyTorch",
        "LLM",
        "machine learning"
    ],
    "companies": [
        "OpenAI",
        "Anthropic",
        "Google",
        "Meta"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lissome_dancer/ai-ml-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 = {
    "sources": [
        "greenhouse",
        "lever",
        "remoteok",
        "weworkremotely",
        "yc",
    ],
    "keywords": [
        "Python",
        "PyTorch",
        "LLM",
        "machine learning",
    ],
    "companies": [
        "OpenAI",
        "Anthropic",
        "Google",
        "Meta",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("lissome_dancer/ai-ml-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 '{
  "sources": [
    "greenhouse",
    "lever",
    "remoteok",
    "weworkremotely",
    "yc"
  ],
  "keywords": [
    "Python",
    "PyTorch",
    "LLM",
    "machine learning"
  ],
  "companies": [
    "OpenAI",
    "Anthropic",
    "Google",
    "Meta"
  ]
}' |
apify call lissome_dancer/ai-ml-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lissome_dancer/ai-ml-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/4KLrftsKgH63Tn9bY/builds/v3jxB98h5dZZTCi1B/openapi.json
