Nodes:
name: When clicking "Test workflow"
type: n8n-nodes-base.manualTrigger
name: Input
type: n8n-nodes-base.set
parameters: assignments: assignments: name: company_input
type: string
value: ={{ $json.input }}
name: row_number
type: number
value: ={{ $json.row_number }}
name: OpenAI Chat Model
type: @n8n/n8n-nodes-langchain.lmChatOpenAi
parameters: model: gpt-4o
options: temperature: 0.3
name: Get website content
type: @n8n/n8n-nodes-langchain.toolWorkflow
parameters: name: get_website_content
source: parameter
description: This tool will return the text from the given URL. 
workflowJson: {
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "2b1cc1a8b0a2fb9caab11ab2d5eb3712f9973066051b2e898cf4041a1f2a7757"
  },
  "nodes": [
    {
      "parameters": {},
      "id": "475eaf3c-7e11-457e-8b72-4d3e683e2f80",
      "name": "Execute Workflow Trigger",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "typeVersion": 1,
      "position": [
        260,
        340
      ]
    },
    {
      "parameters": {
        "url": "={{ $json.query.url }}",
        "options": {}
      },
      "id": "321fbc74-d749-4f9b-954e-7cad37601ddf",
      "name": "Visit Website",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        440,
        340
      ]
    },
    {
      "parameters": {
        "operation": "extractHtmlContent",
        "extractionValues": {
          "values": [
            {
              "key": "body",
              "cssSelector": "html",
              "skipSelectors": "head"
            }
          ]
        },
        "options": {
          "cleanUpText": true
        }
      },
      "id": "6e51732a-4999-4805-838b-f692e9965197",
      "name": "HTML",
      "type": "n8n-nodes-base.html",
      "typeVersion": 1.2,
      "position": [
        620,
        340
      ]
    }
  ],
  "connections": {
    "Execute Workflow Trigger": {
      "main": [
        [
          {
            "node": "Visit Website",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Visit Website": {
      "main": [
        [
          {
            "node": "HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {
    "Execute Workflow Trigger": [
      {
        "query": {
          "url": "https://www.lemlist.com"
        }
      }
    ]
  }
}
jsonSchemaExample: url: https://www.lemlist.com
specifyInputSchema: yes
responsePropertyName: body
name: SerpAPI - Search Google
type: @n8n/n8n-nodes-langchain.toolSerpApi
name: Structured Output Parser
type: @n8n/n8n-nodes-langchain.outputParserStructured
parameters: schemaType: manual
inputSchema: {
	"type": "object",
	"properties": {
		"case_study_link": {
			"type":["string", "null"]
		},
      		"domain": {
			"type": ["string", "null"]
		},
           "linkedinUrl": {
			"type": ["string", "null"]
		},
     	"market": {
			"type": ["string", "null"]
		},
		"cheapest_plan": {
			"type": ["number", "null"]
		},
	"has_enterprise_plan": {
			"type": ["boolean", "null"]
		},
	"has_API": {
			"type": ["boolean", "null"]
		},
	"has_free_trial": {
			"type": ["boolean", "null"]
		},
	"integrations": {
			"type": ["array","null"],
      "items": {
				"type": "string"
			}
		}
	}
}
name: Loop Over Items
type: n8n-nodes-base.splitInBatches
name: AI Researcher Output Data
type: n8n-nodes-base.set
parameters: assignments: assignments: name: domain
type: string
value: ={{ $json.output.domain }}
name: linkedinUrl
type: string
value: ={{ $json.output.linkedinUrl }}
name: market
type: string
value: ={{ $json.output.market }}
name: cheapest_plan
type: number
value: ={{ $json.output.cheapest_plan }}
name: has_enterprise_plan
type: boolean
value: ={{ $json.output.has_enterprise_plan }}
name: has_API
type: boolean
value: ={{ $json.output.has_API }}
name: has_free_trial
type: boolean
value: ={{ $json.output.has_free_trial }}
name: integrations
type: array
value: ={{ $json.output.integrations }}
name: case_study_link
type: string
value: ={{ $json.output.case_study_link }}
name: Google Sheets - Update Row with data
type: n8n-nodes-base.googleSheets
parameters: columns: value: domain: ={{ $json.domain }}
market: ={{ $json.market }}
row_number: ={{ $json.row_number }}
linkedinUrl: ={{ $json.linkedinUrl }}
integrations: ={{ $json.integrations }}
cheapest_plan: ={{ $json.cheapest_plan }}
has_free_trial: ={{ $json.has_free_trial }}
enrichment_status: done
has_entreprise_plan: ={{ $json.has_enterprise_plan }}
last_case_study_link: ={{ $json.case_study_link }}
schema: type: string
display: yes
removed: yes
required: no
displayName: input
defaultMatch: no
canBeUsedToMatch: yes
type: string
display: yes
required: no
displayName: domain
defaultMatch: no
canBeUsedToMatch: yes
type: string
display: yes
required: no
displayName: linkedinUrl
defaultMatch: no
canBeUsedToMatch: yes
type: string
display: yes
required: no
displayName: has_free_trial
defaultMatch: no
canBeUsedToMatch: yes
type: string
display: yes
required: no
displayName: cheapest_plan
defaultMatch: no
canBeUsedToMatch: yes
type: string
display: yes
required: no
displayName: has_entreprise_plan
defaultMatch: no
canBeUsedToMatch: yes
type: string
display: yes
removed: no
required: no
displayName: last_case_study_link
defaultMatch: no
canBeUsedToMatch: yes
type: string
display: yes
required: no
displayName: market
defaultMatch: no
canBeUsedToMatch: yes
type: string
display: yes
required: no
displayName: integrations
defaultMatch: no
canBeUsedToMatch: yes
type: string
display: yes
required: no
displayName: enrichment_status
defaultMatch: no
canBeUsedToMatch: yes
type: string
display: yes
removed: no
readOnly: yes
required: no
displayName: row_number
defaultMatch: no
canBeUsedToMatch: yes
mappingMode: defineBelow
matchingColumns: row_number
operation: update
sheetName: __rl: yes
mode: list
value: gid=0
cachedResultUrl: https://docs.google.com/spreadsheets/d/19U7gAgkUEz6mbFcnygf1zKDdGvY6OAdUqq3bZQWgjxE/edit#gid=0
cachedResultName: Sheet1
documentId: __rl: yes
mode: list
value: 19U7gAgkUEz6mbFcnygf1zKDdGvY6OAdUqq3bZQWgjxE
cachedResultUrl: https://docs.google.com/spreadsheets/d/19U7gAgkUEz6mbFcnygf1zKDdGvY6OAdUqq3bZQWgjxE/edit?usp=drivesdk
cachedResultName: Enrich companies using AI agents
name: Merge data
type: n8n-nodes-base.merge
parameters: mode: combine
combinationMode: mergeByPosition
name: Sticky Note
type: n8n-nodes-base.stickyNote
parameters: width: 409.0131656322444
height: 658.0614601225933
content: ## Read Me

This workflow allows you to do account research with the web using AI.

The advanced AI module has 2 capabilities: 
- Research Google using SerpAPI
- Visit and get website content using a sub-workflow


From an unstructured input like a domain or a company name. 

It will return the following properties: 
- domain
- company Linkedin Url
- cheapest plan
- has free trial
- has entreprise plan
- has API
- market (B2B or B2C)


The strength of n8n here is that you can adapt this workflow to research whatever information you need.

You just have to precise it in the prompt and to precise the output format in the "Strutured Output Parser" module.

[Click here to find more detailed instructions with video guide.](https://lempire.notion.site/AI-Web-research-with-n8n-a25aae3258d0423481a08bd102f16906)

name: Get rows to enrich
type: n8n-nodes-base.googleSheets
parameters: options: returnAllMatches: returnAllMatches
filtersUI: values: enrichment_status
sheetName: __rl: yes
mode: list
value: gid=0
cachedResultUrl: https://docs.google.com/spreadsheets/d/19U7gAgkUEz6mbFcnygf1zKDdGvY6OAdUqq3bZQWgjxE/edit#gid=0
cachedResultName: Sheet1
documentId: __rl: yes
mode: list
value: 19U7gAgkUEz6mbFcnygf1zKDdGvY6OAdUqq3bZQWgjxE
cachedResultUrl: https://docs.google.com/spreadsheets/d/19U7gAgkUEz6mbFcnygf1zKDdGvY6OAdUqq3bZQWgjxE/edit?usp=drivesdk
cachedResultName: Enrich companies using AI agents
name: Sticky Note1
type: n8n-nodes-base.stickyNote
parameters: width: 300.49399096535876
height: 333.8263184006576
content: ### Process rows 1 by 1
This module will allow us to process rows 1 by 1
name: Sticky Note2
type: n8n-nodes-base.stickyNote
parameters: width: 300.49399096535876
height: 236.01118609685022
content: Precise here the format in which you need the data to be 
name: Sticky Note3
type: n8n-nodes-base.stickyNote
parameters: width: 300.49399096535876
height: 279.8787004666023
content: ### Ask AI what are the information you are looking for about the company
name: Sticky Note4
type: n8n-nodes-base.stickyNote
parameters: height: 248.91749449109562
content: Get your free API key here https://serpapi.com/
name: Schedule Trigger
type: n8n-nodes-base.scheduleTrigger
parameters: rule: interval: field: hours
hoursInterval: 2
name: Sticky Note5
type: n8n-nodes-base.stickyNote
parameters: width: 266.12865147126786
height: 627.5654650079845
content: Run the workflow manually or activate it to run it every 2 hours
name: AI company researcher
type: @n8n/n8n-nodes-langchain.agent
parameters: text: =This is the company I want you to research info about:
{{ $json.company_input }}

Return me:
- the linkedin URL of the company
- the domain of the company. in this format ([domain].[tld])
- market: if they are B2B or B2C. Only reply by "B2B" or "B2B"
- the lowest paid plan the company is offering. If you are not sure, reply null.
- the latest case study URL published on the website (find case study hub using google, and return the first case study link)
- tell me if the company offer an API
- tell me if the company has an enterprise plan
- tell me if the company has a free trial mentionned in their homepage. reply false if you don't find strong evidence.
- return an array with up to 5 tools the company is integrated with
options: maxIterations: 10
promptType: define
hasOutputParser: yes
name: Search Google with ScrapingBee
type: @n8n/n8n-nodes-langchain.toolWorkflow
parameters: name: search_google
source: parameter
description: Call this tool to get results from a google search.
workflowJson: {
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "2b1cc1a8b0a2fb9caab11ab2d5eb3712f9973066051b2e898cf4041a1f2a7757"
  },
  "nodes": [
    {
      "parameters": {},
      "id": "fbb17d8d-e2dc-46ae-aba4-8c27cc9d8766",
      "name": "Execute Workflow Trigger",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "typeVersion": 1,
      "position": [
        20,
        460
      ]
    },
    {
      "parameters": {
        "url": "https://app.scrapingbee.com/api/v1/store/google",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpQueryAuth",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "search",
              "value": "={{ $json.query.google_search_query }}"
            },
            {
              "name": "language",
              "value": "en"
            },
            {
              "name": "nb_results",
              "value": "5"
            }
          ]
        },
        "options": {}
      },
      "id": "b938a2bd-030e-46d7-adee-4e3c85cfc1b3",
      "name": "Search Google",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        300,
        460
      ],
      "credentials": {
        "httpQueryAuth": {
          "id": "Pb2CIMT0tN838QPy",
          "name": "ScrapingBee"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "096fee70-444e-4948-816c-752b20786062",
              "name": "response",
              "value": "={{ $json.organic_results }}",
              "type": "array"
            }
          ]
        },
        "options": {}
      },
      "id": "c5db1fb6-d875-47d2-97db-287777583f22",
      "name": "Response",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.3,
      "position": [
        520,
        460
      ]
    }
  ],
  "connections": {
    "Execute Workflow Trigger": {
      "main": [
        [
          {
            "node": "Search Google",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search Google": {
      "main": [
        [
          {
            "node": "Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {
    "Execute Workflow Trigger": [
      {
        "query": {
          "google_search_query": "site:lemlist.com pricing"
        }
      }
    ]
  }
}
jsonSchemaExample: google_search_query: site:lemlist.com pricing
specifyInputSchema: yes
name: Sticky Note6
type: n8n-nodes-base.stickyNote
parameters: height: 340.14969579315925
content: Instead of SERP API module, you can also use this custom module for ScrapingBee. It is more cost-efficient.

Get your free API key here https://www.scrapingbee.com/
name: Sticky Note7
type: n8n-nodes-base.stickyNote
parameters: width: 194.6864335083109
height: 525.6560478822986
content: In this workflow, I use Google Sheets to store the results. 

You can use my template to get started faster:

1. [Click on this link to get the template](https://docs.google.com/spreadsheets/d/1vR6s2nlTwu01v3GP7wvSRWS5W49FJIh20ZF7AUkmMDo/edit?usp=sharing)
2. Make a copy of the Sheets
3. Add the URL to this node and the node **"Google Sheets - Update Row with data"**




Connections:
Input: main: node: Loop Over Items
type: main
Merge data: main: node: Google Sheets - Update Row with data
type: main
Loop Over Items: main: node: AI company researcher
type: main
node: Merge data
type: main
Schedule Trigger: main: node: Get rows to enrich
type: main
OpenAI Chat Model: ai_languageModel: node: AI company researcher
type: ai_languageModel
Get rows to enrich: main: node: Input
type: main
Get website content: ai_tool: node: AI company researcher
type: ai_tool
AI company researcher: main: node: AI Researcher Output Data
type: main
SerpAPI - Search Google: ai_tool: node: AI company researcher
type: ai_tool
Structured Output Parser: ai_outputParser: node: AI company researcher
type: ai_outputParser
AI Researcher Output Data: main: node: Merge data
type: main
When clicking "Test workflow": main: node: Get rows to enrich
type: main
Google Sheets - Update Row with data: main: node: Loop Over Items
type: main