AutomationFlowsData & Sheets › Enrich Company Domains with Business Data Using Perplexity AI and Google Sheets

Enrich Company Domains with Business Data Using Perplexity AI and Google Sheets

ByNaveen Choudhary @n8nstein on n8n.io

This workflow automatically enriches company domain lists with comprehensive business information using Perplexity AI's research capabilities and organizes the data in Google Sheets for easy analysis and use. Sales teams building prospect databases with accurate contact…

Event trigger★★★★☆ complexity9 nodesGoogle SheetsHTTP Request
Data & Sheets Trigger: Event Nodes: 9 Complexity: ★★★★☆ Added:

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

This workflow follows the Google Sheets → HTTP Request 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
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "bffa5202-a56e-4f05-8b01-e8c4329915f3",
      "name": "Manual Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -480,
        56
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "bc1ce2a3-f4b0-4cbe-a406-49ac2e339924",
      "name": "Fetch Unprocessed Domains",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -256,
        56
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "=",
              "lookupColumn": "processed"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1737567569,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1bdK8xskt-qfLlDwdzolM0zFyo9KxZ-HHpTVxcEw3ZMY/edit#gid=1737567569",
          "cachedResultName": "Data"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1bdK8xskt-qfLlDwdzolM0zFyo9KxZ-HHpTVxcEw3ZMY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1bdK8xskt-qfLlDwdzolM0zFyo9KxZ-HHpTVxcEw3ZMY/edit?usp=drivesdk",
          "cachedResultName": "Get Addresses"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "e8d61653-67ef-45bd-8640-f3317c859516",
      "name": "Batch Process Domains",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -32,
        56
      ],
      "parameters": {
        "options": {},
        "batchSize": 10
      },
      "typeVersion": 3
    },
    {
      "id": "4946ef7e-852b-4860-bef0-aa44bc0c5221",
      "name": "Perplexity AI Research",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        192,
        -16
      ],
      "parameters": {
        "url": "https://api.perplexity.ai/chat/completions",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"model\": \"sonar\",\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"For each of the following 10 companies, return only German addresses and provide: address split as \\\"address\\\", \\\"city\\\", \\\"state\\\", \\\"postal_code\\\", \\\"country\\\"; phone (international format); latest employee count; latest annual revenue (numbers only in USD); industry (e.g., LinkedIn industry category if available); company LinkedIn URL; and a reliable source URL as \\\"source_url\\\". Output results as an array of 10 JSON objects. If any field can't be found reliably, set it to null and don't make things. Companies: ={{ $input.all().map(item => item.json.domain) }}\"\n    }\n  ],\n  \"response_format\": {\n    \"type\": \"json_schema\",\n    \"json_schema\": {\n      \"schema\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"companies\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"object\",\n              \"properties\": {\n                \"domain\": { \"type\": \"string\" },\n                \"company\": { \"type\": \"string\" },\n                \"address\": { \"type\": \"string\" },\n                \"city\": { \"type\": \"string\" },\n                \"state\": { \"type\": \"string\" },\n                \"postal_code\": { \"type\": \"string\" },\n                \"country\": { \"type\": \"string\" },\n                \"phone\": { \"type\": \"string\" },\n                \"employees\": { \"type\": \"integer\", \"nullable\": true },\n                \"revenue\": { \"type\": \"number\", \"nullable\": true },\n                \"industry\": { \"type\": \"string\", \"nullable\": true },\n                \"linkedin_url\": { \"type\": \"string\", \"nullable\": true },\n                \"source_url\": { \"type\": \"string\" }\n              },\n              \"required\": [\n                \"domain\",\n                \"company\",\n                \"address\",\n                \"city\",\n                \"state\",\n                \"postal_code\",\n                \"country\",\n                \"phone\",\n                \"employees\",\n                \"revenue\",\n                \"industry\",\n                \"linkedin_url\",\n                \"source_url\"\n              ]\n            }\n          }\n        },\n        \"required\": [\"companies\"]\n      }\n    }\n  }\n}\n",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "perplexityApi"
      },
      "credentials": {
        "perplexityApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "9b4c6512-e43b-4568-8bbb-144ef684bb5a",
      "name": "Parse AI Response",
      "type": "n8n-nodes-base.code",
      "position": [
        416,
        -16
      ],
      "parameters": {
        "jsCode": "// Step 1: Get the raw content string\nlet rawContent = $input.first().json.choices[0].message.content;\n\n// Step 2: Try to extract JSON block inside ```json ... ```\nconst match = rawContent.match(/```json\\s*([\\s\\S]*?)\\s*```/i);\n\nif (match) {\n  rawContent = match[1];\n}\n\n// Step 3: Try to parse first-level JSON\nlet parsed;\ntry {\n  parsed = JSON.parse(rawContent);\n\n  // If it's an object with a \"companies\" key, extract the array\n  if (parsed && parsed.companies && Array.isArray(parsed.companies)) {\n    parsed = parsed.companies;\n  }\n  \n  // If it's still a string (stringified JSON inside JSON), parse again\n  if (typeof parsed === 'string') {\n    parsed = JSON.parse(parsed);\n\n    if (parsed && parsed.companies && Array.isArray(parsed.companies)) {\n      parsed = parsed.companies;\n    }\n  }\n\n  // If it's not an array at this point, return warning\n  if (!Array.isArray(parsed)) {\n    return [{\n      json: {\n        warning: \"Parsed result is not an array.\",\n        type: typeof parsed,\n        preview: JSON.stringify(parsed).slice(0, 300)\n      }\n    }];\n  }\n\n} catch (err) {\n  const message = err instanceof Error ? err.message : String(err);\n  return [{\n    json: {\n      error: \"Failed to parse JSON\",\n      message,\n      preview: rawContent.slice(0, 300),\n      rawLength: rawContent.length\n    }\n  }];\n}\n\n// Step 4: Return each company as a separate item\nreturn parsed.map(company => ({ json: company }));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "7d2016fd-3385-4c78-a8f0-37b4dd5df146",
      "name": "Save Enriched Data",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        640,
        56
      ],
      "parameters": {
        "columns": {
          "value": {
            "city": "={{ $json.city }}",
            "phone": "={{ $json.phone.replace(\"+\", \"'+\") }}",
            "state": "={{ $json.state }}",
            "domain": "={{ $json.domain }}",
            "address": "={{ $json.address }}",
            "company": "={{ $json.company }}",
            "country": "={{ $json.country }}",
            "revenue": "={{ $json.revenue }}",
            "industry": "={{ $json.industry }}",
            "postCode": "={{ $json.postal_code }}",
            "employees": "={{ $json.employees }}",
            "processed": "true",
            "source_url": "={{ $json.source_url }}",
            "companyLinkedinUrl": "={{ $json.linkedin_url }}"
          },
          "schema": [
            {
              "id": "domain",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "domain",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "company",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "company",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "address",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "address",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "city",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "city",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "state",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "state",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "postCode",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "postCode",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "country",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "country",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "phone",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "employees",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "employees",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "revenue",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "revenue",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "industry",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "industry",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "companyLinkedinUrl",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "companyLinkedinUrl",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "source_url",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "source_url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "processed",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "processed",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "domain"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1737567569,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1bdK8xskt-qfLlDwdzolM0zFyo9KxZ-HHpTVxcEw3ZMY/edit#gid=1737567569",
          "cachedResultName": "Data"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1bdK8xskt-qfLlDwdzolM0zFyo9KxZ-HHpTVxcEw3ZMY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1bdK8xskt-qfLlDwdzolM0zFyo9KxZ-HHpTVxcEw3ZMY/edit?usp=drivesdk",
          "cachedResultName": "Get Addresses"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6,
      "alwaysOutputData": true
    },
    {
      "id": "5ea0a567-0a88-4724-acc7-f654930c3ae7",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -304,
        -352
      ],
      "parameters": {
        "width": 896,
        "height": 656,
        "content": "\ud83c\udfe2 COMPANY DATA ENRICHMENT SYSTEM\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\n\ud83c\udfaf Automatically enriches company domains with detailed business data using Perplexity AI\n\n\ud83d\udcca PROCESS FLOW:\n1. Reads unprocessed domains from Google Sheets\n2. Batches domains (10 per request) for cost efficiency  \n3. Uses Perplexity AI to research German addresses + business data\n4. Parses AI response and saves enriched data back to sheets\n5. Marks domains as \"processed\" to avoid duplicates\n\n\u23f1\ufe0f Runtime: ~2-3 minutes per batch | \ud83d\udcb0 Cost: ~$0.005 per 10 domains\n\ud83d\udd04 Resumable: Only processes unprocessed domains | \ud83c\udf0d Focus: German addresses (can be customized to HQ addresses)"
      },
      "typeVersion": 1
    },
    {
      "id": "00024d69-8567-4c12-bf92-d54bb5686bd6",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -864,
        -352
      ],
      "parameters": {
        "color": 5,
        "width": 544,
        "height": 656,
        "content": "\ud83d\ude80 SETUP CHECKLIST\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\n\ud83d\udccb GOOGLE SHEETS:\n\ud83d\udd17 [MAKE A COPY of this template](https://docs.google.com/spreadsheets/d/1bdK8xskt-qfLlDwdzolM0zFyo9KxZ-HHpTVxcEw3ZMY/edit?usp=sharing)\n\u26a0\ufe0f Update Sheet ID in both Google Sheets nodes after copying\n\n\ud83d\udcdd Required columns: domain, processed\n\ud83d\udcca Tab: Data | Filter: processed = \"\" (empty only)\n\n\ud83d\udd10 API CREDENTIALS NEEDED:\n\u2705 Perplexity AI API key\n\u2705 Google Sheets OAuth2 authentication\n\n\u2699\ufe0f Batch size: 10 domains (adjustable in \"Batch Process Domains\" node)"
      },
      "typeVersion": 1
    },
    {
      "id": "0609a728-9743-4a92-b64d-a63eec993333",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        608,
        -352
      ],
      "parameters": {
        "color": 4,
        "width": 544,
        "height": 656,
        "content": "\ud83d\udcca OUTPUT DATA FIELDS\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\n\u2705 ENRICHED DATA SAVED:\n- Company name, complete address\n- Phone (international), employee count, revenue (USD)\n- Industry, LinkedIn URL, source URL\n- processed = \"true\" (tracking field)\n\n\ud83d\udee1\ufe0f ERROR HANDLING:\n- Parse failures \u2192 Detailed error info in output\n- Missing data \u2192 AI sets fields to null (no fake data)\n- Rate limiting \u2192 Reduce batch size if needed\n\n\ud83d\udcc8 MONITORING:\n- Check \"processed\" column for completion status\n- Review \"source_url\" for data reliability\n- Monitor costs in Perplexity dashboard"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Manual Trigger": {
      "main": [
        [
          {
            "node": "Fetch Unprocessed Domains",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Response": {
      "main": [
        [
          {
            "node": "Save Enriched Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Enriched Data": {
      "main": [
        [
          {
            "node": "Batch Process Domains",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Batch Process Domains": {
      "main": [
        [],
        [
          {
            "node": "Perplexity AI Research",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Perplexity AI Research": {
      "main": [
        [
          {
            "node": "Parse AI Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Unprocessed Domains": {
      "main": [
        [
          {
            "node": "Batch Process Domains",
            "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 automatically enriches company domain lists with comprehensive business information using Perplexity AI's research capabilities and organizes the data in Google Sheets for easy analysis and use. Sales teams building prospect databases with accurate contact…

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

More Data & Sheets workflows → · Browse all categories →

Related workflows

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

Data & Sheets

This template is ideal for solo store owners, eCommerce marketers, automation beginners, or anyone using Shopify and Gmail who wants to recover lost revenue without coding.

HTTP Request, Gmail, Twilio +3
Data & Sheets

PCN. Uses googleSheets, httpRequest, @n-octo-n/n8n-nodes-json-database, itemLists. Event-driven trigger; 60 nodes.

Google Sheets, HTTP Request, @N Octo N/N8N Nodes Json Database +3
Data & Sheets

The workflow automates the process of gathering extensive keyword data for a "Main Keyword." It starts by reading initial parameters from a Google Sheets template, creates a new dedicated Google Sheet

Google Sheets, Google Drive, HTTP Request
Data & Sheets

🔥 March Sale – n8n Community Members Get ideoGener8r for Just $27! (Reg. $47) Use Coupon Code: (Valid until 3/31/2025 for n8n community members)

HTTP Request, Google Drive, Google Sheets
Data & Sheets

📄 Documentation: Notion Guide

Google Sheets, Google Drive, HTTP Request +2