This workflow corresponds to n8n.io template #6103 — we link there as the canonical source.
This workflow follows the Chainllm → Execute Workflow Trigger 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": "t7e4sQzh96e0xaq7",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "contact enrichment",
"tags": [
{
"id": "0zTM91F1nQEHLKzN",
"name": "template_upload",
"createdAt": "2025-07-17T15:01:40.334Z",
"updatedAt": "2025-07-17T15:01:40.334Z"
}
],
"nodes": [
{
"id": "dbf704c3-2b0e-4158-b5d8-ca1d138d141a",
"name": "When Executed by Another Workflow",
"type": "n8n-nodes-base.executeWorkflowTrigger",
"position": [
-336,
752
],
"parameters": {
"workflowInputs": {
"values": [
{
"name": "name"
},
{
"name": "email"
}
]
}
},
"typeVersion": 1.1
},
{
"id": "747be8f0-cf2b-412d-b7a9-93051ff0a11b",
"name": "Enrich with Apollo",
"type": "n8n-nodes-base.httpRequest",
"position": [
128,
752
],
"parameters": {
"url": "https://api.apollo.io/api/v1/people/match",
"method": "POST",
"options": {},
"sendQuery": true,
"sendHeaders": true,
"queryParameters": {
"parameters": [
{
"name": "reveal_personal_emails",
"value": "false"
},
{
"name": "reveal_phone_number",
"value": "false"
},
{
"name": "email",
"value": "={{ $json.email }}"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Cache-Control",
"value": "no-cache"
},
{
"name": "accept",
"value": "application/json"
},
{
"name": "x-api-key",
"value": "YOUR-API-KEY"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "3630169c-2677-4124-a19b-f9d1a2bfdcce",
"name": "Found?",
"type": "n8n-nodes-base.if",
"position": [
352,
752
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "8037609c-e921-4ef9-9d34-375a6bd471ad",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.person && ($json.person.name || $json.person.email) }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "00a26c55-aa97-4255-b002-cb77bc1a8780",
"name": "Enrich in HubSpot1",
"type": "n8n-nodes-base.hubspot",
"position": [
3168,
752
],
"parameters": {
"email": "={{ $json.output.email }}",
"options": {},
"authentication": "oAuth2",
"additionalFields": {
"city": "={{ $json.output.city }}",
"country": "={{ $json.output.country_region }}",
"jobTitle": "={{ $json.output.job_title }}",
"customPropertiesUi": {
"customPropertiesValues": [
{
"value": "={{ $json.output.linkedin_url }}",
"property": "linkedin_account"
},
{
"value": "={{ $json.output.experience_summary }}",
"property": "experience_summary"
},
{
"value": "={{ $json.output.education_summary }}",
"property": "education_summary"
},
{
"value": "={{ Math.floor(Date.now() / 86400000) * 86400000 }}",
"property": "last_enrichment_date"
},
{
"value": "={{ $json.output.recent_linkedin_activity }}",
"property": "recent_linkedin_posts"
}
]
}
}
},
"credentials": {
"hubspotOAuth2Api": {
"name": "<your credential>"
}
},
"retryOnFail": true,
"typeVersion": 2.1
},
{
"id": "01dd3096-dcb3-4e0d-97ac-581a7d08b55f",
"name": "Auto-fixing Output Parser2",
"type": "@n8n/n8n-nodes-langchain.outputParserAutofixing",
"position": [
2672,
912
],
"parameters": {
"options": {}
},
"typeVersion": 1
},
{
"id": "b819ac28-783c-49d5-8125-fb824fd30661",
"name": "Structured Output Parser2",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
2832,
1040
],
"parameters": {
"jsonSchemaExample": "{\n \"email\": \"user@example.com\",\n \"linkedin_url\": \"http://www.linkedin.com/in/testuser1\",\n \"job_title\": \"CEO & Co-Founder\",\n \"city\": \"Denver\",\n \"state\": \"Colorado\",\n \"country_region\": \"United States\",\n \"experience_summary\": \"User experience content\",\n \"education_summary\": \"Education Level content\",\n \"recent_linkedin_activity\": \"\u2022 Posted about winning 82 % of competitive deals and key sales mantras (6 hours ago)\\n\u2022 Shared guidance on setting realistic expectations for a new VP Sales\u2019 impact (1 day ago)\"\n}"
},
"typeVersion": 1.2
},
{
"id": "06391ddf-2071-4b80-86ad-85c922ae33c8",
"name": "OpenAI Chat Model5",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
2672,
1040
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini"
},
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "3aa928c0-6f12-4f5c-9acb-018b0b87667e",
"name": "Enrichment summary agent",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
2528,
752
],
"parameters": {
"text": "=Here\u2019s the person data to enrich for CRM: \n{{ JSON.stringify($json, null, 2) }}\n\nHere's the recent activity to summarize for the CRM:\n{{ $json.recent_activity }}",
"messages": {
"messageValues": [
{
"message": "=# Overview\nYou are \u201cHubSpot-Enrichment-Agent\u201d, a data-cleaning assistant that converts messy person JSON enrichment data into concise, human-friendly fields ready to upsert into HubSpot. \n\n## OBJECTIVE\nReturn **one** JSON object with exactly these keys:\n\n{\n \"email\": string|null,\n \"linkedin_url\": string|null,\n \"job_title\": string|null, // title at the company that matches the email domain\n \"city\": string|null,\n \"state\": string|null,\n \"country_region\": string|null,\n \"experience_summary\": string|null, // 3-4 recent roles, bullet list, newest \u2192 oldest\n \"education_summary\": string|null, // highest degree(s) & institution(s), 1-2 lines\n \"recent_linkedin_activity\": string|null\n}\n\n## RULES & LOGIC\n\n1. **Email, LinkedIn URL, City, Country/Region** \n *Pass through directly if present; else `null`.*\n\n2. **Job Title (relevant)** \n - Use the employment record whose `organization_name` (or website) shares the **same email domain** as `email`. \n - If no domain match, pick the most recent item where `current == true`. \n - Strip membership-only titles (\u201cMember\u201d, \u201cAngel Investor\u201d) unless no better option exists.\n\n3. **Experience Summary** \n - Sort `employment_history` by `start_date` DESC. \n - Select the first **3\u20134** roles that are either `current == true` _or_ have an `end_date` within the last 10 years. \n - Format each as: \n `\u2022 <Title>, <Org> \u2014 <YYYY-start> \u2192 <\"Present\" | YYYY-end>` \n - Join with line breaks. Return `null` if list is empty.\n\n4. **Education Summary** \n - Look for the highest\u2010level degree (Doctorate > MBA/Master\u2019s > Bachelor\u2019s > Associate > Other). \n - Summarise as: \n `<Degree>, <Institution> (<YYYY-end>)`. \n - If multiple relevant degrees, include up to two lines. \n - If no education data, return `null`.\n\n5. **Recent LinkedIn Activity** \n - If a `recent_activity` or similar field exists, pull the latest **1-3** public posts or updates. \n - Summarise in plain text, e.g., \n `\u201cCommented on procurement AI article\u201d (3 days ago)` \n - If no activity data, set to `null`. Do NOT make up activity.\n\n6. **Null handling** \n - Any missing or empty field **must** be literal `null` (not empty string).\n\n7. **Output style** \n - Pure JSON, no markdown. \n - No additional keys, comments, or nested objects.\n\n## Grammar and Punctuation\n - ensure that your output is cleanly formatted for readiness to import into CRM, including removing uneceesary spaces or other symbols and capitalizing names. (e.g., \"sales director\" should become \"Sales Director\")\n\nReturn only that final JSON. Example output:\n{\n \"email\": \"dustin.c@gatekeeperhq.com\",\n \"linkedin_url\": \"https://www.linkedin.com/in/dustinclinard\",\n \"job_title\": \"Chief Revenue Officer (CRO)\",\n \"city\": \"Concord\",\n \"country_region\": \"United States\",\n \"experience_summary\": \"\u2022 Chief Revenue Officer, Gatekeeper \u2014 2024 \u2192 Present\\n\u2022 Founding Member, Revenue Collective \u2014 2019 \u2192 Present\\n\u2022 Member, Partnership Leaders \u2014 2020 \u2192 Present\\n\u2022 Founder & Growth Consultant, Sales Growth Musings \u2014 2016 \u2192 Present\",\n \"education_summary\": null,\n \"recent_linkedin_activity\": null\n}"
}
]
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.6
},
{
"id": "f3d84acb-fe43-4d14-ab74-97a0e5a336a7",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
48,
592
],
"parameters": {
"color": 5,
"width": 260,
"height": 400,
"content": "## Enrich with Apollo"
},
"typeVersion": 1
},
{
"id": "8f9f9c6c-e9b9-4502-97a2-b4bf3c5a396c",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
2448,
608
],
"parameters": {
"color": 4,
"width": 540,
"height": 620,
"content": "## Summarize enrichment data\nEnsure it's clean and matches our CRM needs"
},
"typeVersion": 1
},
{
"id": "9cc13aca-f660-470f-addb-f17f51f725e7",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
3104,
608
],
"parameters": {
"color": 5,
"width": 260,
"height": 400,
"content": "## Enrich HubSpot"
},
"typeVersion": 1
},
{
"id": "6c4e7437-9a58-4aad-956c-268bb23920e8",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"position": [
2048,
752
],
"parameters": {
"mode": "combine",
"options": {
"includeUnpaired": true
},
"combineBy": "combineByPosition"
},
"typeVersion": 3.1
},
{
"id": "5f3436aa-94d0-46f9-83fd-e60726b8821c",
"name": "OpenAI Chat Model6",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
2512,
912
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "o3",
"cachedResultName": "o3"
},
"options": {
"responseFormat": "json_object"
}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "624d158e-08bc-42df-add7-9462b39cb8de",
"name": "Get recent posts",
"type": "n8n-nodes-base.httpRequest",
"position": [
832,
912
],
"parameters": {
"url": "https://fresh-linkedin-profile-data.p.rapidapi.com/get-profile-posts",
"options": {},
"sendQuery": true,
"sendHeaders": true,
"queryParameters": {
"parameters": [
{
"name": "linkedin_url",
"value": "={{ $json.person.linkedin_url }}"
},
{
"name": "type",
"value": "posts"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "x-rapidapi-host",
"value": "fresh-linkedin-profile-data.p.rapidapi.com"
},
{
"name": "x-rapidapi-key",
"value": "<YOUR API KEY>"
}
]
}
},
"retryOnFail": true,
"typeVersion": 4.2,
"alwaysOutputData": true
},
{
"id": "45dfddb1-ad00-419b-8309-e91de878989d",
"name": "Split Out",
"type": "n8n-nodes-base.splitOut",
"position": [
1040,
912
],
"parameters": {
"options": {},
"fieldToSplitOut": "data"
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "6b392b08-3dff-4201-ba66-a979ac7d301a",
"name": "Filter out reshares and old posts",
"type": "n8n-nodes-base.filter",
"position": [
1264,
912
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "44e79a7e-7ec9-4724-a53b-3e647b6a629a",
"operator": {
"type": "boolean",
"operation": "false",
"singleValue": true
},
"leftValue": "={{ $json.reshared }}",
"rightValue": ""
},
{
"id": "8da29df1-cbfb-42cd-a85f-62b2b4647802",
"operator": {
"type": "dateTime",
"operation": "afterOrEquals"
},
"leftValue": "={{ $json.posted }}",
"rightValue": "={{$now.minus({ days: 30 }).toISO()}}"
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2,
"alwaysOutputData": true
},
{
"id": "466bbf0f-54e8-4c2c-9637-f70925329b72",
"name": "Limit to 3",
"type": "n8n-nodes-base.limit",
"position": [
1680,
912
],
"parameters": {
"maxItems": 3
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "fa0bd77e-310e-4a64-83c9-c4f3b0fddb7a",
"name": "Sort by post date",
"type": "n8n-nodes-base.sort",
"position": [
1488,
912
],
"parameters": {
"options": {},
"sortFieldsUi": {
"sortField": [
{
"order": "descending",
"fieldName": "posted"
}
]
}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "b45d1bb7-5a3f-43f6-ae9c-7a912e3b1114",
"name": "Aggregate",
"type": "n8n-nodes-base.aggregate",
"position": [
1904,
912
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData"
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "c0e75ad6-08db-4bda-9c69-4067adcc4951",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
624,
784
],
"parameters": {
"options": {}
},
"typeVersion": 3,
"alwaysOutputData": false
},
{
"id": "69bd14dd-f6d8-4220-ba6b-dd17d2d1ea8b",
"name": "Extract fields",
"type": "n8n-nodes-base.set",
"position": [
2272,
752
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "19c926c1-da4e-44e2-abce-6d7d172cb0bb",
"name": "person_data",
"type": "string",
"value": "={{ $json.person }}"
},
{
"id": "62615717-7bc7-44c4-9304-7177dfcf3ee8",
"name": "recent_activity",
"type": "string",
"value": "={{ $json.data }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "5b9ce241-42a6-468a-be87-2462248836af",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
768,
848
],
"parameters": {
"color": 5,
"width": 1260,
"height": 220,
"content": "## Grab Recent LinkedIn Posts"
},
"typeVersion": 1
},
{
"id": "f76caacf-bf40-4aa7-b48c-60ebf9c772a8",
"name": "clean",
"type": "n8n-nodes-base.code",
"position": [
-128,
752
],
"parameters": {
"jsCode": "/**********************************************************************\n * Deduplicate contacts by email & drop empties\n * Input: items[] (each item = { json: { \u2026 } })\n * Output: one item per unique, non-empty email\n **********************************************************************/\nconst normEmail = e => (typeof e === 'string' ? e.trim().toLowerCase() : '');\n\nconst seen = new Set();\nconst clean = [];\n\nfor (const itm of items) {\n // Handle both flat and nested structures\n const data = itm.json.output ?? itm.json; // supports {output:{\u2026}} too\n const email = normEmail(data.email);\n\n if (!email || seen.has(email)) continue; // skip blanks & dupes\n\n seen.add(email);\n clean.push({\n json: {\n name: data.name ?? null,\n email // already normalised\n }\n });\n}\n\nreturn clean;"
},
"typeVersion": 2
},
{
"id": "e95c04cb-b9e3-433d-b510-77e1b9b7abf2",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1632,
848
],
"parameters": {
"height": 208,
"content": "Decide how many posts you want to analyse"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "ad6478e5-597d-450d-ab64-d506159731f2",
"connections": {
"Merge": {
"main": [
[
{
"node": "Extract fields",
"type": "main",
"index": 0
}
]
]
},
"clean": {
"main": [
[
{
"node": "Enrich with Apollo",
"type": "main",
"index": 0
}
]
]
},
"Found?": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
},
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
],
[]
]
},
"Aggregate": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Split Out": {
"main": [
[
{
"node": "Filter out reshares and old posts",
"type": "main",
"index": 0
}
]
]
},
"Limit to 3": {
"main": [
[
{
"node": "Aggregate",
"type": "main",
"index": 0
}
]
]
},
"Extract fields": {
"main": [
[
{
"node": "Enrichment summary agent",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
],
[
{
"node": "Get recent posts",
"type": "main",
"index": 0
}
]
]
},
"Get recent posts": {
"main": [
[
{
"node": "Split Out",
"type": "main",
"index": 0
}
]
]
},
"Sort by post date": {
"main": [
[
{
"node": "Limit to 3",
"type": "main",
"index": 0
}
]
]
},
"Enrich in HubSpot1": {
"main": [
[]
]
},
"Enrich with Apollo": {
"main": [
[
{
"node": "Found?",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model5": {
"ai_languageModel": [
[
{
"node": "Auto-fixing Output Parser2",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"OpenAI Chat Model6": {
"ai_languageModel": [
[
{
"node": "Enrichment summary agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Enrichment summary agent": {
"main": [
[
{
"node": "Enrich in HubSpot1",
"type": "main",
"index": 0
}
]
]
},
"Structured Output Parser2": {
"ai_outputParser": [
[
{
"node": "Auto-fixing Output Parser2",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Auto-fixing Output Parser2": {
"ai_outputParser": [
[
{
"node": "Enrichment summary agent",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Filter out reshares and old posts": {
"main": [
[
{
"node": "Sort by post date",
"type": "main",
"index": 0
}
]
]
},
"When Executed by Another Workflow": {
"main": [
[
{
"node": "clean",
"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.
hubspotOAuth2ApiopenAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Turns a plain name + email into a fully-enriched HubSpot contact by matching the person in Apollo, pulling their latest LinkedIn activity, summarising the findings with GPT-4o, and upserting the clean data into HubSpot
Source: https://n8n.io/workflows/6103/ — 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 template attempts to replicate OpenAI's DeepResearch feature which, at time of writing, is only available to their pro subscribers.
The best content automation template in the market is now even better—with “deep research” on time-sensitive topics\! Unlike most n8n content automation templates that are mainly for “demo purposes,”
Typeform IA - YT. Uses typeformTrigger, agent, lmChatOpenAi, toolWorkflow. Event-driven trigger; 75 nodes.
Agent Nodes. Uses lmChatOpenAi, slack, stopAndError, errorTrigger. Event-driven trigger; 72 nodes.
Many new n8n users struggle with testing webhooks when running n8n on localhost, as external services cannot reach . This workflow introduces a technique using PostBin, which provides a temporary, pub