# Substack Hiring Signal — Prime Sieve (`primesieve/substack-hiring-signal`) Actor

Pulls structured job postings from tech-hiring Substack newsletters via RSS. Extracts company, role, tech stack, salary, remote policy, apply link. De-duplicates across newsletters. Built by Prime Sieve — Remote Signal newsletter backend.

- **URL**: https://apify.com/primesieve/substack-hiring-signal.md
- **Developed by:** [Prime Sieve](https://apify.com/primesieve) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.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

## Substack Hiring Signal Scraper — Prime Sieve

**Structured tech jobs from tech-hiring Substack newsletters, in one feed.**

Curated by Prime Sieve. Built on top of the Remote Signal newsletter workflow.

### What it does

Give it a list of Substack newsletter RSS feeds (or use the curated defaults) and get back structured job postings with:

- **company** — extracted from title patterns ("Role at Company")
- **role** — job title
- **location** — when listed
- **seniority** — intern/junior/mid/senior/staff/principal/lead/director/head of/CTO
- **salary** — when disclosed (USD/EUR/GBP/€ / £, including "k" notation)
- **remote** — boolean (matches remote / WFH / anywhere / worldwide)
- **tech\_stack** — extracted languages/frameworks/cloud (Python, TS, React, AWS, K8s, etc.)
- **apply\_url** — direct link to the post
- **published\_at** — ISO timestamp

**De-duplicated** across newsletters (same job cross-posted = one row).

### Pricing

**$0.80 per 1,000 results** (pay-per-result). Compared to the only competitor:

| | Prime Sieve (this) | parseforge/tech-jobs-newsletter-substack |
|---|---|---|
| **Price / 1K results** | **$0.80** | $21.00 |
| Default curated feeds | ✅ 6 hiring newsletters | ❌ user supplies all |
| Structured fields (salary, tech stack, seniority) | ✅ | ❌ raw RSS |
| De-duplication | ✅ built-in | ❌ user-side |
| Remote filter | ✅ | ❌ |

90% cheaper + ships structure instead of raw RSS.

### Use cases

1. **Personal job search dashboard** — point at 5-10 niche newsletters, filter for "staff engineer" + "remote", get a daily feed
2. **Recruiting signal** — track which companies keep showing up across newsletters (hiring velocity)
3. **Newsletter curation** — feed your own Substack a weekly digest (this is how Remote Signal is built)
4. **Market intelligence** — track tech stack trends and salary bands across the newsletter ecosystem

### Input

```json
{
  "newsletters": [
    "https://remotesignal.substack.com/feed",
    "https://jobhired.substack.com/feed"
  ],
  "lookbackDays": 30,
  "maxItems": 100,
  "keyword": "python",
  "remoteOnly": false
}
```

All fields are optional. Defaults ship 5 curated tech-hiring newsletters.

### Output sample

```json
{
  "source": "Remote Signal",
  "title": "Senior Python Engineer at Stripe",
  "company": "Stripe",
  "role": "Senior Python Engineer",
  "location": null,
  "seniority": "Senior",
  "salary": "$160K-$220K",
  "remote": true,
  "tech_stack": ["python", "aws", "postgres"],
  "apply_url": "https://remotesignal.substack.com/p/...",
  "published_at": "2026-09-02T14:30:00.000Z",
  "body_excerpt": "We're hiring senior engineers to build out our payments infrastructure..."
}
```

### How it works

1. Fetches each RSS feed with rss-parser
2. Filters posts by date (lookbackDays)
3. Extracts structured fields via regex (title patterns for company/role, body patterns for salary/tech/remote/seniority)
4. De-duplicates by URL or (title + company) key
5. Pushes each result to the dataset with pay-per-result charging

### Limitations

- Field extraction is regex-based (no LLM). Works well for clear structured posts; misses niche formatting.
- Free RSS feeds only — no login, no paywall-bypass.
- Substack summaries only — full body text may be truncated if the author set RSS to excerpt-only.

### Roadmap

- LLM-based description parsing (GPT-4o-mini) for better field extraction
- Tech stack trend tracking across runs (weekly deltas)
- Browser extension that one-clicks "subscribe to this newsletter" for new sources

***

### 📬 Get Remote Tech Roles Weekly

Prime Sieve ships the [Remote Signal](https://remotesignal.substack.com) newsletter every Wednesday — 5 featured remote engineering roles + 10 quick hits, with tech stack and salary when disclosed. This Actor is the data pipeline behind it.

👉 **[Subscribe to Remote Signal](https://remotesignal.substack.com)**

### About Prime Sieve

Prime Sieve is the dev/tech brand by **PrimeSieveCoder**. We build small, sharp tools for solo developers — Apify actors, micro-SaaS, and the Remote Signal newsletter. Our other actors cover GitHub repo search, Apify Store scraping, music charts, and more.

Built in Indonesia. Run from anywhere.

# Actor input Schema

## `newsletters` (type: `array`):

List of Substack newsletter RSS feed URLs. Defaults to Prime Sieve curated tech-hiring newsletters.

## `lookbackDays` (type: `integer`):

Only include posts published within this many days.

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

Cap total results returned (de-duplicated).

## `keyword` (type: `string`):

Filter jobs by keyword in title or body (e.g. 'python', 'remote', 'staff engineer'). Case-insensitive.

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

If true, only return roles flagged as remote.

## Actor input object example

```json
{
  "newsletters": [
    "https://remotesignal.substack.com/feed",
    "https://jobhired.substack.com/feed",
    "https://remotejobsandyou.substack.com/feed",
    "https://thepragmaticengineer.substack.com/feed",
    "https://lennysnewsletter.substack.com/feed",
    "https://newsletter.pragmaticengineer.com/feed"
  ],
  "lookbackDays": 30,
  "maxItems": 100,
  "keyword": "",
  "remoteOnly": false
}
```

# Actor output Schema

## `source` (type: `string`):

Name of the Substack newsletter the job came from

## `title` (type: `string`):

Raw posting title

## `company` (type: `string`):

Company name extracted from the posting

## `role` (type: `string`):

Role part of the title (before ' at Company')

## `location` (type: `string`):

Location if mentioned

## `seniority` (type: `string`):

intern / junior / senior / staff / lead / director / vp / cto

## `salary` (type: `string`):

Salary range if disclosed (e.g. $120k-$150k)

## `remote` (type: `string`):

true when the posting mentions remote/WFH/anywhere

## `tech_stack` (type: `string`):

Detected technologies (python, react, go, aws, ...)

## `apply_url` (type: `string`):

Link to the original posting

## `published_at` (type: `string`):

ISO timestamp of the posting

## `body_excerpt` (type: `string`):

First 400 chars of the posting body

# 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("primesieve/substack-hiring-signal").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("primesieve/substack-hiring-signal").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 '{}' |
apify call primesieve/substack-hiring-signal --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,primesieve/substack-hiring-signal"
        }
    }
}
```

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/wSkUerlTaoWYEZGM0/builds/b6DJR9D8Q81SHLJty/openapi.json
