{
  "id": "BbDI3foH7nCAdFnj",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "AI LinkedIn Outreach Agent",
  "tags": [],
  "nodes": [
    {
      "id": "fbdb8eda-9818-46d2-9e43-48c50419a4c7",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2608,
        816
      ],
      "parameters": {
        "width": 480,
        "height": 896,
        "content": "## AI LinkedIn Outreach Agent\n\n### How it works\n\nThis workflow starts from a form submission, uses Gemini to turn the submitted targeting details into a LinkedIn search URL, then prepares that URL for scraping. It runs an Apify actor to collect prospect results, limits the returned list, and uses Gemini again to personalize outreach messaging. The generated leads and messages are saved to Google Sheets, then after a 15-minute delay the workflow triggers a PhantomBuster agent to continue the LinkedIn outreach process.\n\n### Setup steps\n\n- Configure the n8n form fields to collect the search criteria needed for LinkedIn prospecting.\n- Add Google Gemini credentials and verify the prompts in both Gemini nodes match the desired search URL generation and outreach personalization style.\n- Configure the JavaScript code node to format the Gemini output correctly for the Apify actor input.\n- Add the Apify API token and actor configuration in the HTTP request node.\n- Connect Google Sheets credentials and select the target spreadsheet and worksheet for storing prospects and messages.\n- Add the PhantomBuster API key and agent ID or endpoint details in the final HTTP request node.\n\n### Customization\n\nAdjust the Limit node to control how many prospects are processed per run, edit the Gemini prompts to change targeting or message tone, and change the Wait duration to match the desired delay before triggering PhantomBuster."
      },
      "typeVersion": 1
    },
    {
      "id": "b452e27b-a133-4daa-a4ba-1adf71e65915",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3168,
        816
      ],
      "parameters": {
        "color": 7,
        "width": 768,
        "height": 320,
        "content": "## Capture search intent\n\nStarts the workflow from a form submission, generates a LinkedIn search URL with Gemini, and formats the generated output with JavaScript for the scraping step. These nodes form the leftmost input and preparation cluster."
      },
      "typeVersion": 1
    },
    {
      "id": "e2028555-edec-45b3-9587-12ff6da8f88d",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4032,
        816
      ],
      "parameters": {
        "color": 7,
        "width": 704,
        "height": 320,
        "content": "## Scrape and personalize leads\n\nRuns the Apify actor to retrieve LinkedIn search results, limits the number of prospects to process, and uses Gemini to generate personalized outreach content. This middle cluster handles lead retrieval and AI enrichment."
      },
      "typeVersion": 1
    },
    {
      "id": "23022f96-6af4-466b-bb48-5563ed14593e",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4928,
        816
      ],
      "parameters": {
        "color": 7,
        "width": 816,
        "height": 320,
        "content": "## Save and trigger outreach\n\nStores the personalized prospect data in Google Sheets, waits 15 minutes, then calls the PhantomBuster API to trigger the outreach agent. This rightmost cluster handles persistence, pacing, and outbound automation."
      },
      "typeVersion": 1
    },
    {
      "id": "425a93cb-0410-4fe7-a7d4-c4353d592192",
      "name": "Wait 15 Minutes",
      "type": "n8n-nodes-base.wait",
      "position": [
        5296,
        976
      ],
      "parameters": {
        "unit": "minutes",
        "amount": 15
      },
      "typeVersion": 1.1
    },
    {
      "id": "e63317ad-3caf-4959-bc78-117e3b05b952",
      "name": "When Form Submitted",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        3216,
        976
      ],
      "parameters": {
        "options": {},
        "formTitle": "LinkedIn Lead Outreach Trigger",
        "formFields": {
          "values": [
            {
              "fieldType": "textarea",
              "fieldLabel": "Describe your audience in plain English.",
              "placeholder": "Company type, location etc"
            }
          ]
        },
        "formDescription": "Insert an audience for your LinkedIn Outreach Campaign here."
      },
      "typeVersion": 2.6
    },
    {
      "id": "7330b38d-26a8-4376-bc7e-0924b1c5f65c",
      "name": "Execute Custom Script",
      "type": "n8n-nodes-base.code",
      "position": [
        3792,
        976
      ],
      "parameters": {
        "jsCode": "for (const item of $input.all()) {\n  try {\n    let rawText = item.json.content.parts[0].text;\n    rawText = rawText.replace(/```json/g, '').replace(/```/g, '').trim();\n    const parsedJson = JSON.parse(rawText);\n    item.json.searchUrl = parsedJson.searchUrl;\n  } catch (error) {\n    item.json.searchUrl = \"Error parsing URL\";\n  }\n}\nreturn $input.all();"
      },
      "typeVersion": 2
    },
    {
      "id": "73608274-a730-4501-b65a-3fd75f8730e9",
      "name": "Launch PhantomBuster Agent",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        5600,
        976
      ],
      "parameters": {
        "url": "https://api.phantombuster.com/api/v1/agent/1143979160139652/launch",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "id",
              "value": "1143979160139652"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "X-Phantombuster-Key-1",
              "value": "IKHfthwpvSe9tSsghN24a92GJHaTEVfk2KoBgv11Fpo"
            },
            {
              "name": "accept",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "342ef22f-cb97-4701-bf83-6ef835cc33dd",
      "name": "Execute Apify Actor",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        4080,
        976
      ],
      "parameters": {
        "url": "https://api.apify.com/v2/actors/kVYdvNOefemtiDXO5/run-sync-get-dataset-items",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n    \"companyLocationCountryIncludes\": [\"United States\"],\n    \"companySizeIncludes\": [\"201-500\",\"1-10\",\"51-200\"],\n    \"countOnly\": false,\n    \"dontSaveProgress\": false,\n    \"hasEmail\": false,\n    \"hasPhone\": false,\n    \"includeTitleVariants\": true,\n    \"personTitleIncludes\": [\"Owner\",\"Ceo\",\"Founder\",\"Partner\"],\n    \"resetProgress\": false,\n    \"seniorityIncludes\": [\"director\",\"manager\",\"entry\",\"senior\",\"owner\",\"partner\"],\n    \"totalResults\": 100\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "86ad2d46-2ba1-4201-8926-e262becbc889",
      "name": "AI Personalize Outreach",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        4592,
        976
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "models/gemini-3-flash-preview"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "role": "model",
              "content": "You are a helpful, intelligent writing assistant."
            },
            {
              "role": "model",
              "content": "Your task is to take as input LinkedIn profile information and generate a very short, highly personalized, and spartan connection message (under 30 words).\n\nCRITICAL: Every message must be unique in sentence structure, syntax, and phrasing. Avoid rigid templates.\n- Alternate between opening styles (e.g., skip \"Hey [Name]\", use their name mid-sentence, or dive directly into their work).\n- Paraphrase fields uniquely; never copy phrases directly.\n- Avoid generic corporate fluff (e.g., do not say \"scaling platforms\", \"turning vision into reality\", or \"founder life\" repeatedly). Keep it laconic, sharp, and highly contextualized to their company description or title.\n\nReturn your results strictly in this JSON format:\n{\"icebreaker\":\"Icebreaker goes here\"}"
            },
            {
              "content": "={\"linkedInFields\":\"{{ $json.firstName }} {{ $json.lastName }},{{ $json.personCity }} {{ $json.title }} at {{ $json.companyName }}\"} "
            }
          ]
        },
        "jsonOutput": true,
        "builtInTools": {}
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "35624b91-da6c-4450-95f5-7d42bd35a488",
      "name": "AI Generate Search URL",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        3440,
        976
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "models/gemini-3-flash-preview"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "You're helpful, intelligent sales assistant."
            },
            {
              "content": "Your task is to take as input a natural language description of a prospect audience, and turn that into an Apollo Search URL.\n\nHere's an example of an Apollo Search URL:\nhttps://console.apify.com/actors/kVYdvNOefemtiDXO5\n\nReturn your response in JSON using this format:\n{\"searchUrl\": \"search url goes here\"}\n"
            },
            {
              "content": "={{ $json['Describe your audience in plain English.'] }}"
            }
          ]
        },
        "builtInTools": {}
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "8eae5826-8a1c-4af2-ac7a-75eb91836382",
      "name": "Limit to Top 5 Items",
      "type": "n8n-nodes-base.limit",
      "position": [
        4352,
        976
      ],
      "parameters": {
        "maxItems": 5
      },
      "typeVersion": 1
    },
    {
      "id": "f916ec81-6715-4925-9b83-d0c65602855b",
      "name": "Update Google Sheet Data",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        4976,
        976
      ],
      "parameters": {
        "columns": {
          "value": {
            "id": "={{ Date.now().toString(36) + Math.random().toString(36).substring(2, 5) }}",
            "name": "={{ $('Limit to Top 5 Items').item.json.fullName }}",
            "title": "={{ $('Limit to Top 5 Items').item.json.title }}",
            "lats_name": "={{ $('Limit to Top 5 Items').item.json.lastName }}",
            "first_name": "={{ $('Limit to Top 5 Items').item.json.firstName }}",
            "icebreaker": "={{ JSON.parse($json.content.parts[0].text).icebreaker }}",
            "email_status": "={{ $('Limit to Top 5 Items').item.json.email }}",
            "linkedIn_url": "={{ $('Limit to Top 5 Items').item.json.linkedinUrl }}",
            "company_linkedIn_url": "={{ $('Limit to Top 5 Items').item.json.companyLinkedinUrl }}"
          },
          "schema": [
            {
              "id": "id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "id",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "https://docs.google.com/spreadsheets/d/1X7X-mLAFY0zpSr4QvDwYYXMabckDFQR4xmd4b74TWOg"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "bb6d1578-e446-4616-a80b-a8a2f42425ad",
  "nodeGroups": [],
  "connections": {
    "Wait 15 Minutes": {
      "main": [
        [
          {
            "node": "Launch PhantomBuster Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute Apify Actor": {
      "main": [
        [
          {
            "node": "Limit to Top 5 Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Form Submitted": {
      "main": [
        [
          {
            "node": "AI Generate Search URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Limit to Top 5 Items": {
      "main": [
        [
          {
            "node": "AI Personalize Outreach",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute Custom Script": {
      "main": [
        [
          {
            "node": "Execute Apify Actor",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Generate Search URL": {
      "main": [
        [
          {
            "node": "Execute Custom Script",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Personalize Outreach": {
      "main": [
        [
          {
            "node": "Update Google Sheet Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Google Sheet Data": {
      "main": [
        [
          {
            "node": "Wait 15 Minutes",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}