# AI Coding Job Tracker (`ianymu/ai-coding-job-tracker`) Actor

Scrapes HN 'Who is hiring?' threads (via Algolia) and RemoteOK for job postings mentioning AI coding tools — Claude Code, Cursor, Copilot, Aider, Cline, Windsurf and more. Emits a ranked, filterable feed with company, role, seniority, remote flag, tools mentioned, and salary range.

- **URL**: https://apify.com/ianymu/ai-coding-job-tracker.md
- **Developed by:** [Yanlong Mu](https://apify.com/ianymu) (community)
- **Categories:** AI, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

### What does AI Coding Job Tracker do?

**AI Coding Job Tracker** scans Hacker News' monthly "Who is hiring?" threads (via Algolia) and the RemoteOK JSON feed for engineering postings that mention **AI coding tools** — Claude Code, Cursor, GitHub Copilot, Aider, Cline, Windsurf, Continue, Codeium, Sourcegraph Cody, Devin, Replit Agent, v0, and Bolt. It deduplicates, normalizes seniority, extracts salary ranges where possible, and emits a structured, filterable feed.

The Actor exists because the AI-coding tooling labor market moved faster than the job-board taxonomy. There is no "Cursor" checkbox on RemoteOK. There is no "Claude Code" filter on HN. This Actor regex-matches the JD text so you can finally answer questions like *"who is hiring senior engineers who already use Claude Code?"*

Running on Apify means scheduling, CSV/JSON/Excel export, webhook integrations, and zero infra to maintain.

### Why use AI Coding Job Tracker?

- **Find AI-tool-friendly employers.** If a JD already lists "Cursor", "Claude Code", or "Aider", the engineering culture is at least one step ahead.
- **Track tool adoption over time.** Schedule daily; compare mention counts week-over-week to see which tools are gaining job-posting share.
- **Source for AI-coding-tool vendor outreach.** Vendors of AI coding tools can find companies whose engineers are already evangelizing competitors.
- **Build a personal job radar.** Filter by `seniority` and `remoteOnly` to keep only postings that match your search.

Companion to Ian Mu's [**verify-before-stop**](https://github.com/ianymu/claude-verify-before-stop) Claude Code completion hook — once you find the job, verify-before-stop keeps your agent's PRs honest.

### How to use AI Coding Job Tracker

1. Open the Actor on Apify and click **Try for free**.
2. Tune `aiToolFilter` — default is `["claude code", "cursor", "copilot", "aider", "cline"]`. Empty list = any AI coding tool match.
3. Optionally set `seniorityFilter` to `["senior", "staff", "principal"]` if you only want senior roles.
4. Toggle `remoteOnly` to true for fully-remote-only output.
5. Click **Save & Start**. A run takes 1-5 minutes.
6. Open the **Dataset** tab. Sort by `postedAt` or by the count of `aiToolsMentioned`.
7. Download as JSON / CSV / Excel, or wire a webhook into your CRM / spreadsheet.

### Input

The Actor accepts a JSON input with four optional fields:

```json
{
  "aiToolFilter": ["claude code", "cursor", "copilot", "aider", "cline"],
  "seniorityFilter": ["senior", "staff"],
  "remoteOnly": true,
  "maxResults": 100
}
````

| Field | Type | Default | Description |
|---|---|---|---|
| `aiToolFilter` | string\[] | 5 popular tools | Lowercased substring match. Empty = any AI coding tool hit. |
| `seniorityFilter` | string\[] | `[]` | Values: `junior`, `mid`, `senior`, `staff`, `principal`. |
| `remoteOnly` | boolean | false | Keep only postings flagged remote. |
| `maxResults` | integer | 100 | Hard cap across both sources. |

### Output

Each dataset row is a job posting. You can download the dataset in **JSON, HTML, CSV, or Excel**.

```json
{
  "source": "remoteok",
  "company": "Anthropic",
  "title": "Senior AI Engineer",
  "url": "https://remoteok.com/remote-jobs/12345",
  "location": "Remote / SF",
  "isRemote": true,
  "seniority": "senior",
  "aiToolsMentioned": ["claude code", "cursor"],
  "postedAt": "2026-05-15T14:30:00.000Z",
  "salaryRange": "$160k-$220k",
  "rawId": "12345"
}
```

### Data table

| Field | Type | Description |
|---|---|---|
| `source` | string | `remoteok` or `hn-hiring` |
| `company` | string | Company name (parsed from HN `Company \| Role \| ...` convention or RemoteOK) |
| `title` | string | Role title |
| `url` | link | Direct link to posting |
| `location` | string | Reported location or "Remote" |
| `isRemote` | boolean | Detected from text + source |
| `seniority` | string | One of: `junior`, `mid`, `senior`, `staff`, `principal`, `unspecified` |
| `aiToolsMentioned` | array | Canonicalized list (e.g. `["claude code", "cursor"]`) |
| `postedAt` | date | ISO 8601 timestamp |
| `salaryRange` | string | E.g. `$160k-$220k`, when extractable |
| `rawId` | string | Source-specific ID for dedup |
| `hnStoryId` | string | (HN only) parent "Who is hiring?" thread ID |

### Pricing / Cost estimation

**How much does it cost to scrape AI coding job postings?**

This is a lightweight HTTP-only Actor. A typical run with `maxResults=100` consumes a few minutes of compute, well within the free Apify tier ($5/month credits). RemoteOK and HN's Algolia API are both free and anonymous.

### Tips or Advanced options

- **Schedule daily** for a constantly-fresh dataset; integrate via webhook into Slack/Discord.
- **Combine sources.** Set `aiToolFilter: []` to widen the net to *any* AI coding tool mention and discover emerging tools.
- **Salary signal:** when `salaryRange` is non-null on `hn-hiring` rows, that's a strong "this poster takes hiring seriously" signal.
- **Future sources** (not yet implemented): YC Work at a Startup, AngelList Talent, LinkedIn. These require auth + browser automation and will arrive in a future version.
- **Pair with Ian Mu's [100-Actor portfolio](https://github.com/ianymu)** for cross-signal scraping.

### FAQ, disclaimers, and support

**Is this legal?** Yes. RemoteOK exposes a public anonymous JSON API; HN comments are public and Algolia provides an official API. No credentials, no scraping behind login walls.

**Why missing salary on most HN rows?** Most HN posts don't include explicit salary. The regex only fires on patterns like `$160k-$220k`.

**Why are some `company` values "(see post)"?** When a HN poster doesn't follow the `Company | Role | Location` convention, we cannot reliably split fields. The `url` always points to the original comment.

**Found a bug or want extra sources?** Open an issue on the Actor's Issues tab. Custom variants for vendor sales prospecting available — reach out via [github.com/ianymu](https://github.com/ianymu).

Part of **Ian Mu's 100-Apify-Actor portfolio**. Companion to [verify-before-stop](https://github.com/ianymu/claude-verify-before-stop).

# Actor input Schema

## `aiToolFilter` (type: `array`):

Only keep job postings whose description mentions at least one of these tools (case-insensitive). Set to an empty list to keep any posting that mentions any AI coding tool.

## `seniorityFilter` (type: `array`):

Only keep postings matching these seniorities. Values: junior, mid, senior, staff, principal. Empty = no filter.

## `remoteOnly` (type: `boolean`):

If true, drop postings that don't mention 'remote' / 'anywhere' / 'WFH'. RemoteOK posts are already all remote.

## `maxResults` (type: `integer`):

Stop after collecting this many matching jobs across all sources.

## Actor input object example

```json
{
  "aiToolFilter": [
    "claude code",
    "cursor",
    "copilot",
    "aider",
    "cline"
  ],
  "seniorityFilter": [],
  "remoteOnly": false,
  "maxResults": 100
}
```

# Actor output Schema

## `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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("ianymu/ai-coding-job-tracker").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("ianymu/ai-coding-job-tracker").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call ianymu/ai-coding-job-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=ianymu/ai-coding-job-tracker",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "AI Coding Job Tracker",
        "description": "Scrapes HN 'Who is hiring?' threads (via Algolia) and RemoteOK for job postings mentioning AI coding tools — Claude Code, Cursor, Copilot, Aider, Cline, Windsurf and more. Emits a ranked, filterable feed with company, role, seniority, remote flag, tools mentioned, and salary range.",
        "version": "0.0",
        "x-build-id": "hCTOW5B3Wbn9XN4J1"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/ianymu~ai-coding-job-tracker/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-ianymu-ai-coding-job-tracker",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/ianymu~ai-coding-job-tracker/runs": {
            "post": {
                "operationId": "runs-sync-ianymu-ai-coding-job-tracker",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/ianymu~ai-coding-job-tracker/run-sync": {
            "post": {
                "operationId": "run-sync-ianymu-ai-coding-job-tracker",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "aiToolFilter": {
                        "title": "AI tool keywords to match",
                        "type": "array",
                        "description": "Only keep job postings whose description mentions at least one of these tools (case-insensitive). Set to an empty list to keep any posting that mentions any AI coding tool.",
                        "default": [
                            "claude code",
                            "cursor",
                            "copilot",
                            "aider",
                            "cline"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "seniorityFilter": {
                        "title": "Seniority filter (optional)",
                        "type": "array",
                        "description": "Only keep postings matching these seniorities. Values: junior, mid, senior, staff, principal. Empty = no filter.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "remoteOnly": {
                        "title": "Remote only",
                        "type": "boolean",
                        "description": "If true, drop postings that don't mention 'remote' / 'anywhere' / 'WFH'. RemoteOK posts are already all remote.",
                        "default": false
                    },
                    "maxResults": {
                        "title": "Maximum results",
                        "minimum": 5,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Stop after collecting this many matching jobs across all sources.",
                        "default": 100
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
