This workflow corresponds to n8n.io template #18127 — we link there as the canonical source.
This workflow follows the Google Sheets → Slack recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "ZFMKPMpsEy2HP6e6",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Alumni Job-Change Radar",
"tags": [],
"nodes": [
{
"id": "3e64d4ab-2248-403f-bf0f-54543d968989",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
5440,
1392
],
"parameters": {
"width": 480,
"height": 896,
"content": "## Untitled workflow\n\n### How it works\n\n1. Triggers every week to check alumni status.\n2. Reads alumni profile URLs from a Google Sheet.\n3. Normalizes and verifies URLs with Coresignal.\n4. Checks for job changes and fetches employee details if profile is found.\n5. Sends notifications and logs results back to Google Sheets.\n\n### Setup steps\n\n- [ ] Set up Google Sheets API access for reading and writing data.\n- [ ] Configure Coresignal credentials for API access.\n- [ ] Connect Slack and set channel for alert notifications.\n\n### Customization\n\nYou can customize the batch size of alumni processed per run."
},
"typeVersion": 1
},
{
"id": "03c02396-4092-4726-afc3-72d6742121fc",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
6000,
1760
],
"parameters": {
"color": 7,
"width": 912,
"height": 272,
"content": "## Scheduled trigger and read data\n\nTriggered weekly to read alumni data from Google Sheets."
},
"typeVersion": 1
},
{
"id": "409b6453-cf43-4288-9576-5331946191b2",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
6960,
1776
],
"parameters": {
"color": 7,
"width": 672,
"height": 272,
"content": "## Normalize and verify URLs\n\nNormalizes URLs and verifies them using Coresignal API."
},
"typeVersion": 1
},
{
"id": "2a0314e5-be38-4664-84a8-3f6529c54537",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
7680,
1760
],
"parameters": {
"color": 7,
"width": 928,
"height": 368,
"content": "## Check and fetch profiles\n\nDetermines if profile exists, then fetches and processes data."
},
"typeVersion": 1
},
{
"id": "b7676f9a-b699-415d-9cb9-5e77a3549771",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
8672,
1696
],
"parameters": {
"color": 7,
"width": 464,
"height": 416,
"content": "## Send alerts and handle results\n\nSends notifications if job change is detected and handles logging."
},
"typeVersion": 1
},
{
"id": "22222388-6f32-438d-a5c1-f9e5a4579a63",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
7232,
1328
],
"parameters": {
"color": 7,
"width": 896,
"height": 400,
"content": "## Error handling and completion\n\nMarks no-match cases and completes the alumni loop process."
},
"typeVersion": 1
},
{
"id": "fb9e5ba3-2b9c-4c28-8e57-0a6000da779d",
"name": "When Weekly on Monday at 8am",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
6048,
1872
],
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtDay": [
1
],
"triggerAtHour": 8
}
]
}
},
"typeVersion": 1.2
},
{
"id": "6542d8c6-98f3-4cc2-8214-be5e4becc8e4",
"name": "Read Employees from Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
6288,
1872
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1VBboOirOjYRF_zPYaLnMhws7gHNZzzpAsac4aw6KAPQ/edit#gid=0",
"cachedResultName": "Employees"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1VBboOirOjYRF_zPYaLnMhws7gHNZzzpAsac4aw6KAPQ",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1VBboOirOjYRF_zPYaLnMhws7gHNZzzpAsac4aw6KAPQ/edit?usp=drivesdk",
"cachedResultName": "Testing_claude"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "0efdb9b4-423f-4e59-b817-f9776a0b250b",
"name": "Filter by Profile URL Presence",
"type": "n8n-nodes-base.filter",
"position": [
6528,
1872
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "c-url",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.profile_url }}",
"rightValue": ""
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "81452b6c-23a2-43e7-8657-551333bafe16",
"name": "Loop Over Alumni Profiles",
"type": "n8n-nodes-base.splitInBatches",
"position": [
6768,
1872
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "ebd5928d-032d-4d18-831f-ca0327bf4939",
"name": "Set Summary Field",
"type": "n8n-nodes-base.set",
"position": [
7328,
1504
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "s1",
"name": "summary",
"type": "string",
"value": "Alumni job-change check complete"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "8e6e1111-62a6-4143-8f11-16b71f67cc06",
"name": "Transform Profile URL",
"type": "n8n-nodes-base.code",
"position": [
6992,
1904
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Coresignal stores LinkedIn URLs as a lowercase keyword with no trailing slash.\n// An exact-term match will silently miss on casing, /mwlite/, trailing slashes,\n// tracking params or locale prefixes, so canonicalise to the slug first.\nconst raw = String($json.profile_url || '').trim();\nlet slug = '';\nconst m = raw.match(/linkedin\\.com\\/(?:[a-z]{2}\\/)?(?:mwlite\\/)?in\\/([^\\/?#]+)/i);\nif (m) slug = decodeURIComponent(m[1]).toLowerCase();\nconst normalized = slug ? 'https://www.linkedin.com/in/' + slug : '';\nreturn { json: Object.assign({}, $json, {\n profile_url_normalized: normalized,\n profile_url_slug: slug\n}) };\n"
},
"typeVersion": 2
},
{
"id": "0347b526-5aa9-44f2-8308-1044d7b66b85",
"name": "Search Employee in Coresignal",
"type": "n8n-nodes-coresignal-api.coresignal",
"onError": "continueRegularOutput",
"position": [
7232,
1904
],
"parameters": {
"esQuery": "={{ JSON.stringify({ query: { bool: { should: [ { term: { \"linkedin_url.exact\": $json.profile_url_normalized } }, { term: { \"linkedin_shorthand_names.exact\": $json.profile_url_slug } } ], minimum_should_match: 1 } } }) }}",
"operation": "search_es_dsl"
},
"credentials": {
"coresignalApi": {
"name": "<your credential>"
}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "bbca1d2f-b6fa-4fe5-8330-4aea719d527f",
"name": "Extract IDs from Response",
"type": "n8n-nodes-base.code",
"position": [
7472,
1904
],
"parameters": {
"jsCode": "// Employee search_es_dsl returns a bare array of IDs, which n8n explodes into one\n// item per number. Collapse back to a single item so the IF node sees one decision.\nconst items = $input.all();\nlet ids = [];\nfor (const it of items) {\n const j = it.json;\n if (typeof j === 'number' || (typeof j === 'string' && j.trim() !== '')) {\n ids.push(j);\n } else if (Array.isArray(j)) {\n ids = ids.concat(j);\n } else if (j && typeof j === 'object') {\n if (Array.isArray(j.body)) ids = ids.concat(j.body);\n else if (j.id) ids.push(j.id);\n }\n}\nids = ids.filter(v => typeof v === 'number' || (typeof v === 'string' && String(v).trim() !== ''));\nif (!ids.length) return [{ json: { employee_id: null, match_count: 0 } }];\nreturn [{ json: { employee_id: ids[0], match_count: ids.length } }];\n"
},
"typeVersion": 2
},
{
"id": "2aae6ad0-73ae-4937-b913-429881e3d198",
"name": "If Profile Found",
"type": "n8n-nodes-base.if",
"position": [
7744,
1904
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "c-found",
"operator": {
"type": "number",
"operation": "gt"
},
"leftValue": "={{ $json.match_count }}",
"rightValue": 0
}
]
}
},
"typeVersion": 2.3
},
{
"id": "e77a6c16-c710-413c-9f3c-2c3e21b800de",
"name": "Collect Employee Details",
"type": "n8n-nodes-coresignal-api.coresignal",
"onError": "continueRegularOutput",
"position": [
7984,
1872
],
"parameters": {
"employeeId": "={{ $json.employee_id }}"
},
"credentials": {
"coresignalApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "37ef2d5a-e9f9-4fa7-bdcd-54b55ad2c90f",
"name": "Determine Job Change",
"type": "n8n-nodes-base.code",
"position": [
8224,
1872
],
"parameters": {
"jsCode": "// ===== JOB-CHANGE DECISION =====\n// Alert rule: BOTH the active employer ID and the employer NAME must differ from the\n// last recorded snapshot. No freshness window, no rebrand heuristic, no denylist.\n//\n// Fix vs v1: the snapshot is only advanced when a full, trustworthy comparison was\n// possible. Previously every branch wrote the new employer id even when no alert was\n// sent, which turned a suppressed change into the new baseline and destroyed the signal.\n\nlet emp = $input.first().json;\nif (emp && emp.body !== undefined) emp = emp.body;\nif (Array.isArray(emp)) emp = emp[0] || {};\n\nconst row = $('Loop Over Alumni Profiles').first().json;\nconst nrm = $('Transform Profile URL').first().json;\n\n// Light normalisation only: case, punctuation, whitespace. Legal suffixes are NOT\n// stripped - \"Acme\" vs \"Acme Group\" counts as a genuine name difference.\nconst norm = (s) => String(s || '')\n .toLowerCase()\n .replace(/[.,'\"()]/g, '')\n .replace(/\\s+/g, ' ')\n .trim();\n\nconst exp = Array.isArray(emp.experience) ? emp.experience : [];\nconst active = exp.find(e => e && e.active_experience === 1) || null;\n\nconst newId = emp.active_experience_company_id || (active ? active.company_id : null);\nconst newName = (active && active.company_name) || '';\nconst newTitle = emp.active_experience_title || (active ? active.position_title : '') || '';\nconst newStart = (active && active.date_from_year)\n ? active.date_from_year + '-' + String(active.date_from_month || 1).padStart(2, '0')\n : '';\n\nconst prevId = String(row.current_company_id || '').trim();\nconst prevName = String(row.current_company_name || '').trim();\nconst alertedId = String(row.alerted_company_id || '').trim();\n\nlet monthsSinceStart = null;\nif (active && active.date_from_year) {\n const d = Date.UTC(active.date_from_year, (active.date_from_month || 1) - 1, 1);\n monthsSinceStart = Math.round((Date.now() - d) / (1000 * 60 * 60 * 24 * 30.44));\n}\n\nconst idDiffers = !!newId && !!prevId && String(newId) !== prevId;\nconst nameDiffers = !!newName && !!prevName && norm(newName) !== norm(prevName);\n\nlet status = 'unchanged';\nlet reason = '';\nlet changed = false;\nlet advance = true; // may this run overwrite the stored snapshot?\n\nif (!newId || !newName) {\n // The ID+name rule cannot be evaluated. Hold the existing snapshot rather than\n // overwrite it with partial data and lose the comparison point.\n status = (emp.is_working === 0) ? 'no_active_role' : 'insufficient_data';\n reason = 'missing employer ' + (!newId ? 'id' : 'name') +\n ' on the active experience - snapshot held, nothing overwritten';\n advance = false;\n} else if (!prevId || !prevName) {\n status = 'baseline_set';\n reason = 'first complete observation for this profile - snapshot stored, no alert';\n} else if (!idDiffers && !nameDiffers) {\n status = 'unchanged';\n} else if (idDiffers && nameDiffers) {\n if (String(newId) === alertedId) {\n status = 'already_alerted';\n reason = 'an alert was already sent for this employer';\n } else {\n status = 'job_changed';\n changed = true;\n }\n} else if (idDiffers) {\n status = 'same_employer_new_id';\n reason = 'employer id changed but the name is identical - duplicate or merged company record';\n} else {\n status = 'employer_renamed';\n reason = 'employer name changed but the id is identical - company rebrand';\n}\n\nconst now = new Date().toISOString();\n\nreturn [{ json: {\n profile_url: row.profile_url || '',\n profile_url_normalized: nrm.profile_url_normalized || '',\n full_name: emp.full_name || row.full_name || '',\n coresignal_employee_id: emp.id || row.coresignal_employee_id || '',\n current_company_id: advance ? String(newId) : prevId,\n current_company_name: advance ? newName : prevName,\n current_title: advance ? newTitle : (row.current_title || ''),\n current_company_start: advance ? newStart : (row.current_company_start || ''),\n previous_company_id: changed ? prevId : (row.previous_company_id || ''),\n previous_company_name: changed ? prevName : (row.previous_company_name || ''),\n status: status,\n suppressed_reason: reason,\n last_checked_at: now,\n last_change_detected_at: changed ? now : (row.last_change_detected_at || ''),\n alerted_company_id: changed ? String(newId) : alertedId,\n alerted_at: changed ? now : (row.alerted_at || ''),\n job_changed: changed,\n months_since_start: monthsSinceStart === null ? '' : monthsSinceStart,\n location: emp.location_full || '',\n company_linkedin_url: (active && active.company_linkedin_url) || ''\n} }];\n"
},
"typeVersion": 2
},
{
"id": "638253e2-1ccb-44c1-b92f-81acdc46e4a4",
"name": "If Job Changed",
"type": "n8n-nodes-base.if",
"position": [
8464,
1872
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "c-changed",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.job_changed }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.3
},
{
"id": "6760de85-5f4a-4329-b2ae-e6ed397749bd",
"name": "Post to Slack Channel",
"type": "n8n-nodes-base.slack",
"onError": "continueRegularOutput",
"position": [
8752,
1856
],
"parameters": {
"text": "=:arrows_counterclockwise: *Alumni job change*\n\n*{{ $json.full_name }}* has moved to a new employer.\n\n\u2022 *From:* {{ $json.previous_company_name || '(unknown)' }}\n\u2022 *To:* {{ $json.current_company_name }}\n\u2022 *Title:* {{ $json.current_title || '(not listed)' }}\n\u2022 *Started:* {{ $json.current_company_start || 'n/a' }}{{ $json.months_since_start === '' ? '' : ' (~' + $json.months_since_start + ' months ago)' }}\n\u2022 *Location:* {{ $json.location || 'n/a' }}\n\n<{{ $json.profile_url }}|LinkedIn profile>",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "id",
"value": "C0AST3Z3SBC"
},
"otherOptions": {
"mrkdwn": true,
"includeLinkToWorkflow": false
},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.3
},
{
"id": "05d7a045-03a1-443d-b6b3-0bb146715915",
"name": "Log No Match Found",
"type": "n8n-nodes-base.code",
"position": [
7920,
1520
],
"parameters": {
"jsCode": "// No Coresignal profile matched this LinkedIn URL. Log it and move on - never halt\n// the run, and never overwrite the last good snapshot.\nconst row = $('Loop Over Alumni Profiles').first().json;\nreturn [{ json: {\n profile_url: row.profile_url || '',\n full_name: row.full_name || '',\n coresignal_employee_id: row.coresignal_employee_id || '',\n current_company_id: row.current_company_id || '',\n current_company_name: row.current_company_name || '',\n current_title: row.current_title || '',\n current_company_start: row.current_company_start || '',\n previous_company_id: row.previous_company_id || '',\n previous_company_name: row.previous_company_name || '',\n status: 'no_match',\n suppressed_reason: 'no Coresignal profile matched this LinkedIn URL - check the url or the slug changed',\n last_checked_at: new Date().toISOString(),\n last_change_detected_at: row.last_change_detected_at || '',\n alerted_company_id: row.alerted_company_id || '',\n alerted_at: row.alerted_at || ''\n} }];\n"
},
"typeVersion": 2
},
{
"id": "4b9c62bf-232c-44c5-963c-3f2992035b94",
"name": "Append or Update in Sheets",
"type": "n8n-nodes-base.googleSheets",
"onError": "continueRegularOutput",
"position": [
8992,
1888
],
"parameters": {
"columns": {
"value": {
"status": "={{ $json.status }}",
"full_name": "={{ $json.full_name }}",
"alerted_at": "={{ $json.alerted_at }}",
"profile_url": "={{ $json.profile_url }}",
"current_title": "={{ $json.current_title }}",
"last_checked_at": "={{ $json.last_checked_at }}",
"suppressed_reason": "={{ $json.suppressed_reason }}",
"alerted_company_id": "={{ $json.alerted_company_id }}",
"current_company_id": "={{ $json.current_company_id }}",
"previous_company_id": "={{ $json.previous_company_id }}",
"current_company_name": "={{ $json.current_company_name }}",
"current_company_start": "={{ $json.current_company_start }}",
"previous_company_name": "={{ $json.previous_company_name }}",
"coresignal_employee_id": "={{ $json.coresignal_employee_id }}",
"last_change_detected_at": "={{ $json.last_change_detected_at }}"
},
"schema": [
{
"id": "profile_url",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "profile_url",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "full_name",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "full_name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "coresignal_employee_id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "coresignal_employee_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "current_company_id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "current_company_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "current_company_name",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "current_company_name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "current_title",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "current_title",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "current_company_start",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "current_company_start",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "previous_company_id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "previous_company_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "previous_company_name",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "previous_company_name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "status",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "suppressed_reason",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "suppressed_reason",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "last_checked_at",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "last_checked_at",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "last_change_detected_at",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "last_change_detected_at",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "alerted_company_id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "alerted_company_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "alerted_at",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "alerted_at",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "ref_headline",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "ref_headline",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "ref_active_title",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "ref_active_title",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "ref_active_company_id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "ref_active_company_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "ref_seniority",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "ref_seniority",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "ref_location",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "ref_location",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "ref_country",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "ref_country",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "ref_total_experience_months",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "ref_total_experience_months",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "ref_coresignal_checked_at",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "ref_coresignal_checked_at",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"profile_url"
],
"attemptToConvertTypes": false,
"convertFieldsToString": true
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1VBboOirOjYRF_zPYaLnMhws7gHNZzzpAsac4aw6KAPQ/edit#gid=0",
"cachedResultName": "Employees"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1VBboOirOjYRF_zPYaLnMhws7gHNZzzpAsac4aw6KAPQ",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1VBboOirOjYRF_zPYaLnMhws7gHNZzzpAsac4aw6KAPQ/edit?usp=drivesdk",
"cachedResultName": "Testing_claude"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"availableInMCP": false,
"executionOrder": "v1"
},
"versionId": "a6c195ab-fb2c-4b00-9e68-b562a16516ed",
"nodeGroups": [],
"connections": {
"If Job Changed": {
"main": [
[
{
"node": "Post to Slack Channel",
"type": "main",
"index": 0
},
{
"node": "Append or Update in Sheets",
"type": "main",
"index": 0
}
],
[
{
"node": "Append or Update in Sheets",
"type": "main",
"index": 0
}
]
]
},
"If Profile Found": {
"main": [
[
{
"node": "Collect Employee Details",
"type": "main",
"index": 0
}
],
[
{
"node": "Log No Match Found",
"type": "main",
"index": 0
}
]
]
},
"Log No Match Found": {
"main": [
[
{
"node": "Append or Update in Sheets",
"type": "main",
"index": 0
}
]
]
},
"Determine Job Change": {
"main": [
[
{
"node": "If Job Changed",
"type": "main",
"index": 0
}
]
]
},
"Transform Profile URL": {
"main": [
[
{
"node": "Search Employee in Coresignal",
"type": "main",
"index": 0
}
]
]
},
"Collect Employee Details": {
"main": [
[
{
"node": "Determine Job Change",
"type": "main",
"index": 0
}
]
]
},
"Extract IDs from Response": {
"main": [
[
{
"node": "If Profile Found",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Alumni Profiles": {
"main": [
[
{
"node": "Set Summary Field",
"type": "main",
"index": 0
}
],
[
{
"node": "Transform Profile URL",
"type": "main",
"index": 0
}
]
]
},
"Append or Update in Sheets": {
"main": [
[
{
"node": "Loop Over Alumni Profiles",
"type": "main",
"index": 0
}
]
]
},
"Read Employees from Sheets": {
"main": [
[
{
"node": "Filter by Profile URL Presence",
"type": "main",
"index": 0
}
]
]
},
"When Weekly on Monday at 8am": {
"main": [
[
{
"node": "Read Employees from Sheets",
"type": "main",
"index": 0
}
]
]
},
"Search Employee in Coresignal": {
"main": [
[
{
"node": "Extract IDs from Response",
"type": "main",
"index": 0
}
]
]
},
"Filter by Profile URL Presence": {
"main": [
[
{
"node": "Loop Over Alumni Profiles",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
coresignalApigoogleSheetsOAuth2ApislackOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow runs weekly, reads alumni profile URLs from Google Sheets, looks up matching employee profiles in Coresignal, detects job changes based on the current active employer, posts alerts to Slack when a change is confirmed, and writes the latest status and snapshot…
Source: https://n8n.io/workflows/18127/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow continuously monitors the TikTok Ads Library for new creatives from specific advertisers or keyword searches, scrapes them via Apify, logs them into Google Sheets, and sends concise noti
This workflow runs every Monday, pulls the latest Apple App Store reviews for a list of apps using Apify, and logs them to Google Sheets while also generating a per-app weekly rating scorecard (averag
This workflow runs weekly, searches Coresignal job ads for recent roles matching your keywords and country, enriches each posting with the hiring company and a likely HR contact, and sends a single Sl
This workflow contains community nodes that are only compatible with the self-hosted version of n8n.
Simplify financial oversight with this automated n8n workflow. Triggered daily, it fetches cash flow and expense data from a Google Sheet, analyzes inflows and outflows, validates records, and generat