{
  "id": "yN5I1ei5K4vPytnb",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Autonomous Sales Research Agent",
  "tags": [],
  "nodes": [
    {
      "id": "f3de07d1-5cd2-4374-9d58-b479d37f8f39",
      "name": "Sticky Note - Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -416,
        -128
      ],
      "parameters": {
        "width": 1020,
        "height": 1400,
        "content": "## Autonomous Sales Research Agent\n\nThis workflow automatically researches prospects from a queue, pulling company insights, recent news, funding history, technology stack, and decision-maker contacts from multiple sources. It then uses AI to synthesize everything into a concise, personalized sales brief with an outreach recommendation and a draft first-touch message, so reps spend less time researching and more time selling.\n\n### Who's it for\n- SDR/BDR teams who need a fast, consistent research pass before outreach\n- AEs prepping for a first call or demo\n- RevOps teams standardizing account research across a team\n- Anyone replacing manual LinkedIn/Google tab-hopping with one automated pass\n\n### How it works\n1. A schedule trigger polls a Prospects queue in Google Sheets for rows marked 'New'\n2. Each prospect is researched in parallel across three source types: company website + recent news, funding + technology data, and decision-maker contacts\n3. The three research branches are merged and scored for priority and research completeness\n4. Prospects with at least one usable data source move forward; thin/empty profiles are skipped\n5. AI (Claude) writes a structured sales brief: company overview, news summary, funding summary, tech angle, key decision makers, pain points, personalized icebreakers, recommended channel/timing, and a draft outreach message\n6. The brief is logged to a SalesBriefs sheet, the prospect's status is updated to 'Researched', and the assigned rep is notified in Slack\n\n### How to set up\n1. Import this workflow into n8n\n2. Add Anthropic Claude credentials and attach to the Anthropic model node\n3. Swap the three research HTTP Request nodes for your real data providers (e.g. SerpAPI/NewsAPI for news, Crunchbase/Clearbit for funding & tech, Apollo/People Data Labs for decision makers) and add their API keys\n4. Switch the Google Sheets HTTP nodes to the native Google Sheets node with OAuth2, or add OAuth2 credentials directly\n5. Replace YOUR_SHEET_ID in all Sheets HTTP nodes with your actual Spreadsheet ID\n6. Replace YOUR_SLACK_WEBHOOK_URL with your Slack Incoming Webhook URL\n7. Set up your Google Sheet with three tabs: Prospects, SalesBriefs (column layouts below)\n8. Set the schedule interval to match how often new prospects are added (default: every 15 minutes)\n9. Activate the workflow\n\n### Requirements\n- Anthropic Claude API key (claude-sonnet-4 recommended)\n- News/search API (e.g. SerpAPI, NewsAPI)\n- Company enrichment API for funding & technology data (e.g. Crunchbase, Clearbit, BuiltWith)\n- People/contact enrichment API for decision makers (e.g. Apollo, People Data Labs)\n- Google Sheets with OAuth2 credentials (Prospects, SalesBriefs tabs)\n- Slack Incoming Webhook (optional, for rep notifications)\n\n### How to customize\n- Adjust priority/completeness scoring weights in JS - Compile Research Profile & Priority Score\n- Raise or lower the minimum data bar in Filter - Sufficient Data For Brief (default: completeness score >= 25)\n- Add an email node alongside Slack for reps who prefer inbox notifications\n- Add a CRM write-back step (HubSpot/Salesforce) instead of, or in addition to, Google Sheets\n- Add a fourth research branch (e.g. G2/review site sentiment) by following the existing branch + merge pattern\n\n### Google Sheets Column Layout\n\nProspects tab - row 1 headers:\nProspect ID | Company Name | Domain | Industry | Contact Name | Contact Title | Contact Email | Status\n\nSalesBriefs tab - row 1 headers:\nGenerated At | Prospect ID | Company Name | Contact Name | Contact Title | Priority Score | Company Overview | Recent News Summary | Funding Summary | Tech Stack Summary | Key Decision Makers | Pain Points & Opportunities | Icebreakers | Recommended Channel | Recommended Timing | Outreach Message Draft"
      },
      "typeVersion": 1
    },
    {
      "id": "dea4fc3b-88f2-4e1a-a00c-e3e750293b5a",
      "name": "Sticky Note - Stage 1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        752,
        -80
      ],
      "parameters": {
        "color": 3,
        "width": 820,
        "height": 700,
        "content": "## Stage 1: Prospect Queue Intake\n\nSchedule Trigger polls on a fixed interval (default every 15 minutes).\n\nFetch New Prospects pulls every row from the Prospects tab.\n\nJS - Parse Prospect Rows keeps only rows with Status = 'New', maps columns into named fields, and records each row's sheet row number (for the later status update).\n\nSplit Out - Prospects turns that array into one item per prospect so the rest of the workflow researches each prospect independently."
      },
      "typeVersion": 1
    },
    {
      "id": "d63bb8d0-cf86-4259-a3e7-63076df75321",
      "name": "Sticky Note - Stage 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1632,
        -320
      ],
      "parameters": {
        "color": 4,
        "width": 1072,
        "height": 1324,
        "content": "## Stage 2: Multi-Source Research\n\nThree branches run in parallel per prospect:\n\n- Company Website & News Search: recent news mentions and public signals\n- Funding & Technology Data: funding stage/amount, headcount, and detected technologies\n- Decision Makers Lookup: names, titles, and contact details for relevant roles\n\nEach HTTP call is followed by a small JS node that pulls the original prospect fields back in (via the Split Out - Prospects reference) and attaches the new signals, so nothing is lost.\n\nTwo chained Merge nodes (combine by position) reconverge the three branches into a single research object per prospect.\n\nJS - Compile Research Profile & Priority Score scores each prospect 0-100 on both sales priority and research completeness, so thin profiles can be filtered out before spending an AI call on them."
      },
      "typeVersion": 1
    },
    {
      "id": "aff7478c-380d-41a3-b4de-7f9e252e4b5d",
      "name": "Sticky Note - Stage 3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2864,
        -80
      ],
      "parameters": {
        "color": 6,
        "width": 1068,
        "height": 1096,
        "content": "## Stage 3: AI Sales Brief Generation\n\nFilter - Sufficient Data For Brief lets through only prospects with a research completeness score of 25+ (at least one source returned usable data), so empty profiles never trigger an AI call.\n\nA Wait buffer respects API rate limits, then the brief-writing AI (claude-sonnet-4, temperature 0.3 for grounded, consistent output) turns the merged research object into a structured brief: overview, news/funding/tech summaries, key decision makers, pain points, icebreakers, recommended channel/timing, and a draft outreach message.\n\nJS - Parse Sales Brief Output extracts the structured JSON safely, with a fallback that builds a minimal generic brief from the raw research fields if AI parsing fails."
      },
      "typeVersion": 1
    },
    {
      "id": "2827e96c-f151-41c2-a391-428b5d51b1da",
      "name": "Sticky Note - Stage 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4064,
        112
      ],
      "parameters": {
        "color": 5,
        "width": 1000,
        "height": 700,
        "content": "## Stage 4: Logging & Rep Notification\n\nJS - Format Sales Brief Record assembles the row for the SalesBriefs tab.\n\nSave Sales Brief to Google Sheets appends that row.\n\nUpdate Prospect Status to Researched writes 'Researched' back into the prospect's Status cell using the row number captured in Stage 1, so it's never researched twice.\n\nSend Slack Notification to Sales Rep posts a short summary and the outreach draft to a Slack channel or webhook so the rep sees it land."
      },
      "typeVersion": 1
    },
    {
      "id": "160db0f9-8fd6-41dc-95fe-9ca85a1d3d63",
      "name": "Schedule Trigger - Poll Prospect Queue",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        784,
        464
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 15
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "c3f72df4-c208-46f1-a918-561bedb80512",
      "name": "Fetch New Prospects",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1008,
        464
      ],
      "parameters": {
        "url": "=https://sheets.googleapis.com/v4/spreadsheets/YOUR_SHEET_ID/values/Prospects!A1:H1000",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "oAuth2Api"
      },
      "credentials": {
        "oAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "0228645e-a37c-4fd5-ba2c-0f3c62ace7f3",
      "name": "JS - Parse Prospect Rows",
      "type": "n8n-nodes-base.code",
      "position": [
        1232,
        464
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const item = $input.item.json;\nconst rows = (item.values || []).slice(1); // skip header\n\n// columns: [prospectId, companyName, domain, industry, contactName, contactTitle, contactEmail, status]\nconst prospects = rows\n  .map((r, i) => ({ r, rowIndex: i + 2 })) // +2: header row + 1-indexed sheet rows\n  .filter(({ r }) => (r[7] || '').toLowerCase() === 'new')\n  .map(({ r, rowIndex }) => ({\n    prospectId: r[0] || '',\n    companyName: r[1] || '',\n    domain: r[2] || '',\n    industry: r[3] || '',\n    contactName: r[4] || '',\n    contactTitle: r[5] || '',\n    contactEmail: r[6] || '',\n    status: r[7] || '',\n    rowIndex\n  }));\n\nreturn { json: { prospects } };"
      },
      "typeVersion": 2
    },
    {
      "id": "9b446ea3-6cc4-4260-97e7-773be0c6f69b",
      "name": "Split Out - Prospects",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        1456,
        464
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "prospects"
      },
      "typeVersion": 1
    },
    {
      "id": "c6adccf9-532f-4cc5-af67-8915a01dca40",
      "name": "HTTP Request - Company Website & News Search",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1680,
        144
      ],
      "parameters": {
        "url": "=https://serpapi.com/search.json?q={{ encodeURIComponent($json.companyName + ' company news') }}&api_key=YOUR_SERPAPI_KEY",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "9f52047f-fcd8-4056-ac29-3ea12ee021a2",
      "name": "JS - Extract Company & News Signals",
      "type": "n8n-nodes-base.code",
      "position": [
        1904,
        144
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const prospect = $('Split Out - Prospects').item.json;\nconst item = $input.item.json;\n\nconst rawResults = item.news_results || item.organic_results || [];\nconst newsResults = rawResults.slice(0, 5).map(n => ({\n  title: n.title || '',\n  snippet: n.snippet || '',\n  link: n.link || '',\n  date: n.date || ''\n}));\n\nreturn {\n  json: {\n    ...prospect,\n    newsResults\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "dfcd1a54-736b-4994-a313-409c1dfd3221",
      "name": "HTTP Request - Funding & Technology Data",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1680,
        464
      ],
      "parameters": {
        "url": "=https://api.companyenrichment.example.com/v1/company?domain={{ $json.domain }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "c25daa75-3e7b-4c8e-bf66-405887bdeb8c",
      "name": "JS - Extract Funding & Tech Signals",
      "type": "n8n-nodes-base.code",
      "position": [
        1904,
        464
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const prospect = $('Split Out - Prospects').item.json;\nconst item = $input.item.json;\n\nreturn {\n  json: {\n    ...prospect,\n    fundingStage: item.funding_stage || item.fundingStage || 'Unknown',\n    totalFundingRaised: item.total_funding || item.totalFunding || 'Unknown',\n    lastFundingDate: item.last_funding_date || item.lastFundingDate || '',\n    employeeCount: item.employee_count || item.employeeCount || 'Unknown',\n    technologies: item.technologies || item.tech_stack || []\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "73544341-7b54-40dd-b553-1f70f076ef6b",
      "name": "HTTP Request - Decision Makers Lookup",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1680,
        784
      ],
      "parameters": {
        "url": "=https://api.peopledata.example.com/v1/people?company_domain={{ $json.domain }}&titles=CEO,CTO,VP%20Sales,Head%20of%20Marketing",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "852e45a2-b591-4c87-911c-ec3fd339c021",
      "name": "JS - Extract Decision Maker Signals",
      "type": "n8n-nodes-base.code",
      "position": [
        1904,
        784
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const prospect = $('Split Out - Prospects').item.json;\nconst item = $input.item.json;\n\nconst rawPeople = item.people || item.results || [];\nconst decisionMakers = rawPeople.slice(0, 5).map(p => ({\n  name: p.name || '',\n  title: p.title || '',\n  linkedinUrl: p.linkedin_url || p.linkedinUrl || '',\n  email: p.email || ''\n}));\n\nreturn {\n  json: {\n    ...prospect,\n    decisionMakers\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "d04f4739-143f-49d2-8453-c9326aab6efb",
      "name": "Merge - Combine News & Funding Data",
      "type": "n8n-nodes-base.merge",
      "position": [
        2128,
        320
      ],
      "parameters": {
        "mode": "combine",
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "99d2615d-c72d-430a-9988-d2f5efb59ad1",
      "name": "Merge - Combine All Research Signals",
      "type": "n8n-nodes-base.merge",
      "position": [
        2352,
        512
      ],
      "parameters": {
        "mode": "combine",
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "87bdf056-f75f-4da5-86ba-c7a6a592c557",
      "name": "JS - Compile Research Profile & Priority Score",
      "type": "n8n-nodes-base.code",
      "position": [
        2576,
        512
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const item = $input.item.json;\n\nconst newsResults = item.newsResults || [];\nconst decisionMakers = item.decisionMakers || [];\nconst technologies = item.technologies || [];\nconst hasFunding = !!item.fundingStage && item.fundingStage !== 'Unknown';\n\nlet priorityScore = 0;\nif (newsResults.length > 0) priorityScore += 25;\nif (hasFunding && /series|seed|ipo/i.test(item.fundingStage)) priorityScore += 30;\nif (decisionMakers.length > 0) priorityScore += 25;\nif (technologies.length > 0) priorityScore += 20;\npriorityScore = Math.min(100, priorityScore);\n\nlet researchCompletenessScore = 0;\nresearchCompletenessScore += newsResults.length > 0 ? 25 : 0;\nresearchCompletenessScore += hasFunding ? 25 : 0;\nresearchCompletenessScore += decisionMakers.length > 0 ? 25 : 0;\nresearchCompletenessScore += technologies.length > 0 ? 25 : 0;\n\nreturn {\n  json: {\n    ...item,\n    priorityScore,\n    researchCompletenessScore,\n    researchedAt: new Date().toISOString()\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "c7708252-afce-43a7-9eed-9f35e8559b25",
      "name": "Filter - Sufficient Data For Brief",
      "type": "n8n-nodes-base.filter",
      "position": [
        2912,
        512
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "conditions": [
            {
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ $json.researchCompletenessScore }}",
              "rightValue": 25
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "66e879d0-e100-4a49-8101-988f4df7cf6a",
      "name": "Wait - API Rate Limit",
      "type": "n8n-nodes-base.wait",
      "position": [
        3168,
        512
      ],
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "7861f4bd-4b3a-44d3-a5fb-1841dd59fa5d",
      "name": "AI - Generate Sales Research Brief",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        3472,
        512
      ],
      "parameters": {
        "text": "=You are an expert B2B sales research analyst preparing a prospect brief for an Account Executive.\n\nCompany: {{ $json.companyName }}\nDomain: {{ $json.domain }}\nIndustry: {{ $json.industry }}\nPrimary Contact: {{ $json.contactName }} ({{ $json.contactTitle }})\n\nRecent News:\n{{ JSON.stringify($json.newsResults) }}\n\nFunding & Company Data:\nFunding Stage: {{ $json.fundingStage }}\nTotal Funding Raised: {{ $json.totalFundingRaised }}\nLast Funding Date: {{ $json.lastFundingDate }}\nEmployee Count: {{ $json.employeeCount }}\nTechnologies Detected: {{ JSON.stringify($json.technologies) }}\n\nDecision Makers:\n{{ JSON.stringify($json.decisionMakers) }}\n\nWrite a concise, actionable sales research brief. Focus only on facts useful for a first outreach conversation. Do not invent facts that are not present above; where data is missing, say so rather than guessing.\n\nReturn a JSON object with EXACTLY these fields:\n{\n  \"companyOverview\": \"2-3 sentence summary of what the company does and its current stage\",\n  \"recentNewsSummary\": \"1-2 sentence summary of the most relevant recent news, or 'No recent news found'\",\n  \"fundingSummary\": \"1 sentence summary of funding status and what it implies for buying power\",\n  \"techStackSummary\": \"1 sentence summary of relevant technologies and a possible integration or replacement angle\",\n  \"keyDecisionMakers\": [ { \"name\": \"\", \"title\": \"\", \"whyRelevant\": \"\" } ],\n  \"painPointsAndOpportunities\": [\"short bullet\", \"short bullet\"],\n  \"personalizedIcebreakers\": [\"short opener referencing something specific about the company\", \"second option\"],\n  \"recommendedOutreachChannel\": \"email, phone, or LinkedIn\",\n  \"recommendedTiming\": \"short guidance on timing based on news/funding signals\",\n  \"outreachMessageDraft\": \"A short, personalized first-touch outreach message under 500 characters\"\n}\n\nReturn ONLY the JSON. No markdown, no explanation.",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 1.6
    },
    {
      "id": "ab74b516-1f31-4db4-b1f3-8cfa69c905ea",
      "name": "Anthropic - Sales Brief Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        3248,
        736
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "claude-sonnet-4-20250514"
        },
        "options": {
          "temperature": 0.3
        }
      },
      "credentials": {
        "anthropicApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "7644e85c-9a37-4eb2-96ae-867229d9bfc7",
      "name": "JS - Parse Sales Brief Output",
      "type": "n8n-nodes-base.code",
      "position": [
        3792,
        512
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const item = $input.item.json;\nlet parsed = {};\ntry {\n  const rawText = item.output || item.text || item.response || '{}';\n  const clean = rawText.replace(/```json|```/g, '').trim();\n  parsed = JSON.parse(clean);\n} catch (e) {\n  parsed = {\n    companyOverview: `${item.companyName || 'This company'} is in the ${item.industry || 'unknown'} industry. Automated brief generation failed; manual review recommended.`,\n    recentNewsSummary: (item.newsResults && item.newsResults.length) ? `${item.newsResults.length} recent news item(s) found; see raw research data.` : 'No recent news found',\n    fundingSummary: item.fundingStage ? `Funding stage: ${item.fundingStage}.` : 'Funding data unknown.',\n    techStackSummary: (item.technologies && item.technologies.length) ? `Detected technologies: ${item.technologies.join(', ')}.` : 'No technology data found.',\n    keyDecisionMakers: item.decisionMakers || [],\n    painPointsAndOpportunities: [],\n    personalizedIcebreakers: [],\n    recommendedOutreachChannel: 'email',\n    recommendedTiming: 'No timing signal available; use standard cadence.',\n    outreachMessageDraft: `Hi ${item.contactName || 'there'}, wanted to reach out regarding ${item.companyName || 'your company'}.`\n  };\n}\nreturn {\n  json: {\n    ...item,\n    ...parsed\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "69a48734-f92f-4a26-b3fc-d7011a5a8c02",
      "name": "JS - Format Sales Brief Record",
      "type": "n8n-nodes-base.code",
      "position": [
        4160,
        512
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const item = $input.item.json;\nconst generatedAt = new Date().toISOString();\n\nconst decisionMakersStr = (item.keyDecisionMakers || [])\n  .map(d => `${d.name || ''} (${d.title || ''})${d.whyRelevant ? ' - ' + d.whyRelevant : ''}`)\n  .join(' | ');\nconst painPointsStr = (item.painPointsAndOpportunities || []).join(' | ');\nconst icebreakersStr = (item.personalizedIcebreakers || []).join(' | ');\n\nreturn {\n  json: {\n    ...item,\n    generatedAt,\n    salesBriefRow: [\n      generatedAt,\n      item.prospectId || '',\n      item.companyName || '',\n      item.contactName || '',\n      item.contactTitle || '',\n      item.priorityScore || 0,\n      item.companyOverview || '',\n      item.recentNewsSummary || '',\n      item.fundingSummary || '',\n      item.techStackSummary || '',\n      decisionMakersStr,\n      painPointsStr,\n      icebreakersStr,\n      item.recommendedOutreachChannel || '',\n      item.recommendedTiming || '',\n      item.outreachMessageDraft || ''\n    ]\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "f2acf28c-05bc-4e39-a920-9474535195d5",
      "name": "Save Sales Brief to Google Sheets",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        4368,
        512
      ],
      "parameters": {
        "url": "https://sheets.googleapis.com/v4/spreadsheets/YOUR_SHEET_ID/values/SalesBriefs!A1:append?valueInputOption=USER_ENTERED",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"values\": [{{ JSON.stringify($json.salesBriefRow) }}]\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "oAuth2Api"
      },
      "credentials": {
        "oAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "e87c3dd6-0753-49e6-939b-2b1cc5959a4b",
      "name": "Update Prospect Status to Researched",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        4592,
        512
      ],
      "parameters": {
        "url": "=https://sheets.googleapis.com/v4/spreadsheets/YOUR_SHEET_ID/values/Prospects!H{{ $json.rowIndex }}?valueInputOption=USER_ENTERED",
        "method": "PUT",
        "options": {},
        "jsonBody": "={\n  \"values\": [[\"Researched\"]]\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "oAuth2Api"
      },
      "credentials": {
        "oAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "8a762ebc-29c9-4273-ad8e-34e60fc07ac8",
      "name": "Send Slack Notification to Sales Rep",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        4816,
        512
      ],
      "parameters": {
        "url": "YOUR_SLACK_WEBHOOK_URL",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"text\": \":mag: New sales brief ready for *{{ $json.companyName }}* (Priority: {{ $json.priorityScore }}/100)\\n*Contact:* {{ $json.contactName }} - {{ $json.contactTitle }}\\n*Overview:* {{ $json.companyOverview }}\\n*Recommended channel:* {{ $json.recommendedOutreachChannel }} | *Timing:* {{ $json.recommendedTiming }}\\n*Draft message:* {{ $json.outreachMessageDraft }}\"\n}",
        "sendBody": true,
        "specifyBody": "json"
      },
      "typeVersion": 4.2
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "d1126da3-fe34-4c3b-8ab3-b956cfb35523",
  "connections": {
    "Fetch New Prospects": {
      "main": [
        [
          {
            "node": "JS - Parse Prospect Rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out - Prospects": {
      "main": [
        [
          {
            "node": "HTTP Request - Company Website & News Search",
            "type": "main",
            "index": 0
          },
          {
            "node": "HTTP Request - Funding & Technology Data",
            "type": "main",
            "index": 0
          },
          {
            "node": "HTTP Request - Decision Makers Lookup",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait - API Rate Limit": {
      "main": [
        [
          {
            "node": "AI - Generate Sales Research Brief",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "JS - Parse Prospect Rows": {
      "main": [
        [
          {
            "node": "Split Out - Prospects",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Anthropic - Sales Brief Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI - Generate Sales Research Brief",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "JS - Parse Sales Brief Output": {
      "main": [
        [
          {
            "node": "JS - Format Sales Brief Record",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "JS - Format Sales Brief Record": {
      "main": [
        [
          {
            "node": "Save Sales Brief to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Sales Brief to Google Sheets": {
      "main": [
        [
          {
            "node": "Update Prospect Status to Researched",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI - Generate Sales Research Brief": {
      "main": [
        [
          {
            "node": "JS - Parse Sales Brief Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter - Sufficient Data For Brief": {
      "main": [
        [
          {
            "node": "Wait - API Rate Limit",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "JS - Extract Company & News Signals": {
      "main": [
        [
          {
            "node": "Merge - Combine News & Funding Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "JS - Extract Decision Maker Signals": {
      "main": [
        [
          {
            "node": "Merge - Combine All Research Signals",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "JS - Extract Funding & Tech Signals": {
      "main": [
        [
          {
            "node": "Merge - Combine News & Funding Data",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge - Combine News & Funding Data": {
      "main": [
        [
          {
            "node": "Merge - Combine All Research Signals",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge - Combine All Research Signals": {
      "main": [
        [
          {
            "node": "JS - Compile Research Profile & Priority Score",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Prospect Status to Researched": {
      "main": [
        [
          {
            "node": "Send Slack Notification to Sales Rep",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request - Decision Makers Lookup": {
      "main": [
        [
          {
            "node": "JS - Extract Decision Maker Signals",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger - Poll Prospect Queue": {
      "main": [
        [
          {
            "node": "Fetch New Prospects",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request - Funding & Technology Data": {
      "main": [
        [
          {
            "node": "JS - Extract Funding & Tech Signals",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request - Company Website & News Search": {
      "main": [
        [
          {
            "node": "JS - Extract Company & News Signals",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "JS - Compile Research Profile & Priority Score": {
      "main": [
        [
          {
            "node": "Filter - Sufficient Data For Brief",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}