# Leadership Change Tracker — New Exec Hires & Job Changes (`inovaflow/leadership-change-tracker`) Actor

New executive hires and job changes as buying signals: who just took which role at which company, where they came from, when it happened, and who to sell to. One row per change, merged across every outlet that reported it, with what is new since your last run. Dataset-only, MCP-ready.

- **URL**: https://apify.com/inovaflow/leadership-change-tracker.md
- **Developed by:** [inovaflow](https://apify.com/inovaflow) (community)
- **Categories:** Lead generation, News
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 leadership changes

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

## Leadership Change Tracker — New Exec Hires & Job Changes

**A new VP has ninety days to prove they were the right hire.** In those ninety days they re-examine every
tool, every agency and every vendor their predecessor picked — and they are the person who signs. That is
why "new executive hire" sits next to "just raised" at the top of every outbound playbook, and why the
advice is to reach out inside thirty days.

The problem is finding the moves. This Actor does: **who just took which senior role at which company**,
where they came from, when it happened, who to approach, and **what is new since your last run**.

***

### Who it is for

- **Outbound and SDR teams** — a daily or weekly feed of new CROs, CMOs, VPs of Sales and Heads of Data,
  with the opening line written for you.
- **AI / GTM agents** — one call, a flat dataset, no login and no key. `person`, `newTitle`, `company`,
  `domain`, `sellTo`, `buyingWindow`, `whyNow`, `signalScore` are all on the row.
- **Account teams** — be told the day your champion leaves, or the day a new decision-maker lands on one of
  your target accounts.
- **Recruiters** — an executive move is usually followed by a team build-out.
- **Investors and analysts** — leadership churn across a portfolio or a market, as data.

***

### What makes it different

| | A people scraper | This Actor |
| --- | --- | --- |
| Row shape | one row per profile | one row per **change** — person, role, company, when |
| Where it looks | one source | announcements **and** the company's own leadership page |
| Duplicates | five outlets, five rows | one row, with every source URL and a `mentions` count |
| Over time | nothing | `isNewSinceLastRun`, `replacedPerson` — the delta an agent acts on |
| Output | contact data | the signal: `sellTo`, `buyingWindow`, `whyNow`, a 0–100 score |
| Access | usually needs cookies or a login | nothing private, ever |

***

### What you get per change

```jsonc
{
  "person": "Nicole Bello",
  "newTitle": "Chief Revenue Officer",
  "company": "Dext",
  "domain": "dext.com",
  "seniority": "c-level",
  "department": "sales",
  "changeType": "appointed",
  "previousCompany": "Zillow",
  "previousTitle": "VP",
  "announcedDate": "2026-09-09",
  "effectiveDate": "2026-10-01",
  "daysSinceChange": 3,
  "signalScore": 93,
  "signalTags": ["new-cxo", "new-vp-sales", "budget-authority", "external-hire",
                 "announced-this-week", "widely-covered", "new-since-last-run"],
  "sellTo": ["Nicole Bello — Chief Revenue Officer", "Their direct reports (VPs and Heads of Sales)",
             "Chief of Staff / Executive Assistant (for the intro)", "Head of RevOps / Marketing Ops"],
  "buyingWindow": "Reach out now — inside the 30-day window when a new leader is still choosing their tools",
  "whyNow": "Nicole Bello joined Dext as Chief Revenue Officer 3 days ago, from Zillow — they bring their old stack with them and re-evaluate the new one.",
  "isNewSinceLastRun": true,
  "replacedPerson": "John Roe",
  "mentions": 4,
  "sourceUrls": ["https://…", "https://…"]
}
```

Three dataset views are built in: **Leadership changes**, **Outreach** and **New since last run**.

***

### Use it in three ways

**1 · Discover every change by title.** Name the roles whose new holder is a buyer for you:

```json
{ "titles": ["Chief Revenue Officer", "VP of Sales", "Head of Growth"], "daysBack": 30 }
```

Leave `titles` empty and it covers the whole executive bench.

**2 · Watch your target accounts.** Paste the companies and be told when anyone senior joins, is promoted
or leaves:

```json
{ "companies": ["gong.io", "ramp.com", "hubspot.com"], "seniority": ["c-level", "vp"] }
```

With domains it also reads each company's own leadership page — which is how it catches the VP hire that
never got a press release.

**3 · A scheduled feed of what changed.** Set a `watchId`, turn on `onlyNewSinceLastRun`, schedule it. The
first run stores who holds what; every run after it returns only the people who are new in a role, plus the
seats that changed hands.

***

### How the signal is built

- **Merge, then report.** One appointment is written up by the company, two trade outlets and a wire
  service, each wording it differently. They become one row with a `mentions` count and every source URL —
  and wide coverage is itself a signal.
- **Remember, then diff.** Each watch keeps a private memory of who holds which role at which company.
  That is what powers `isNewSinceLastRun` and `replacedPerson`: the change, not the roster.
- **Two sources, two kinds of move.** Announcements catch the moves that get written up; the company's own
  leadership page catches the quiet ones. A row says which found it.
- **Departures count too.** An empty seat means the interim owner is deciding now and the successor will
  re-evaluate every vendor. Turn them off with one switch if you only want arrivals.

***

### Chain it

| Then run | To get |
| --- | --- |
| **Email Finder & Verifier** | the new executive's work e-mail |
| **Decision-Maker Finder** | the rest of their leadership team |
| **Recently Funded Companies** | whether the hire followed a raise — two triggers beat one |
| **Ad Activity Tracker** | whether the new marketing leader has already turned the ad spend up |

***

### Notes

- No login, no cookies, no API key, and no other paid Actor is ever started.
- Everything read is public: announcements and the companies' own pages.
- A change with no person named ("Acme names new CFO") is still delivered — the seat moved, and that is the
  trigger. One switch filters those out.
- Company domains are confirmed from the company's own homepage, so a row can be enriched straight away.

### Pricing

Pay per event: you pay per delivered change. Duplicate reports of the same move and empty runs are never
charged. See `PRICING.md`.

# Actor input Schema

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

One per line: a domain (`gong.io`) or a company name (`Gong`). With a domain the company's own leadership page is read as well, which catches moves that never made the news.

## `titles` (type: `array`):

Roles whose new holder is a buyer for you, one per line — `Chief Revenue Officer`, `VP of Marketing`, `Head of Data`. Leave empty to cover the whole executive bench.

## `seniority` (type: `array`):

Keep only changes at these levels. Empty = C-level, VP, Director and Head (the levels with budget).

## `departments` (type: `array`):

Keep only changes in these functions. Empty = every function.

## `daysBack` (type: `integer`):

How far back to look. The outbound playbooks say a new VP should hear from you inside 30 days, so 30 is the default; widen it for a backfill.

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

Used in discovery mode only: words that must appear in the announcement — `fintech`, `healthcare`, `SaaS`. Leave empty for every sector.

## `locations` (type: `array`):

Used in discovery mode only: narrow to announcements that mention these places — `United Kingdom`, `Germany`, `New York`.

## `useAppointmentNews` (type: `boolean`):

Searches public appointment announcements — company press releases, trade press and wire services — bounded to your date window. This is the broad source; keep it on.

## `useLeadershipPages` (type: `boolean`):

Reads each watched company's own leadership / team page and compares it with the previous run. Most VP hires never get a press release, but the page changes — so this is where the quiet moves come from. Free, a few requests per company.

## `includeDepartures` (type: `boolean`):

Also report people leaving a senior seat. An empty chair is its own signal: the interim owner is deciding now and the successor will re-evaluate every vendor.

## `onlyNewSinceLastRun` (type: `boolean`):

Deliver only people this watch had not already seen in that role. Ideal for a schedule. The first run of a watch always returns everything as the baseline.

## `requirePerson` (type: `boolean`):

Drop announcements that name the role but not the person ("Acme names new CFO"). Off by default — an unnamed seat change is still worth knowing about.

## `maxChanges` (type: `integer`):

Cap on delivered rows (highest signal score first). Also caps what you pay.

## `watchId` (type: `string`):

Optional name for this watch, e.g. `target-accounts-emea`. Runs sharing a Watch ID share the memory of who held which role. Leave empty to derive it from the companies and filters.

## `maxQueries` (type: `integer`):

How many announcement queries to send. Each returns up to 100 headlines. In watchlist mode this also caps how many companies get their own query.

## `maxPagesPerSite` (type: `integer`):

How deep to go on each watched company's website when looking for its leadership page.

## `maxDomainLookups` (type: `integer`):

Announcements name the company but never link it, so the top rows get their domain confirmed from the company homepage (free, a few fast requests each). Set to 0 to skip it.

## `maxConcurrency` (type: `integer`):

Concurrent requests to announcement sources and company sites. Lower it if a site starts rate-limiting.

## `newsLanguage` (type: `string`):

Language edition of the announcement search, e.g. `en-US`, `de-DE`, `fr-FR`. Changes which outlets are covered.

## `newsCountry` (type: `string`):

Two-letter country edition of the announcement search, e.g. `US`, `GB`, `DE`, `IN`. Pair it with the matching language for strong local coverage.

## `proxyConfiguration` (type: `object`):

Optional. Everything here is a public page, so no proxy is needed — the Actor already falls back to Apify Proxy if a source rate-limits the run.

## Actor input object example

```json
{
  "companies": [
    "gong.io",
    "Ramp",
    "hubspot.com"
  ],
  "titles": [
    "Chief Revenue Officer",
    "VP of Sales"
  ],
  "seniority": [],
  "departments": [],
  "daysBack": 30,
  "keywords": [
    "fintech",
    "SaaS"
  ],
  "locations": [
    "United Kingdom"
  ],
  "useAppointmentNews": true,
  "useLeadershipPages": true,
  "includeDepartures": true,
  "onlyNewSinceLastRun": false,
  "requirePerson": false,
  "maxChanges": 200,
  "watchId": "target-accounts-emea",
  "maxQueries": 12,
  "maxPagesPerSite": 5,
  "maxDomainLookups": 60,
  "maxConcurrency": 6,
  "newsLanguage": "de-DE",
  "newsCountry": "GB",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `changes` (type: `string`):

One row per change: person, new title, company, seniority, department, when, and the signal score.

## `outreach` (type: `string`):

Who to sell to, the buying window, why now, where they came from and the announcement to reference.

## `newChanges` (type: `string`):

The delta: people new in a role since your previous run, and the seats that changed hands.

## `summary` (type: `string`):

Counts by seniority and department, what changed, signal-tag totals, per-source report and the watch id.

# 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 = {
    "daysBack": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("inovaflow/leadership-change-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 = { "daysBack": 30 }

# Run the Actor and wait for it to finish
run = client.actor("inovaflow/leadership-change-tracker").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 '{
  "daysBack": 30
}' |
apify call inovaflow/leadership-change-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,inovaflow/leadership-change-tracker"
        }
    }
}

```

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/SVStITjqZw3h1OiET/builds/yAbjT5rSNjOmkMdE7/openapi.json
