# Job Board Keyword Signal Scanner GTM Eng Finance Clay-Ready (`mambalabs/job-board-keyword-signal-scanner`) Actor

Scrapes Greenhouse, Lever, and Ashby for configurable role categories: GTM, Engineering, Finance, Ops, Executive, or Custom. Flat Clay-ready row per domain.

- **URL**: https://apify.com/mambalabs/job-board-keyword-signal-scanner.md
- **Developed by:** [Mamba Labs](https://apify.com/mambalabs) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $100.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## 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

## Job Board Keyword Signal Scanner

**Version: 0.2.0**

Actor 1 ([GTM Hiring Signal Scraper](https://apify.com/mambalabs/gtm-hiring-signal-scraper)) is scoped to GTM roles only. This actor does the same thing but lets you pick the category.

Choose GTM, Engineering, Finance, Operations, Executive, or pass your own keyword list. Same Greenhouse, Lever, and Ashby cascade. Same flat Clay-ready output. One row per domain.

---

### What's new in v0.2.0

- **Workday and Rippling support.** Both added to the ATS cascade. Enterprise targets that use Workday or Rippling are now detected. ats_platform now returns "workday" or "rippling" for these domains.
- **Change detection.** Pass previous_roles_detected from a prior run and get new_roles_detected, removed_roles_detected, and change_detected in the output. Turns a one-shot scrape into an outbound timing signal -- run on the same domain weekly and trigger outreach when new roles appear.
- **Pre-indexed fallback.** When the live cascade finds no ATS match, the actor falls back to a pre-indexed database covering 175k+ companies and 54 ATS platforms. enable_fallback defaults to true. Set to false for faster runs on large lists where you are confident about ATS coverage.
- **Ashby date fix.** most_recent_posting_date now populates correctly for Ashby domains. Previous limitation notice removed.

---

### When to use this vs Actor 1

Use **Actor 1** if you only need GTM hiring signals. It is purpose-built for that use case and runs at $0.07/result.

Use **this actor** if your Clay table targets a different ICP (engineering scale-up, finance hire, ops buildout) or if you want to combine multiple hiring categories in one call.

---

### Supported categories

Pass one or more in the `role_categories` input field:

- `GTM` - VP Sales, AE, SDR, RevOps, Head of Growth, CMO, CRO
- `Engineering` - VP Engineering, CTO, Software Engineer, Staff Engineer, Engineering Manager
- `Finance` - CFO, VP Finance, Controller, FP&A, Financial Analyst
- `Operations` - COO, VP Operations, Chief of Staff, Business Operations, Strategy and Operations
- `Executive` - CEO, President, Co-Founder, MD, General Manager, VP+
- `Custom` - pass your own keywords via `custom_keywords` field

---

### Input

| Field | Type | Required | Notes |
|---|---|---|---|
| `company_domain` | String | Yes | Bare domain, e.g. stripe.com |
| `role_categories` | Array | Yes | One or more categories from the list above. Defaults to GTM if empty. |
| `custom_keywords` | Array | No | Required if Custom is in role_categories. Array of keyword strings. |
| `previous_roles_detected` | String | No | Comma-separated matched roles from a prior run. Enables change detection output fields. |
| `previous_run_date` | String | No | ISO date of prior run. Echoed to output for traceability. |
| `enable_fallback` | Boolean | No | Default true. Set to false to skip the pre-indexed fallback layer. |

**Example input:**

```json
{
  "company_domain": "stripe.com",
  "role_categories": ["GTM", "Finance"]
}
````

**Custom keyword example:**

```json
{
  "company_domain": "stripe.com",
  "role_categories": ["Custom"],
  "custom_keywords": ["Partnerships", "Alliances", "Channel"]
}
```

***

### Output

One flat row per domain. Every field is always present. Null over missing keys.

| Field | Type | Description |
|---|---|---|
| `company_domain` | String | Echoed from input |
| `company_name` | String | Derived from ATS data |
| `linkedin_company_url` | String | If available from ATS |
| `hiring_signal` | Boolean | True if any role matched in selected categories |
| `ats_platform` | String | greenhouse / lever / ashby / workday / rippling / none |
| `matched_role_count` | Integer | Roles matched across all selected categories |
| `matched_roles_detected` | String | Comma-separated matched role titles |
| `top_matched_role` | String | Highest-tier role found |
| `most_recent_posting_date` | String | ISO date of most recent matched posting |
| `department_with_most_openings` | String | Department with highest open role count |
| `total_open_roles` | Integer | All open roles across all departments |
| `signal_strength` | String | high / medium / low |
| `categories_searched` | String | Comma-separated categories used, e.g. "GTM,Finance" |
| `roles_by_category` | String | Comma-separated category:role pairs, e.g. "GTM:VP Sales,Finance:CFO" |
| `career_page_url` | String | Direct URL to the career page found |
| `new_roles_detected` | String | Roles appearing in current run but not in previous\_roles\_detected. Null if no prior run provided. |
| `removed_roles_detected` | String | Roles in previous\_roles\_detected not found in current run. Null if no prior run provided. |
| `roles_added_count` | Integer | Count of new roles detected. Null if no prior run provided. |
| `change_detected` | Boolean | True if any new or removed roles found. Null if no prior run provided. |
| `previous_run_date` | String | Echoed from input. Null if not provided. |
| `fallback_used` | Boolean | True if pre-indexed fallback was called and returned data. |
| `fallback_source` | String | "fantastic-jobs" if fallback used, null otherwise. |
| `run_date` | String | ISO timestamp of run |

**signal\_strength logic:**

- High: 2 or more Tier 1 roles, or 5 or more total matched roles, posted within 30 days
- Medium: 1 Tier 1 role, or 2 to 4 matched roles, posted within 90 days
- Low: Tier 3 roles only, or postings older than 90 days

**Sample output:**

```json
{
  "company_domain": "stripe.com",
  "company_name": "Stripe",
  "linkedin_company_url": "https://www.linkedin.com/company/stripe",
  "hiring_signal": true,
  "ats_platform": "greenhouse",
  "matched_role_count": 4,
  "matched_roles_detected": "VP Sales, Account Executive, CFO, Financial Analyst",
  "top_matched_role": "VP Sales",
  "most_recent_posting_date": "2026-04-10",
  "department_with_most_openings": "Sales",
  "total_open_roles": 47,
  "signal_strength": "high",
  "categories_searched": "GTM,Finance",
  "roles_by_category": "GTM:VP Sales,GTM:Account Executive,Finance:CFO,Finance:Financial Analyst",
  "career_page_url": "https://boards.greenhouse.io/stripe",
  "run_date": "2026-04-14T20:00:00.000Z"
}
```

***

### Clay integration

Add this actor as an enrichment column in any Clay table that has a `domain` column.

1. Add column, select Apify, search for `job-board-keyword-signal-scanner`
2. Map `company_domain` to your domain column
3. Set `role_categories` to whichever categories match your ICP, e.g. `["Engineering"]`
4. Set a run condition: `domain` is not empty
5. Map output fields to new columns: `hiring_signal`, `signal_strength`, `matched_role_count`, `top_matched_role`
6. Use `signal_strength` as a filter column or ICP qualification gate

The output is a flat row with no nested objects. Every field maps directly to a Clay column with no transformation required.

***

### Pricing

$0.10 per result. Pay per event, no subscription.

If you only need GTM hiring signals, use [GTM Hiring Signal Scraper](https://apify.com/mambalabs/gtm-hiring-signal-scraper) at $0.07/result instead.

***

### Related actors

**[GTM Hiring Signal Scraper](https://apify.com/mambalabs/gtm-hiring-signal-scraper)** - $0.07/result
GTM-only hiring signals from Greenhouse, Lever, and Ashby. Use this if your ICP is purely GTM-focused.

**[GTM Tech Stack Signal Scraper](https://apify.com/mambalabs/gtm-tech-stack-signal-scraper)** - $0.07/result
Detects CRM, sequencer, and GTM tooling from a domain. Returns flat booleans: uses\_hubspot, uses\_salesforce, crm\_detected, seq\_tool\_detected.

**[GTM Signals Aggregator](https://apify.com/mambalabs/gtm-signals-aggregator)** - $0.12/result
Runs GTM Hiring Signal Scraper and GTM Tech Stack Signal Scraper in parallel and merges both into one Clay-ready row. Cheaper than running both separately ($0.14 combined vs $0.12 bundled).

***

### Known limitations

- Workday and Rippling detection relies on career page scraping. Slug mismatches may cause false negatives on some Workday domains. Coverage is approximately 60-70% for Workday (same as Actor 1 v0.2.0).
- Tools loaded behind authenticated career portals will not be detected.
- The pre-indexed fallback may return slightly stale data (up to a few days old) compared to live scraping.
- No proxy layer by default. Heavy batch runs on the same ATS domain may get rate-limited. Contact support via the Issues tab if this becomes a pattern.
- Custom keywords are all treated as Tier 2 signals by default. Signal strength scoring reflects this.

***

Built by [Mamba Labs](https://apify.com/mambalabs).

# Actor input Schema

## `company_domain` (type: `string`):

Bare domain to check, e.g. stripe.com

## `role_categories` (type: `array`):

One or more of: GTM, Engineering, Finance, Operations, Executive, Custom. Defaults to GTM if empty.

## `custom_keywords` (type: `array`):

Required if Custom is in role\_categories. Array of keyword strings. Prefix with T1: or T3: to set tier, otherwise defaults to Tier 2.

## `previous_roles_detected` (type: `string`):

Comma-separated matched role titles from a previous run of this actor. Used for change detection. Paste the matched\_roles\_detected value from a prior run. If empty, change detection is skipped.

## `previous_run_date` (type: `string`):

ISO date of the previous run (e.g. 2026-03-15). Optional. Used for traceability in change detection output.

## `enable_fallback` (type: `boolean`):

If true, calls a pre-indexed job database when the ATS cascade finds no match. Recovers coverage on domains that time out or use unsupported ATS platforms. Slightly increases run time for unmatched domains.

## Actor input object example

```json
{
  "role_categories": [
    "GTM"
  ],
  "enable_fallback": true
}
```

# 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("mambalabs/job-board-keyword-signal-scanner").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("mambalabs/job-board-keyword-signal-scanner").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 mambalabs/job-board-keyword-signal-scanner --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=mambalabs/job-board-keyword-signal-scanner",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Job Board Keyword Signal Scanner GTM Eng Finance Clay-Ready",
        "description": "Scrapes Greenhouse, Lever, and Ashby for configurable role categories: GTM, Engineering, Finance, Ops, Executive, or Custom. Flat Clay-ready row per domain.",
        "version": "0.0",
        "x-build-id": "P8dhbHdZLjG86xC99"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/mambalabs~job-board-keyword-signal-scanner/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-mambalabs-job-board-keyword-signal-scanner",
                "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/mambalabs~job-board-keyword-signal-scanner/runs": {
            "post": {
                "operationId": "runs-sync-mambalabs-job-board-keyword-signal-scanner",
                "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/mambalabs~job-board-keyword-signal-scanner/run-sync": {
            "post": {
                "operationId": "run-sync-mambalabs-job-board-keyword-signal-scanner",
                "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",
                "required": [
                    "company_domain"
                ],
                "properties": {
                    "company_domain": {
                        "title": "Company Domain",
                        "type": "string",
                        "description": "Bare domain to check, e.g. stripe.com"
                    },
                    "role_categories": {
                        "title": "Role Categories",
                        "type": "array",
                        "description": "One or more of: GTM, Engineering, Finance, Operations, Executive, Custom. Defaults to GTM if empty.",
                        "items": {
                            "type": "string"
                        },
                        "default": [
                            "GTM"
                        ]
                    },
                    "custom_keywords": {
                        "title": "Custom Keywords",
                        "type": "array",
                        "description": "Required if Custom is in role_categories. Array of keyword strings. Prefix with T1: or T3: to set tier, otherwise defaults to Tier 2.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "previous_roles_detected": {
                        "title": "Previous Roles Detected",
                        "type": "string",
                        "description": "Comma-separated matched role titles from a previous run of this actor. Used for change detection. Paste the matched_roles_detected value from a prior run. If empty, change detection is skipped."
                    },
                    "previous_run_date": {
                        "title": "Previous Run Date",
                        "type": "string",
                        "description": "ISO date of the previous run (e.g. 2026-03-15). Optional. Used for traceability in change detection output."
                    },
                    "enable_fallback": {
                        "title": "Enable Pre-Indexed Fallback",
                        "type": "boolean",
                        "description": "If true, calls a pre-indexed job database when the ATS cascade finds no match. Recovers coverage on domains that time out or use unsupported ATS platforms. Slightly increases run time for unmatched domains.",
                        "default": true
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
