AutomationFlowsAI & RAG › Qualify and Route Free Signups with Twain, Claude, Slack, Hubspot and Gmail

Qualify and Route Free Signups with Twain, Claude, Slack, Hubspot and Gmail

ByMohamed Yahya Chahin @motwain on n8n.io

This workflow receives free-signup events via webhook, enriches the contact with Twain research (and optional Findymail LinkedIn lookup), uses Anthropic Claude to score ICP fit, then routes outcomes to Slack and, for high-fit leads, to HubSpot and Gmail. Receives a POST webhook…

Webhook trigger★★★★★ complexityAI-powered40 nodesSlackHTTP RequestAgentAnthropic ChatOutput Parser StructuredHubSpotGmailGoogle BigQuery
AI & RAG Trigger: Webhook Nodes: 40 Complexity: ★★★★★ AI nodes: yes Added:
Qualify and Route Free Signups with Twain, Claude, Slack, Hubspot and Gmail — n8n workflow card showing Slack, HTTP Request, Agent integration

This workflow corresponds to n8n.io template #16782 — we link there as the canonical source.

This workflow follows the Agent → Gmail 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 →

Download .json
{
  "id": "I4DZYq0e7ZgxSReh",
  "meta": {
    "builderVariant": "mcp",
    "aiBuilderAssisted": true,
    "templateCredsSetupCompleted": true
  },
  "name": "Qualify and route free signups with Twain",
  "tags": [
    {
      "id": "RbQkDoqE7tO0Uf0S",
      "name": "Qualify lead",
      "createdAt": "2026-06-26T10:33:33.657Z",
      "updatedAt": "2026-06-26T10:33:33.657Z"
    },
    {
      "id": "fCnrltXSe85Ec1I8",
      "name": "n8n",
      "createdAt": "2026-06-26T10:33:26.707Z",
      "updatedAt": "2026-06-26T10:33:26.707Z"
    },
    {
      "id": "wZk8565KQmd7c0S5",
      "name": "Twain",
      "createdAt": "2026-06-26T10:33:19.597Z",
      "updatedAt": "2026-06-26T10:33:19.597Z"
    }
  ],
  "nodes": [
    {
      "id": "e5b87045-866c-4179-8f5f-039aa20374be",
      "name": "Signup Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        240,
        528
      ],
      "parameters": {
        "path": "signup-lead-qualify",
        "options": {},
        "httpMethod": "POST",
        "authentication": "headerAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "e136bab6-5b4b-44b8-8661-d4eb4847cfad",
      "name": "Has usable contact?",
      "type": "n8n-nodes-base.if",
      "position": [
        3280,
        560
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "usable-1",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ Boolean($json.has_work_email) || Boolean($json.has_linkedin_url) }}",
              "rightValue": ""
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.3
    },
    {
      "id": "3071075f-8355-4380-82c0-baa8e2f57d58",
      "name": "Slack: Personal email",
      "type": "n8n-nodes-base.slack",
      "onError": "continueRegularOutput",
      "position": [
        3664,
        752
      ],
      "parameters": {
        "text": "=:no_entry_sign:  *Twain \u2014 Qualify & Route Free Signup \u2014 skipped*\n*{{ $('Normalize Signup').item.json.displayName || $('Normalize Signup').item.json.email || 'Unknown signup' }}* ({{ $('Normalize Signup').item.json.email || 'No email provided' }})\n{{ (($('Normalize Signup').item.json.linkedin_url) || '') ? '<' + (($('Normalize Signup').item.json.linkedin_url)) + '|LinkedIn profile>' : '' }}\nNo work email, and the LinkedIn lookup didn't return a profile URL for this signup \u2014 so there's nothing to research or qualify. Enable a LinkedIn Lookup provider (or add a work email / LinkedIn URL upstream) to catch leads like this.\n<https://www.twain.ai/w|Open Twain workspace>",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Settings').item.json.slack_channel }}"
        },
        "otherOptions": {
          "unfurl_links": false,
          "unfurl_media": false,
          "includeLinkToWorkflow": false
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.5
    },
    {
      "id": "57f5a107-40c8-41c7-8df6-18dc5bab8278",
      "name": "Twain Generate Research",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "position": [
        3664,
        560
      ],
      "parameters": {
        "url": "https://public.api.twain.ai/v2/Generate/Research",
        "method": "POST",
        "options": {
          "timeout": 180000
        },
        "jsonBody": "={{ {\n  campaign_id: $('Normalize Signup').item.json.campaign_id,\n  contact: {\n    ...($('Normalize Signup').item.json.has_work_email ? { work_email: $('Normalize Signup').item.json.email } : {}),\n    ...($json.has_linkedin_url ? { linkedin_profile_url: $json.linkedin_url } : {}),\n  },\n  add_contact_to_campaign: true,\n} }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "ac4d8c53-4292-47ba-9cea-e5c59befd797",
      "name": "Stage A \u2014 Hard Disqualify?",
      "type": "n8n-nodes-base.if",
      "position": [
        4048,
        560
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "8e8de89c-59d1-4dff-8271-81a3896c5f54",
              "operator": {
                "type": "array",
                "operation": "contains",
                "rightType": "any"
              },
              "leftValue": "={{ $('Twain Generate Research').item.json.warnings.categories }}",
              "rightValue": "PERSONA_MISMATCH"
            },
            {
              "id": "99e07edb-fc06-4ba3-86e2-4995a996d349",
              "operator": {
                "type": "array",
                "operation": "contains",
                "rightType": "any"
              },
              "leftValue": "={{ $('Twain Generate Research').item.json.warnings.categories }}",
              "rightValue": "INCOMPLETE_PROFILE"
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.3
    },
    {
      "id": "5a8ec23c-c547-489d-9e62-b9f54b76de37",
      "name": "Stage B \u2014 Fit Judge",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        4288,
        688
      ],
      "parameters": {
        "text": "=Prospect company: {{ $('Twain Generate Research').item.json.research?.company?.name || $('Normalize Signup').item.json.displayName || $('Normalize Signup').item.json.email_domain }}\nWebsite: {{ $('Twain Generate Research').item.json.research?.company?.website || '' }}\nCompany size: {{ $('Twain Generate Research').item.json.research?.company?.size || 'unknown' }}\nCompany description: {{ $('Twain Generate Research').item.json.research?.company?.description || '' }}\n\nIndividual: {{ $('Normalize Signup').item.json.displayName || '' }} \u2014 {{ $('Twain Generate Research').item.json.research?.person?.title || '' }} ({{ $('Normalize Signup').item.json.email }})\nHeadline: {{ $('Twain Generate Research').item.json.research?.person?.headline || '' }}\n\nResearch signals:\n- Warnings: {{ JSON.stringify($('Twain Generate Research').item.json.warnings) }}\n- Why now: {{ $('Twain Generate Research').item.json.research?.expanded_research?.why_now?.markdown || 'n/a' }}\n- Why us: {{ $('Twain Generate Research').item.json.research?.expanded_research?.why_us?.markdown || 'n/a' }}\n- Insights: {{ $('Twain Generate Research').item.json.research?.expanded_research?.insights?.markdown || '' }}",
        "options": {
          "systemMessage": "You qualify whether a PROSPECT company is an ICP fit for a B2B product. Be decisive and evidence-based.\n\n=== THE PRODUCT YOU QUALIFY FOR (edit this section for your company) ===\nProduct: Twain \u2014 https://twain.ai\nWhat it does: Twain is an AI sales-research-and-writing platform that turns real-time research into personalized, on-brand B2B outreach (cold email + LinkedIn), with native syncs to tools like Clay and HubSpot. If a web-search tool is connected, search the web (including the product URL) to confirm the current positioning, since it changes often.\n\n=== JOB-TO-BE-DONE THE PRODUCT SERVES ===\n\"When my top-of-funnel outreach hits a performance ceiling because the copy is too generic for high-value accounts, I want an automated system for highly personalized, relevant, scalable communications that natively syncs with my stack (e.g. Clay, HubSpot) so I can launch signal-based engagement and prove the ROI of Demand Gen \u2014 without manual prospecting or risking brand reputation through hallucinated AI.\"\nThe closer the prospect resembles a company that would have this job, the better the fit.\n\n=== ICP TIERS (edit for your company) ===\nTIER 1 (strongest) \u2014 ALL of: >=100 employees; HQ in Europe or North America; raised at least Series B; the individual prospect works in Demand Generation, Growth, GTM, or RevOps. Reference Tier-1 customers (look for resemblance): ashbyhq.com, xentral.com, everstage.com, graviteesource.com, rechargeapps.com, factorialhr.co, tracksuit.com.\nTIER 2 (good) \u2014 ALL of: >=11 and <5000 employees; a genuine B2B company with a B2B offering; at least 1 year old; NOT a lead-generation agency, recruiting agency, freelancer, or marketing agency. Reference Tier-2 customers: vumo.ai, nory.ai, getnnuvo.com, cotiss.com.\nNO FIT \u2014 fails the Tier-2 bar, or is a disqualified type (lead-gen/recruiting/marketing agency, freelancer, B2C-only, <1 year old, >5000 employees, or clearly off-ICP).\n\n=== HOW TO JUDGE ===\n1. Understand the product (above; use a connected web-search tool if available).\n2. Understand the prospect from the research provided in the user message (company size, description, region, funding/maturity, B2B model, the individual's role) plus the why-now / why-us / warnings signals; if a web-search tool is connected, also look up the prospect's website to confirm.\n3. Compare against the tiers and reference customers; assess the job-to-be-done fit.\n4. Pick the single best tier. If a hard Tier-1 criterion is unknown, do not assume it \u2014 fall to Tier 2 if Tier-2 criteria are met, else NO FIT.\n\nReturn ONLY the structured object: analysis (comprehensive reasoning citing the strongest concrete signals \u2014 size, region, funding, role, B2B model, resemblance to reference customers, JTBD match); summary (1-2 sentences); tier (exactly \"TIER 1\", \"TIER 2\", or \"NO FIT\")."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "0f7239d7-3799-4f65-a99c-9c60271da518",
      "name": "Claude Sonnet 4.6",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        4160,
        848
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "id",
          "value": "claude-sonnet-4-6",
          "cachedResultName": "Claude Sonnet 4.6"
        },
        "options": {
          "temperature": 0.1
        }
      },
      "credentials": {
        "anthropicApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.5
    },
    {
      "id": "0248db4c-fdf0-477f-8d2d-9ecfd931dd06",
      "name": "Fit Verdict Schema",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        4544,
        848
      ],
      "parameters": {
        "jsonSchemaExample": "{ \"analysis\": \"RevOps leader at a Series-C B2B SaaS (~400 FTE, US) running outbound \u2014 closely resembles Everstage/Ashby; strong JTBD match.\", \"summary\": \"Strong Tier-1 fit: large NA B2B SaaS with a RevOps buyer and a clear personalization-at-scale need.\", \"tier\": \"TIER 1\" }"
      },
      "typeVersion": 1.3
    },
    {
      "id": "c5a14b42-2b83-41bf-98f6-e4151bd5d5b0",
      "name": "Is High Fit?",
      "type": "n8n-nodes-base.if",
      "position": [
        4800,
        528
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "4300371c-0841-48d9-8392-39f6f9dd308c",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.output?.tier ?? $json.tier ?? '' }}",
              "rightValue": "TIER 1"
            },
            {
              "id": "cef49b99-1cd3-4b4e-991e-40d38552f542",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.output?.tier ?? $json.tier ?? '' }}",
              "rightValue": "TIER 2"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "97d7a1ee-16d0-4b46-8c99-5a95e0459b2a",
      "name": "High Fit (A/B)",
      "type": "n8n-nodes-base.noOp",
      "position": [
        5184,
        528
      ],
      "parameters": {},
      "executeOnce": false,
      "typeVersion": 1
    },
    {
      "id": "b3aaea39-c00c-4445-8e32-6f31f0d3ae22",
      "name": "Slack: Twain error",
      "type": "n8n-nodes-base.slack",
      "onError": "continueRegularOutput",
      "position": [
        3904,
        752
      ],
      "parameters": {
        "text": "=:warning:  *Twain research failed*\n*{{ $('Normalize Signup').item.json.displayName || $('Normalize Signup').item.json.email || 'Unknown signup' }}* ({{ $('Normalize Signup').item.json.email || 'No email provided' }})\n{{ (($('Normalize Signup').item.json.linkedin_url) || '') ? '<' + (($('Normalize Signup').item.json.linkedin_url)) + '|LinkedIn profile>' : '' }}\n*Error:*\n{{ ((String($json.error?.message ?? $json.message ?? '').replace(/^\\s*\\d{3}\\s*-\\s*/, '').trim()).includes('\"message\":\"') ? (((String($json.error?.message ?? $json.message ?? '').replace(/^\\s*\\d{3}\\s*-\\s*/, '').trim()).split('\"message\":\"')[1] || '').split('\"')[0].replace(/\\\\/g, '')) : String($json.error?.message ?? $json.message ?? '').replace(/^\\s*\\d{3}\\s*-\\s*/, '').trim()) || 'Unknown error' }}\n<https://www.twain.ai/w|Open Twain workspace>",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Settings').item.json.slack_channel }}"
        },
        "otherOptions": {
          "unfurl_links": false,
          "unfurl_media": false,
          "includeLinkToWorkflow": false
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.5
    },
    {
      "id": "69d4ba16-d74b-462b-bede-17d1c697c093",
      "name": "Slack: High-fit alert",
      "type": "n8n-nodes-base.slack",
      "onError": "continueRegularOutput",
      "position": [
        5568,
        304
      ],
      "parameters": {
        "text": "=*High-fit signup*\n*{{ $('Twain Generate Research').item.json.research?.person?.name || $('Normalize Signup').item.json.displayName || $('Normalize Signup').item.json.email }}* ({{ $('Normalize Signup').item.json.email }}){{ ([$('Twain Generate Research').item.json.research?.person?.title, $('Twain Generate Research').item.json.research?.company?.name].filter(Boolean).join(' @ ')) ? ' \u00b7 ' + ([$('Twain Generate Research').item.json.research?.person?.title, $('Twain Generate Research').item.json.research?.company?.name].filter(Boolean).join(' @ ')) : '' }}\n{{ (($('Twain Generate Research').item.json?.research?.person?.linkedin_profile_url) || ($('Normalize Signup').item.json.linkedin_url) || '') ? '<' + (($('Twain Generate Research').item.json?.research?.person?.linkedin_profile_url) || ($('Normalize Signup').item.json.linkedin_url)) + '|LinkedIn profile>' : '' }}\n*Tier:* {{ $('Stage B \u2014 Fit Judge').item.json.output?.tier ?? $('Stage B \u2014 Fit Judge').item.json.tier ?? 'Unknown' }}\n*Fit:* {{ $('Stage B \u2014 Fit Judge').item.json.output?.summary ?? $('Stage B \u2014 Fit Judge').item.json.summary ?? 'No fit summary returned.' }}\n*Why now:*\n{{ $('Twain Generate Research').item.json.research?.expanded_research?.why_now?.markdown || 'No why-now summary returned.' }}\n<{{ $('Twain Generate Research').item.json.link }}|Open lead in Twain>",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Settings').item.json.slack_channel }}"
        },
        "otherOptions": {
          "unfurl_links": false,
          "unfurl_media": false,
          "includeLinkToWorkflow": false
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": false,
      "typeVersion": 2.5
    },
    {
      "id": "63d3862e-16a6-492d-b3f3-cb6a28cb8e2a",
      "name": "HubSpot: Upsert Contact",
      "type": "n8n-nodes-base.hubspot",
      "onError": "continueRegularOutput",
      "position": [
        5568,
        528
      ],
      "parameters": {
        "email": "={{ $('Normalize Signup').item.json.email }}",
        "options": {},
        "authentication": "oAuth2",
        "additionalFields": {
          "jobTitle": "={{ $('Twain Generate Research').item.json.research.person.title }}",
          "websiteUrl": "={{ $('Twain Generate Research').item.json.research.company.website }}",
          "companyName": "={{ $('Twain Generate Research').item.json.research.company.name }}",
          "linkedinUrl": "={{ $('Twain Generate Research').item.json.research.person.linkedin_profile_url }}",
          "customPropertiesUi": {
            "customPropertiesValues": [
              {
                "value": "={{ $('Stage B \u2014 Fit Judge').item.json.output?.tier ?? $('Stage B \u2014 Fit Judge').item.json.tier ?? '' }}",
                "property": "twain_fit_tier"
              },
              {
                "value": "={{ $('Stage B \u2014 Fit Judge').item.json.output?.summary ?? $('Stage B \u2014 Fit Judge').item.json.summary ?? '' }}",
                "property": "twain_fit_reason"
              }
            ]
          }
        }
      },
      "credentials": {
        "hubspotOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "f47d6093-1629-4df4-83b8-a4570204acb7",
      "name": "Email Owning AE",
      "type": "n8n-nodes-base.gmail",
      "onError": "continueRegularOutput",
      "position": [
        5568,
        752
      ],
      "parameters": {
        "message": "=<p><strong>High-fit signup</strong></p><p><strong>Tier:</strong> {{ $('Stage B \u2014 Fit Judge').item.json.output?.tier ?? $('Stage B \u2014 Fit Judge').item.json.tier ?? 'Unknown' }}</p><p><strong>{{ $('Twain Generate Research').item.json.research.person.name }}</strong>{{ $('Twain Generate Research').item.json.research.person.title ? ' \u2014 ' + $('Twain Generate Research').item.json.research.person.title : '' }}{{ $('Twain Generate Research').item.json.research.company.name ? ' @ ' + $('Twain Generate Research').item.json.research.company.name : '' }}<br/>{{ $('Normalize Signup').item.json.email }}</p><p><strong>Fit summary:</strong> {{ $('Stage B \u2014 Fit Judge').item.json.output?.summary ?? $('Stage B \u2014 Fit Judge').item.json.summary ?? 'No fit summary returned.' }}</p><p><a href=\"{{ $('Twain Generate Research').item.json.link }}\">Open in Twain</a></p>",
        "options": {},
        "subject": "=High-fit signup: {{ $('Twain Generate Research').item.json.research.person.name }} ({{ $('Twain Generate Research').item.json.research.company.name }}) \u2014 {{ $('Stage B \u2014 Fit Judge').item.json.output?.tier ?? $('Stage B \u2014 Fit Judge').item.json.tier ?? 'Unknown' }}",
        "resource": "draft"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c9efb69f-40a8-47d1-a5ea-5d0d3c29fa1c",
      "name": "Dedupe New Signups",
      "type": "n8n-nodes-base.removeDuplicates",
      "position": [
        1392,
        528
      ],
      "parameters": {
        "options": {
          "scope": "node",
          "historySize": 100000
        },
        "operation": "removeItemsSeenInPreviousExecutions",
        "dedupeValue": "={{ $json.uid }}"
      },
      "typeVersion": 2
    },
    {
      "id": "40137c3e-58b3-4e19-b5a7-dd652841f51a",
      "name": "Schedule: BigQuery backfill",
      "type": "n8n-nodes-base.scheduleTrigger",
      "disabled": true,
      "position": [
        240,
        704
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours"
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "de834cef-8461-456a-85b1-d13e50512155",
      "name": "BigQuery: New signups",
      "type": "n8n-nodes-base.googleBigQuery",
      "disabled": true,
      "position": [
        624,
        960
      ],
      "parameters": {
        "options": {},
        "sqlQuery": "-- Backfill: new signups since last run. Alias columns to uid/email/displayName/signup_ts.\nSELECT uid, email, display_name AS displayName, signup_ts\nFROM `your_dataset.signups`\nWHERE signup_ts > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)\nORDER BY signup_ts",
        "projectId": {
          "__rl": true,
          "mode": "id",
          "value": "REPLACE_WITH_GCP_PROJECT_ID"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "57cf8da0-6a06-4d71-b738-2a77db5dc5e3",
      "name": "Schedule: Firestore poll",
      "type": "n8n-nodes-base.scheduleTrigger",
      "disabled": true,
      "position": [
        240,
        864
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 15
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "620d442a-5979-4807-b653-b866e197c1ec",
      "name": "Firestore: New customers",
      "type": "n8n-nodes-base.googleFirebaseCloudFirestore",
      "disabled": true,
      "position": [
        624,
        1184
      ],
      "parameters": {
        "query": "{\n  \"from\": [{ \"collectionId\": \"customers\" }],\n  \"orderBy\": [{ \"field\": { \"fieldPath\": \"created_at\" }, \"direction\": \"DESCENDING\" }],\n  \"limit\": 50\n}",
        "operation": "query",
        "projectId": "REPLACE_WITH_FIREBASE_PROJECT_ID",
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "bc64fcb1-8681-4bfa-bb8c-3c36361ee5ad",
      "name": "Slack: Disqualified",
      "type": "n8n-nodes-base.slack",
      "onError": "continueRegularOutput",
      "position": [
        4400,
        528
      ],
      "parameters": {
        "text": "=:no_entry:  *Signup disqualified at Stage A*\n*{{ $('Twain Generate Research').item.json.research?.person?.name || $('Normalize Signup').item.json.displayName || $('Normalize Signup').item.json.email }}* ({{ $('Normalize Signup').item.json.email }})\n{{ (($('Twain Generate Research').item.json?.research?.person?.linkedin_profile_url) || ($('Normalize Signup').item.json.linkedin_url) || '') ? '<' + (($('Twain Generate Research').item.json?.research?.person?.linkedin_profile_url) || ($('Normalize Signup').item.json.linkedin_url)) + '|LinkedIn profile>' : '' }}\n<{{ $('Twain Generate Research').item.json.link }}|Open lead in Twain>",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Settings').item.json.slack_channel }}"
        },
        "otherOptions": {
          "unfurl_links": false,
          "unfurl_media": false,
          "includeLinkToWorkflow": false
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.5
    },
    {
      "id": "fe544299-13dc-4a0e-b658-d612eefec88e",
      "name": "Slack: Low fit (C)",
      "type": "n8n-nodes-base.slack",
      "onError": "continueRegularOutput",
      "position": [
        5184,
        752
      ],
      "parameters": {
        "text": "=:heavy_multiplication_x:  *Not a fit (NO FIT)*\n*{{ $('Twain Generate Research').item.json.research?.person?.name || $('Normalize Signup').item.json.displayName || $('Normalize Signup').item.json.email }}* ({{ $('Normalize Signup').item.json.email }}){{ ([$('Twain Generate Research').item.json.research?.person?.title, $('Twain Generate Research').item.json.research?.company?.name].filter(Boolean).join(' @ ')) ? ' \u00b7 ' + ([$('Twain Generate Research').item.json.research?.person?.title, $('Twain Generate Research').item.json.research?.company?.name].filter(Boolean).join(' @ ')) : '' }}\n{{ (($('Twain Generate Research').item.json?.research?.person?.linkedin_profile_url) || ($('Normalize Signup').item.json.linkedin_url) || '') ? '<' + (($('Twain Generate Research').item.json?.research?.person?.linkedin_profile_url) || ($('Normalize Signup').item.json.linkedin_url)) + '|LinkedIn profile>' : '' }}\n*Tier:* {{ $('Stage B \u2014 Fit Judge').item.json.output?.tier ?? $('Stage B \u2014 Fit Judge').item.json.tier ?? 'Unknown' }}\n*Fit:* {{ $('Stage B \u2014 Fit Judge').item.json.output?.summary ?? $('Stage B \u2014 Fit Judge').item.json.summary ?? 'No fit summary returned.' }}\n<{{ $('Twain Generate Research').item.json.link }}|Open lead in Twain>",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Settings').item.json.slack_channel }}"
        },
        "otherOptions": {
          "unfurl_links": false,
          "unfurl_media": false,
          "includeLinkToWorkflow": false
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.5
    },
    {
      "id": "ba507a33-13dc-4008-a4e8-2f918d80affa",
      "name": "Normalize Signup",
      "type": "n8n-nodes-base.set",
      "position": [
        1008,
        528
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "uid",
              "name": "uid",
              "type": "string",
              "value": "={{ $json.body?.uid ?? $json.uid }}"
            },
            {
              "id": "email",
              "name": "email",
              "type": "string",
              "value": "={{ ($json.body?.email ?? $json.email ?? \"\").toLowerCase().trim() }}"
            },
            {
              "id": "displayName",
              "name": "displayName",
              "type": "string",
              "value": "={{ $json.body?.displayName ?? $json.displayName ?? \"\" }}"
            },
            {
              "id": "signup_ts",
              "name": "signup_ts",
              "type": "string",
              "value": "={{ $json.body?.signup_ts ?? $json.signup_ts ?? $now.toISO() }}"
            },
            {
              "id": "campaign_id",
              "name": "campaign_id",
              "type": "string",
              "value": "={{ $(\"Settings\").item.json.campaign_id }}"
            },
            {
              "id": "linkedin_url",
              "name": "linkedin_url",
              "type": "string",
              "value": "={{ ($json.body?.linkedin_url ?? $json.body?.linkedin_profile_url ?? $json.linkedin_url ?? $json.linkedin_profile_url ?? \"\").trim() }}"
            },
            {
              "id": "email_domain",
              "name": "email_domain",
              "type": "string",
              "value": "={{ ((($json.body?.email ?? $json.email ?? \"\").toLowerCase().trim()).split(\"@\")[1] ?? \"\").toLowerCase() }}"
            },
            {
              "id": "is_personal_email",
              "name": "is_personal_email",
              "type": "boolean",
              "value": "={{ [\"gmail.com\",\"googlemail.com\",\"outlook.com\",\"hotmail.com\",\"live.com\",\"msn.com\",\"yahoo.com\",\"ymail.com\",\"icloud.com\",\"me.com\",\"mac.com\",\"proton.me\",\"protonmail.com\",\"aol.com\",\"gmx.com\",\"gmx.net\",\"zoho.com\",\"pm.me\",\"mail.com\",\"yandex.com\"].includes(((($json.body?.email ?? $json.email ?? \"\").toLowerCase().trim()).split(\"@\")[1] ?? \"\").toLowerCase()) }}"
            },
            {
              "id": "has_linkedin_url",
              "name": "has_linkedin_url",
              "type": "boolean",
              "value": "={{ Boolean(($json.body?.linkedin_url ?? $json.body?.linkedin_profile_url ?? $json.linkedin_url ?? $json.linkedin_profile_url ?? \"\").trim()) }}"
            },
            {
              "id": "has_work_email",
              "name": "has_work_email",
              "type": "boolean",
              "value": "={{ Boolean((($json.body?.email ?? $json.email ?? \"\").toLowerCase().trim())) && ![\"gmail.com\",\"googlemail.com\",\"outlook.com\",\"hotmail.com\",\"live.com\",\"msn.com\",\"yahoo.com\",\"ymail.com\",\"icloud.com\",\"me.com\",\"mac.com\",\"proton.me\",\"protonmail.com\",\"aol.com\",\"gmx.com\",\"gmx.net\",\"zoho.com\",\"pm.me\",\"mail.com\",\"yandex.com\"].includes((((($json.body?.email ?? $json.email ?? \"\").toLowerCase().trim()).split(\"@\")[1] ?? \"\").toLowerCase())) }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "21178752-fe72-4012-a3cf-feb6390eef8d",
      "name": "Needs LinkedIn Lookup?",
      "type": "n8n-nodes-base.if",
      "position": [
        1760,
        528
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "needs-li-1",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ !$('Normalize Signup').item.json.has_linkedin_url && Boolean($('Normalize Signup').item.json.email) }}",
              "rightValue": ""
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.3
    },
    {
      "id": "23ac4183-d3c6-4d8e-8a22-77025934344b",
      "name": "LinkedIn Lookup \u2014 Findymail",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "position": [
        2144,
        304
      ],
      "parameters": {
        "url": "https://app.findymail.com/api/search/reverse-email",
        "method": "POST",
        "options": {
          "timeout": 30000
        },
        "jsonBody": "={{ { email: $('Normalize Signup').item.json.email, with_profile: true } }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        },
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "2e8c96f2-7a78-4849-90ae-43c8115954e5",
      "name": "Apply Resolved LinkedIn",
      "type": "n8n-nodes-base.code",
      "position": [
        2528,
        304
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Resolve LinkedIn URL from the provider response.\n// Adjust the field below to match YOUR provider's response shape.\nconst resp = $json || {};\nconst linkedin_url = resp.linkedin_url ?? resp.linkedin_profile_url ?? resp.url ?? resp.contact?.linkedin_url ?? resp.profile?.linkedin_url ?? resp.person?.linkedin_url ?? resp.data?.linkedin_url ?? resp.response?.linkedin_url ?? \"\";\n\n// Carry forward all normalized fields, overriding only the LinkedIn ones.\nconst n = $('Normalize Signup').item.json;\nreturn {\n  ...n,\n  linkedin_url: linkedin_url,\n  has_linkedin_url: Boolean(linkedin_url)\n};\n"
      },
      "typeVersion": 2
    },
    {
      "id": "99a2b760-f06b-4e79-a21a-9efcf97f1a31",
      "name": "Resolved Contact",
      "type": "n8n-nodes-base.merge",
      "position": [
        2912,
        528
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "f5f07945-95b6-4181-b5c5-9be06207d7e4",
      "name": "LinkedIn Lookup \u2014 Apollo",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "disabled": true,
      "position": [
        2144,
        80
      ],
      "parameters": {
        "url": "https://api.apollo.io/api/v1/people/match",
        "method": "POST",
        "options": {
          "timeout": 30000
        },
        "jsonBody": "={{ { email: $('Normalize Signup').item.json.email } }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.4
    },
    {
      "id": "5a14c68c-da13-4546-abdf-d3d4f988ea88",
      "name": "LinkedIn Lookup \u2014 People Data Labs",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "disabled": true,
      "position": [
        2144,
        -144
      ],
      "parameters": {
        "url": "=https://api.peopledatalabs.com/v5/person/enrich?email={{ encodeURIComponent($('Normalize Signup').item.json.email) }}",
        "options": {
          "timeout": 30000
        },
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.4
    },
    {
      "id": "627f1cca-fbda-4f5f-af51-f47dd25c9a41",
      "name": "LinkedIn Lookup \u2014 Proxycurl",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "disabled": true,
      "position": [
        2144,
        -368
      ],
      "parameters": {
        "url": "=https://nubela.co/proxycurl/api/linkedin/profile/resolve/email?email={{ encodeURIComponent($('Normalize Signup').item.json.email) }}",
        "options": {
          "timeout": 30000
        },
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.4
    },
    {
      "id": "c70fb2d6-7a66-493f-b032-02f45bbe5bc9",
      "name": "Sticky: Section 1 Intake",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        144,
        368
      ],
      "parameters": {
        "color": 7,
        "width": 1520,
        "height": 1000,
        "content": "### 1 \u00b7 Intake & dedupe\n\nEach new signup arrives via the **webhook** (or an optional BigQuery / Firestore backfill) and is normalized to a common shape. Duplicate `uid`s are then dropped, so every person is processed only once."
      },
      "typeVersion": 1
    },
    {
      "id": "4d47cca4-066e-48a4-9ae5-8b43665c4ed3",
      "name": "Sticky: Section 2 Resolve",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1712,
        -464
      ],
      "parameters": {
        "color": 7,
        "width": 1400,
        "height": 1180,
        "content": "### 2 \u00b7 Resolve contact\n\nSignups on a **personal email** get a LinkedIn / work-email lookup so Twain has a real person to research. Work-email signups skip this. Only one lookup provider is needed."
      },
      "typeVersion": 1
    },
    {
      "id": "dee205d4-56c0-4c9e-b82e-6ac3a3a6d60a",
      "name": "Sticky: Section 3 Qualify",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3120,
        400
      ],
      "parameters": {
        "color": 7,
        "width": 1580,
        "height": 616,
        "content": "### 3 \u00b7 Qualify \u2014 Twain research + 2-stage judge\n\n**The core.** Twain Deep Research enriches the contact, a fast **Stage A** gate hard-disqualifies obvious no-gos, and **Stage B** (an LLM fit judge) scores the rest **A / B / C** with a reason \u2014 fewer LLM calls, grounded decisions."
      },
      "typeVersion": 1
    },
    {
      "id": "e100f989-f677-4bfc-9bc0-ac2b896f981a",
      "name": "Sticky: Section 4 Route",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4768,
        208
      ],
      "parameters": {
        "color": 7,
        "width": 1120,
        "height": 740,
        "content": "### 4 \u00b7 Route the decision\n\n**High fit (A / B)** \u2192 Slack alert + HubSpot upsert + email the owning AE.\n**Low fit (C)**, **disqualified**, and **errors** are posted to Slack \u2014 so nothing is silently dropped."
      },
      "typeVersion": 1
    },
    {
      "id": "9b17a604-59c1-4f54-af43-93f52b480669",
      "name": "Sticky: Try it out",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -976,
        -128
      ],
      "parameters": {
        "width": 900,
        "height": 1880,
        "content": "## Try It Out!\n\nThis n8n template turns inbound **free signups** into qualified, routed leads \u2014 automatically. For each new signup it resolves a real work contact, runs **Twain Deep Research**, scores fit with a two-stage judge, and routes the result: high-fit leads to Slack + HubSpot + the owning AE, everyone else to Slack for visibility.\n\n### Who's it for\n\nPLG and sales teams that get inbound free signups and want the good-fit ones in front of a human fast \u2014 while the rest are filtered out, with no manual triage.\n\n### How it works\n\n- **Intake** \u2014 a signup hits the webhook (or an optional BigQuery / Firestore backfill), is normalized, and de-duplicated by `uid`.\n- **Resolve contact** \u2014 personal-email signups get a LinkedIn / work-email lookup so there's a real person to research.\n- **Qualify** \u2014 **Twain Deep Research** turns the bare signup into a real profile (person, role, company, industry, size, buying signals). **Stage A** then hard-disqualifies obvious no-gos and **Stage B** (an LLM judge) scores the rest A / B / C on facts, with a reason.\n- **Route** \u2014 high fit \u2192 Slack alert + HubSpot upsert + email the AE; low-fit, disqualified, and errors \u2192 Slack.\n\n### Why Twain Deep Research\n\nA signup is just an email and maybe a name \u2014 not enough to decide fit or personalize routing. Twain enriches it into a full picture of the person and their company (role, seniority, industry, size, signals), so the judge scores on **real data, not the email domain**, and the AE gets context to act on right away.\n\n### How to set up\n\n- **Add credentials:** Twain (HTTP Header Auth, header `X-Api-Key`), a LinkedIn-lookup provider (Findymail by default), Anthropic, Slack, HubSpot, and Gmail.\n- **Configure:** open the **Settings** node and set `campaign_id`, `slack_channel`, and `ae_email` (the AE inbox to notify).\n- **Tune the judge:** edit the **Stage B \u2014 Fit Judge** prompt \u2014 and the **Stage A** disqualify rules \u2014 to define what a good-fit signup means for your ICP.\n- **Trigger:** POST signups to the **Signup Webhook** as `{ email, displayName, linkedin_url, uid, signup_ts }`.\n\n### Requirements\n\nA **Twain** account + API key and a campaign; a LinkedIn-lookup provider (**Findymail**, Apollo, People Data Labs, or Proxycurl); and **Anthropic**, **Slack**, **HubSpot**, and **Gmail** credentials.\n\n### How to customize\n\n- Swap the lookup provider, or enable a **BigQuery / Firestore** backfill trigger instead of the webhook.\n- Route each tier differently (e.g., separate Slack channels, or auto-create tasks for A-tier).\n\nBuilt with Twain \u2014 https://www.twain.ai"
      },
      "typeVersion": 1
    },
    {
      "id": "50eb4258-2655-4962-99ac-93ee07633ead",
      "name": "Sticky: Alt intake",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1008,
        816
      ],
      "parameters": {
        "color": 7,
        "width": 560,
        "height": 150,
        "content": "**Optional intake** \u2014 enable a **BigQuery** or **Firestore** trigger to pull signups on a schedule instead of (or alongside) the webhook. Disabled by default."
      },
      "typeVersion": 1
    },
    {
      "id": "8d1bda58-6c09-47bc-9954-d8fc5cc2c9c4",
      "name": "Sticky: Alt LinkedIn",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1712,
        -608
      ],
      "parameters": {
        "color": 7,
        "width": 1120,
        "height": 130,
        "content": "**Swap the lookup provider** \u2014 Apollo \u00b7 People Data Labs \u00b7 Proxycurl are pre-wired. Enable one, disable the rest. Only one is needed."
      },
      "typeVersion": 1
    },
    {
      "id": "12321568-0557-4181-8f77-c1ef7394c68f",
      "name": "Sticky: config",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        560,
        368
      ],
      "parameters": {
        "color": 7,
        "width": 560,
        "height": 150,
        "content": "\u2699\ufe0f **Config lives here** \u2014 set `campaign_id`, `slack_channel`, and `ae_email` in this **Settings** node. Every downstream node reads from it."
      },
      "typeVersion": 1
    },
    {
      "id": "bc8e6486-ad02-4939-8cc8-6ff8c6130fdd",
      "name": "Settings",
      "type": "n8n-nodes-base.set",
      "position": [
        624,
        528
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "campaign_id",
              "name": "campaign_id",
              "type": "string",
              "value": "YOUR_TWAIN_CAMPAIGN_ID"
            },
            {
              "id": "slack_channel",
              "name": "slack_channel",
              "type": "string",
              "value": "signups"
            },
            {
              "id": "ae_email",
              "name": "ae_email",
              "type": "string",
              "value": "user@example.com"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "47c668d5-6405-4f76-b6b8-92995f55805a",
      "name": "Sticky: why-research",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3120,
        208
      ],
      "parameters": {
        "color": 7,
        "width": 772,
        "height": 170,
        "content": "\ud83d\udd0e **Why Twain Deep Research?** A bare signup \u2014 an email, maybe a name \u2014 isn't enough to judge fit. Twain enriches it into a real profile: person, role & seniority, company, industry, size, and buying signals \u2014 so the judge decides on **facts, not the email domain**, and the AE gets full context to act on."
      },
      "typeVersion": 1
    },
    {
      "id": "120c1466-ef64-4c23-9b6d-bd2ea526ed18",
      "name": "Sticky: judge",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3920,
        208
      ],
      "parameters": {
        "color": 7,
        "width": 780,
        "height": 170,
        "content": "\u270f\ufe0f **Tune the fit judge** \u2014 edit this **Stage B \u2014 Fit Judge** prompt to define your ICP and what makes an A / B / C lead. Also adjust the **Stage A** hard-disqualify rules to match your business."
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": true,
    "executionOrder": "v1"
  },
  "versionId": "a9cd08fd-baa8-40da-9899-2813eaa6b140",
  "nodeGroups": [],
  "connections": {
    "Settings": {
      "main": [
        [
          {
            "node": "Normalize Signup",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is High Fit?": {
      "main": [
        [
          {
            "node": "High Fit (A/B)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Slack: Low fit (C)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "High Fit (A/B)": {
      "main": [
        [
          {
            "node": "Slack: High-fit alert",
            "type": "main",
            "index": 0
          },
          {
            "node": "HubSpot: Upsert Contact",
            "type": "main",
            "index": 0
          },
          {
            "node": "Email Owning AE",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Signup Webhook": {
      "main": [
        [
          {
            "node": "Settings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Signup": {
      "main": [
        [
          {
            "node": "Dedupe New Signups",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Resolved Contact": {
      "main": [
        [
          {
            "node": "Has usable contact?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude Sonnet 4.6": {
      "ai_languageModel": [
        [
          {
            "node": "Stage B \u2014 Fit Judge",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Dedupe New Signups": {
      "main": [
        [
          {
            "node": "Needs LinkedIn Lookup?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fit Verdict Schema": {
      "ai_outputParser": [
        [
          {
            "node": "Stage B \u2014 Fit Judge",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Has usable contact?": {
      "main": [
        [
          {
            "node": "Twain Generate Research",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Slack: Personal email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "BigQuery: New signups": {
      "main": [
        [
          {
            "node": "Settings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Stage B \u2014 Fit Judge": {
      "main": [
        [
          {
            "node": "Is High Fit?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Needs LinkedIn Lookup?": {
      "main": [
        [
          {
            "node": "LinkedIn Lookup \u2014 Findymail",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Resolved Contact",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Apply Resolved LinkedIn": {
      "main": [
        [
          {
            "node": "Resolved Contact",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Twain Generate Research": {
      "main": [
        [
          {
            "node": "Stage A \u2014 Hard Disqualify?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Slack: Twain error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Firestore: New customers": {
      "main": [
        [
          {
            "node": "Settings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule: Firestore poll": {
      "main": [
        [
          {
            "node": "Firestore: New customers",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule: BigQuery backfill": {
      "main": [
        [
          {
            "node": "BigQuery: New signups",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Stage A \u2014 Hard Disqualify?": {
      "main": [
        [
          {
            "node": "Slack: Disqualified",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Stage B \u2014 Fit Judge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "LinkedIn Lookup \u2014 Findymail": {
      "main": [
        [
          {
            "node": "Apply Resolved LinkedIn",
            "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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow receives free-signup events via webhook, enriches the contact with Twain research (and optional Findymail LinkedIn lookup), uses Anthropic Claude to score ICP fit, then routes outcomes to Slack and, for high-fit leads, to HubSpot and Gmail. Receives a POST webhook…

Source: https://n8n.io/workflows/16782/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

This template uses the Apify LinkedIn Profile Scraper, which is a community node only available in self-hosted n8n installations. The LinkedIn scraping step is optional and can be removed for n8n Clou

HTTP Request, Perplexity, Slack +8
AI & RAG

Fully automates your service order pipeline from incoming booking to supplier confirmation — with built-in SLA enforcement and automatic escalation if a supplier goes silent. 📥 Receives orders via web

HTTP Request, Google Sheets, Agent +4
AI & RAG

My workflow 250630. Uses httpRequest, lmChatOpenAi, outputParserStructured, gmail. Event-driven trigger; 37 nodes.

HTTP Request, OpenAI Chat, Output Parser Structured +5
AI & RAG

This workflow automates end-to-end contract analysis using AI. It extracts clauses, evaluates risks, tracks obligations, and generates an executive summary from uploaded contracts.

Agent, Anthropic Chat, Output Parser Structured +3
AI & RAG

This workflow receives a meeting voice recording via webhook, transcribes it with Deepgram, and uses Google Gemini to extract client details and next-step tasks. It then updates GoHighLevel, posts a t

High Level, Agent, Google Gemini Chat +5