job-posting-intent

$npx mdskill add gooseworks-ai/goose-skills/job-posting-intent

Identify budget-ready companies hiring for your problem area.

  • Converts active hiring signals into qualified lead opportunities.
  • Uses Apify LinkedIn job search API to scan for relevant roles.
  • Scores signal strength based on budget allocation and timing.
  • Exports findings to Google Sheets with outreach angles and context.

SKILL.md

.github/skills/job-posting-intentView on GitHub ↗
---
name: job-posting-intent
version: 1.1.0
description: >
  Detect buying intent from job postings. When a company posts a job in your problem area,
  they've allocated budget and are actively thinking about the problem. This skill finds those
  companies, qualifies them, extracts personalization context, and outputs everything to a
  Google Sheet. Does NOT do outreach — just delivers qualified leads with reasoning.
tags: [lead-generation, outreach]
---

# Job Posting Intent Detection

Find companies that are hiring for roles related to the problem you solve. A job posting is a **budget signal** — the company has allocated money to solve a problem your product addresses.

Results are automatically exported to a **Google Sheet** with signal strength, decision-maker suggestions, outreach angles, and personalization context.

## Why This Works

When a company posts a job, they've:
- Allocated budget (headcount is expensive)
- Acknowledged the problem exists
- Started actively solving it

If your product helps solve that problem faster, cheaper, or better than a hire alone, the timing is perfect.

## Cost

**Apify Actor:** `harvestapi/linkedin-job-search` (pay-per-event)

| Component | Cost |
|-----------|------|
| Actor start (per run) | $0.001 |
| Per job result | $0.001 |
| Apify platform fee | +20% |

**Typical run costs:**
| Scenario | Titles | Jobs/title | Runs | Est. Cost |
|----------|--------|------------|------|-----------|
| Quick scan | 3 | 25 | 3 | ~$0.09 |
| Standard | 5 | 25 | 5 | ~$0.16 |
| Deep search | 5 | 100 | 5 | ~$0.60 |
| Multi-location | 5×3 | 25 | 15 | ~$0.47 |

Google Sheet creation is free (uses Rube/Composio integration).

Always run `--estimate-only` first to see the Apify cost before executing.

Track usage: https://console.apify.com/billing

## Setup

### 1. Apify API Token

```bash
# Get your token at https://console.apify.com/account/integrations
export APIFY_API_TOKEN="apify_api_YOUR_TOKEN_HERE"
```

### 2. Install dependencies

```bash
pip3 install requests
```

### 3. Rube/Composio (for Google Sheets)

Google Sheet creation uses Rube MCP with Composio. The token is preconfigured.
If it stops working, update the `RUBE_TOKEN` env var or the default in `search_jobs.py`.

## Usage

### Step 1: Define your ICP and target titles

Think about it this way: **"If a company is hiring for [role], it means they're investing in [problem area you solve]."**

Examples:
- GTM agency: "Growth Marketing Manager", "SDR Manager", "RevOps Engineer", "GTM Engineer"
- AI dev tools: "AI Engineer", "ML Ops Engineer", "Prompt Engineer", "LLM Engineer"
- Sales automation: "SDR", "BDR Manager", "Sales Ops", "Revenue Operations"

### Step 2: Estimate cost

```bash
python3 scripts/search_jobs.py \
  --titles "GTM Engineer,SDR Manager,Head of Demand Gen" \
  --locations "United States" \
  --max-per-title 25 \
  --estimate-only
```

### Step 3: Run the search

The script searches LinkedIn Jobs, groups results by company, qualifies leads, and creates a Google Sheet automatically.

```bash
# Standard search (creates Google Sheet)
python3 scripts/search_jobs.py \
  --titles "GTM Engineer,SDR Manager,RevOps Engineer" \
  --locations "United States" \
  --max-per-title 25

# Deep search with custom sheet name
python3 scripts/search_jobs.py \
  --titles "AI Engineer,ML Ops Engineer,Prompt Engineer" \
  --locations "United States" \
  --max-per-title 50 \
  --sheet-name "AI Hiring Signals - Feb 2026"

# Filter results to only relevant titles (LinkedIn search is fuzzy)
python3 scripts/search_jobs.py \
  --titles "GTM Engineer,Growth Marketing Manager,SDR Manager" \
  --locations "United States" \
  --relevance-keywords "gtm,growth,sdr,marketing,demand gen,revops"

# Also save raw JSON alongside the sheet
python3 scripts/search_jobs.py \
  --titles "GTM Engineer,SDR Manager" \
  --locations "United States" \
  --output results.json

# Skip Google Sheet, console + JSON only
python3 scripts/search_jobs.py \
  --titles "GTM Engineer" \
  --no-sheet --json
```

## What the Script Does

1. **Searches** LinkedIn Jobs for each title/location combination via Apify
2. **Groups** results by company (deduplicates)
3. **Computes signal strength** based on number of relevant postings + seniority
4. **Extracts personalization context** from job descriptions (tech stack, growth signals, pain points)
5. **Suggests decision-maker title** (one level above the hired role)
6. **Suggests outreach angle** (accelerate / replace / multiply the hire)
7. **Creates a Google Sheet** with all qualified leads
8. **Prints a console summary** of all companies found

## Options Reference

```
Required:
  --titles              Comma-separated job titles to search

Optional:
  --locations           Comma-separated locations (default: no filter)
  --max-per-title       Max jobs per title per location (default: 25)
  --posted-limit        Recency: 1h, 24h, week, month (default: week)
  --output, -o          Also save raw JSON to this file path
  --json                Print JSON output to console
  --estimate-only       Show cost estimate without running
  --no-sheet            Skip Google Sheet creation
  --sheet-name          Custom Google Sheet title (default: "Job Posting Intent Signals - {date}")
  --relevance-keywords  Comma-separated keywords to filter truly relevant postings
```

## Google Sheet Columns

| Column | Description |
|--------|-------------|
| Signal | HIGH / MEDIUM / LOW based on # postings + seniority |
| Company | Company name |
| Employees | Employee count |
| Industry | Company industry |
| Website | Company website |
| LinkedIn | Company LinkedIn URL |
| # Postings | Number of relevant job postings found |
| Job Titles | The actual job titles posted |
| Job URL | Link to the primary job posting |
| Location | Job location(s) |
| Decision Maker | Suggested title of person to contact |
| Outreach Angle | Accelerate / Replace / Multiply the hire |
| Tech Stack | Technologies mentioned in job descriptions |
| Growth Signals | Growth indicators (first hire, scaling, series stage) |
| Pain Points | Pain indicators (automate, optimize, manual processes) |
| Description | Company description snippet |

## AI Agent Integration

When using this skill as an agent, the typical flow is:

1. User describes their product and the types of roles that signal intent
2. Agent runs `--estimate-only` and confirms cost with user
3. Agent runs the search (Google Sheet is created automatically)
4. Agent shares the Google Sheet link with the user
5. Agent provides a brief summary of top leads and why they're qualified

**Example prompt:**
> "Find companies hiring growth marketers and SDRs in the US this week. These are signals they need GTM help. We sell AI-powered GTM systems to Series A-C B2B SaaS companies with 20-200 employees."

The agent should NOT:
- Do any outreach
- Send any emails or messages
- Contact anyone

The agent SHOULD:
- Present cost estimate before running
- Run the search (sheet is created automatically)
- Share the Google Sheet link
- Provide a brief summary of the top leads with reasoning

## Outreach Angle Templates

The script auto-assigns an angle based on job posting context:

**"Accelerate while you hire"** — Best when: posting is recent, role is junior/mid
> They're looking for someone to do X. Your product can deliver X outcomes while they ramp the hire.

**"Replace the hire"** — Best when: small company, "first hire" signals, building from scratch
> They want the output of a [role] but may not need a full-time person if they use your product.

**"Multiply the hire"** — Best when: company is clearly scaling, multiple related roles
> When their new hire starts, your product makes them 10x more effective from day one.

## Troubleshooting

### "No jobs found"
- Try broader titles (e.g., "marketing" instead of "demand generation specialist")
- Extend the time window: `--posted-limit month`
- Remove location filter to search globally

### "Too many irrelevant results"
- Use `--relevance-keywords` to filter by title keywords
- LinkedIn's search is fuzzy — the grouping and qualification step helps filter

### "Google Sheet creation failed"
- Check that Rube MCP is accessible (the token may have expired)
- Use `--no-sheet --json --output results.json` to save results without a sheet
- You can create the sheet later with `scripts/create_sheet_mcp.py`

### High cost estimate
- Reduce `--max-per-title` (25 is usually enough)
- Search fewer titles
- Use `--posted-limit 24h` for a quick daily scan

## Links

- [Apify LinkedIn Job Search Actor](https://apify.com/harvestapi/linkedin-job-search)
- [Apify API Token](https://console.apify.com/account/integrations)
- [Apify Billing Dashboard](https://console.apify.com/billing)

More from gooseworks-ai/goose-skills