---
name: champion-job-change-tracking
description: "Track when past champions change jobs, check if the new company fits your ICP, alert the right rep with context, and flag the old account for a new champion. Use when former champions who move to a new company are some of the warmest prospects you have, but most teams notice the move months later, after the new team has picked its tools."
---

# Track Champion Job Changes to Open New Accounts

Former champions who move to a new company are some of the warmest prospects you have, but most teams notice the move months later, after the new team has picked its tools.

## When to use this skill

- The user wants to set up or run this workflow: "Track Champion Job Changes to Open New Accounts".
- The user describes this problem: Former champions who move to a new company are some of the warmest prospects you have, but most teams notice the move months later, after the new team has picked its tools.

## At a glance

- Category: Outbound
- Difficulty: Intermediate
- Time saved: 3 hours per week. This figure is an estimate, not a measured result.

## Tools

Options separated by "or" are alternatives; use whichever the user already has.

- Clay
- HubSpot or Salesforce
- Apollo
- Slack
- Instantly or Smartlead

## Steps

1. Build the champion list from closed-won deals and active customers in HubSpot or Salesforce: the primary contact, deal owner, account, and LinkedIn URL for each
2. Upload the list to Clay monthly and re-enrich each person to get their current company and title, or use a Clay job change signal if you keep champions in a Clay table
3. Compare the current company domain to the domain stored in the CRM and continue only when it changed
4. Enrich the new company, check it against your ICP, and look it up in the CRM to see whether it is already a customer or an open opportunity
5. For ICP fits, create the contact at the new company, assign it to the territory owner, post a Slack message with the shared history (which deal they championed and when), and add them to a short Instantly or Smartlead sequence written for past customers
6. Open a task on the old account for the account manager to find a new champion, since the departure can put the renewal at risk

## Template outline

Field names, thresholds, and message text are starting points to adapt.

~~~text
Clay Workflow (CSV trigger, monthly champion export):
1. Input: first_name, last_name, linkedin_url, crm_company, crm_company_domain, deal_owner, championed_deal
2. Enrich person: current_company, current_domain, current_title
3. IF current_domain != crm_company_domain: continue
4. Enrich new company: headcount, industry, country
5. CRM lookup by current_domain: customer, open deal, or new
6. IF ICP fit AND not a customer:
   - Create contact at new company, owner = territory owner
   - Slack: "{{first_name}} {{last_name}} (championed {{championed_deal}}) is now {{current_title}} at {{current_company}}"
   - Sequence: past-customer intro, owner as sender
7. Old account: task for the AM, "Find a new champion"
Output: monthly list of moved champions at ICP companies, routed to an owner, plus a renewal task on the account they left
~~~

## Optional: build it with the Clay CLI

This builds champion tracking as a Clay workflow. A CSV trigger sends each past champion through person enrichment, a check of their new company, and a Slack alert to the deal owner. Each CSV row becomes one workflow run. The Clay CLI cannot create tables, so this build uses a workflow. If you already keep champions in a Clay table, the optional JobChange signal below is the other route.

Written against Clay CLI v1.3.1. Run these commands only in the user's own Clay workspace, logged in with their own account, after they confirm. Items marked VERIFY are config shapes the CLI help does not document; check them in the workspace before relying on them.

### Prerequisites

- Install the Clay CLI: Use version 1.3.1 or later, installed from Clay's own instructions. This page does not include an install command because the CLI reference it was written from does not list one. You also need jq, which the script uses to read the JSON the CLI prints.
- Log in to your workspace: Browser login is the default. Use the device flow on a headless machine. A static key in the CLAY_API_KEY environment variable also works. Workflow commands need the terracotta:cli scope, so an auth error that names it means your login cannot manage workflows.
  - Log in with a browser: `clay login`
  - Log in on a headless machine: `clay login --device`
  - Confirm who you are logged in as: `clay whoami`
- Pick the workspace to build in: The workflow is created in your active workspace. Switch first if you belong to more than one.
  - List workspaces: `clay workspaces list`
  - Show the active workspace: `clay workspaces current`
  - Switch workspace: `clay workspaces switch <workspaceId>`
- Find your action keys: Action package ids and keys are specific to your workspace. Save the catalog, search it for person enrichment from a LinkedIn URL, company enrichment, and Slack, then paste their ids into the top of the script. Skip "clay workflows actions test": it spends credits.
  - Save the action catalog: `clay workflows actions list > catalog.json`
  - Search the catalog: `grep -Eio '"[^"]*(enrich person|enrich company|linkedin|apollo|slack)[^"]*"' catalog.json | sort -u`
  - See an action's inputs and outputs: `clay workflows actions schema <packageId> <actionKey>`
- Export your champions and connect Slack: Export the primary contact from closed-won deals and active customers with the columns in the sample CSV, and connect Slack inside Clay.
- Optional: use a Clay job change signal instead: If you already keep champions in a Clay table, the CLI can attach a JobChange signal to it. It creates a new destination table unless you pass one. Replace the ids with your table, view, and LinkedIn URL field.
  - Create a job change signal on your champions table: `clay signals create --type JobChange --input '{"tableId":"t_...","viewId":"view_...","personIdentifier":{"fieldId":"f_...","pathAsFormula":"{{f_...}}"}}'`

### Workflow: Champion job change tracking

Trigger (csv_upload): You upload your champion list to the trigger, monthly or on your own schedule. Each header becomes a string input, and each row becomes one run once the workflow is published. VERIFY: The trigger type string "csv_upload" is inferred. The CLI help does not show how to create a CSV trigger.

Inputs (CSV headers):

- first_name: Champion first name (example: Jane)
- last_name: Champion last name (example: Doe)
- linkedin_url: LinkedIn profile URL (example: https://www.linkedin.com/in/...)
- crm_company: Company on the CRM record (example: Example Co)
- crm_company_domain: Domain on the CRM record (example: example.com)
- deal_owner: Rep who owned the deal (example: owner@yourdomain.com)
- championed_deal: Deal they championed (example: Example Co annual plan (2025))

1. Find current company and title (action): Re-enriches the person from their LinkedIn URL to get where they work now.
   - Inputs: linkedin_url
   - Outputs: current_company, current_domain, current_title
2. Check the new company (action): Enriches the new company so the alert shows whether it fits your ICP. Runs only when the domain changed.
   - Inputs: current_domain
   - Outputs: headcount, industry, country
   - VERIFY: The "domain changed" rule needs a run condition, which the CLI help does not document. Set it in the Clay UI, or compare domains in a spreadsheet before uploading.
3. Alert the owner in Slack (action): Posts the move to the deal owner with the shared history, for example: "Jane Doe, who championed the Example Co annual plan, is now VP Sales at a 200-person fintech company."
   - Inputs: first_name, last_name, current_title, current_company, headcount, industry, deal_owner, championed_deal
   - Outputs: Slack message

### Script: build-champion-moves.sh

Creates the workflow, trigger, and three steps, then pauses so you can map step inputs and the domain-changed condition. It validates the graph, offers one test run, and asks before publishing.

~~~bash
#!/usr/bin/env bash
# Builds the "Champion job change tracking" Clay workflow
# in YOUR Clay workspace, using YOUR Clay CLI login.
# Written against Clay CLI v1.3.1. Not run or tested by GTM Playbooks.
# Lines tagged VERIFY use a shape the CLI help does not document.
set -euo pipefail

# Copy these from catalog.json (see "Find your action keys").
PERSON_PACKAGE_ID=""  # Person enrichment from a LinkedIn URL
PERSON_ACTION_KEY=""
COMPANY_PACKAGE_ID="" # Company enrichment (headcount, industry)
COMPANY_ACTION_KEY=""
SLACK_PACKAGE_ID=""   # Slack: send message
SLACK_ACTION_KEY=""

# One input to test before real traffic. Use yourself or a teammate.
TEST_ROW='{"first_name":"","last_name":"","linkedin_url":"","crm_company":"","crm_company_domain":"","deal_owner":"","championed_deal":""}'

for v in PERSON_PACKAGE_ID PERSON_ACTION_KEY COMPANY_PACKAGE_ID COMPANY_ACTION_KEY SLACK_PACKAGE_ID SLACK_ACTION_KEY; do
  [[ -n "${!v}" ]] || { echo "Set $v at the top of this script." >&2; exit 1; }
done
command -v clay > /dev/null || { echo "Clay CLI not found on PATH." >&2; exit 1; }
command -v jq > /dev/null || { echo "jq is required to read CLI output." >&2; exit 1; }
clay whoami > /dev/null || { echo "Not logged in. Run: clay login" >&2; exit 1; }

# VERIFY: only "workflows create" documents an "id" field in its output.
read_id() {
  local id
  id=$(jq -r '.id // empty' "$1")
  [[ -n "$id" ]] || { echo "No id found in $1. Open it and adjust read_id." >&2; exit 1; }
  echo "$id"
}

mkdir -p clay-champion-moves
cd clay-champion-moves

echo "1/7 Create the workflow"
clay workflows create --name "Champion job change tracking" > workflow.json
WF_ID=$(read_id workflow.json)
WF_URL=$(jq -r '.url // empty' workflow.json)

echo "2/7 Add the CSV upload trigger"
# VERIFY: triggerType "csv_upload" is inferred; the help does not show it.
clay workflows triggers create "$WF_ID" --input '{"triggerType":"csv_upload"}' > trigger.json
TRG_ID=$(read_id trigger.json)

echo "3/7 Step 1: find current company and title"
# VERIFY: help shows nodeType and name only; actionPackageId and actionKey are a guess.
STEP1=$(jq -nc --arg p "$PERSON_PACKAGE_ID" --arg k "$PERSON_ACTION_KEY" '{nodeType: "tool", name: "Find current company and title", actionPackageId: $p, actionKey: $k}')
clay workflows nodes create "$WF_ID" --input "$STEP1" > step1.json
STEP1_ID=$(read_id step1.json)

echo "4/7 Step 2: check the new company"
# VERIFY: action fields inside "step" are inferred from the documented utility example.
STEP2=$(jq -nc --arg n "$STEP1_ID" --arg p "$COMPANY_PACKAGE_ID" --arg k "$COMPANY_ACTION_KEY" '{target: {type: "after-node", nodeId: $n}, step: {kind: "action", actionPackageId: $p, actionKey: $k}}')
clay workflows nodes insert "$WF_ID" --input "$STEP2" > step2.json
STEP2_ID=$(read_id step2.json)

echo "5/7 Step 3: alert the owner in slack"
# VERIFY: same inferred insert shape as step 2.
STEP3=$(jq -nc --arg n "$STEP2_ID" --arg p "$SLACK_PACKAGE_ID" --arg k "$SLACK_ACTION_KEY" '{target: {type: "after-node", nodeId: $n}, step: {kind: "action", actionPackageId: $p, actionKey: $k}}')
clay workflows nodes insert "$WF_ID" --input "$STEP3" > step3.json
clay workflows graph get "$WF_ID" --mode full > graph.json

echo "6/7 Map step inputs"
cat <<EOF

Step inputs are specific to your workspace. Map them before validating:
  Step 1 person:  linkedin_url
  Step 2 company: the current domain from step 1; add a run condition so it
                  only runs when that domain differs from crm_company_domain
  Step 3 Slack:   name, new title and company, headcount, industry,
                  deal_owner, and championed_deal
Map them in the Clay UI${WF_URL:+ at $WF_URL}, or per node with:
  clay workflows nodes get $WF_ID <nodeId>
  clay workflows nodes update $WF_ID <nodeId> --input node.json
graph.json in this folder shows the current nodes and edges.

EOF
read -r -p "Press Enter when inputs are mapped. "

echo "7/7 Validate, test once, publish"
clay workflows graph validate "$WF_ID"
clay workflows diagram "$WF_ID"

if jq -e 'all(.[]; . != "")' <<< "$TEST_ROW" > /dev/null; then
  read -r -p "Run TEST_ROW once? It can spend Clay credits and post to Slack. [y/N] " answer
  if [[ "$answer" == [yY] ]]; then
    clay workflows runs test "$WF_ID" --inputs "$TEST_ROW" > test-run.json
    echo "Saved test-run.json. Check each step with: clay workflows runs steps $WF_ID <runId>"
  fi
else
  echo "TEST_ROW is empty, skipping the test run."
fi

read -r -p "Publish the workflow now? [y/N] " answer
if [[ "$answer" == [yY] ]]; then
  clay workflows publish "$WF_ID" --name v1
fi

echo "Workflow $WF_ID, CSV upload trigger $TRG_ID. All responses are saved in $(pwd)."
~~~

### Champion CSV: champions.csv

~~~csv
first_name,last_name,linkedin_url,crm_company,crm_company_domain,deal_owner,championed_deal
Jane,Doe,https://www.linkedin.com/in/your-test-profile,Example Co,example.com,owner@yourdomain.com,Example Co annual plan (2025)
~~~

### Run it on your champion list

After publishing, upload the CSV to the trigger and start with a few rows. Each row is one run.

- Load the saved ids (run inside clay-champion-moves/): `WF_ID=$(jq -r '.id' workflow.json); TRG_ID=$(jq -r '.id' trigger.json)`
- Upload the CSV (this does not start runs): `clay workflows triggers csv upload "$TRG_ID" --file champions.csv`
- Run the first 5 rows (needs a published workflow, one run per row): `clay workflows triggers csv run "$TRG_ID" --limit 5`
- List runs: `clay workflows runs list "$WF_ID"`
- Inspect one run: `clay workflows runs get "$WF_ID" <runId>`
- See each step's output for that run: `clay workflows runs steps "$WF_ID" <runId>`

### Verify in the workspace

- The CSV trigger type "csv_upload" is inferred. If "triggers create" exits with code 2 (validation), check which trigger types your workspace accepts.
- The help documents "nodes create" with nodeType and name only. If it rejects actionPackageId and actionKey, create the node with a name only and pick the action in the Clay UI.
- The reference says action steps take actionPackageId and actionKey but shows only a utility example for "nodes insert", so the placement of those fields inside "step" is inferred.
- Only "workflows create" documents an id field in its response. The script reads .id from trigger and node responses too and stops if it is missing.
- Package ids and action keys differ by workspace and depend on which integrations you have connected. Copy them from your catalog; this page does not guess them.
- Step input mapping is dynamic per workspace. The CLI path is "nodes get" then "nodes update", where incomingEdges is a full replacement. The argument order for "nodes get" is inferred from "nodes update".
- The help does not say whether step 1 connects to the trigger automatically. "clay workflows graph validate" reports a disconnected graph.
- The JobChange signal input shape comes from the CLI help example. The table, view, and field ids are yours to fill in.
- "runs test" without --live is assumed to run the draft. The reference lists --live without describing it.
- Workflow runs can spend Clay credits and write to connected tools. Exit code 3 means re-run clay login, and exit code 4 means you are rate limited (wait for details.retryAfter).

## Guardrails

- Work only in the user's own accounts and workspaces, with their credentials.
- Confirm with the user before any step that writes to a CRM, sends email or messages, spends credits, or moves money.
- Treat every hours, cost, and threshold figure as a starting assumption and replace it with the user's numbers.
- Do not invent data, prices, or results. If a vendor price matters, check the vendor's current pricing page.

## Source

https://gtmplaybooks.io/playbooks/champion-job-change-tracking/
