AutomationFlowsWeb Scraping › Enrich Linkedin Profiles in Google Sheets with Apify

Enrich Linkedin Profiles in Google Sheets with Apify

ByDr. Firas @drfiras on n8n.io

This workflow reads LinkedIn profile URLs from Google Sheets, calls the Apify LinkedIn scraper to fetch profile details, and writes enriched fields (name, headline, job title, company, location, skills, positions, education, certifications, and follower data) back to the same…

Event trigger★★★★☆ complexity11 nodesGoogle SheetsHTTP Request
Web Scraping Trigger: Event Nodes: 11 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #17086 — 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
{
  "id": "ubXK2TPL8XSKRhVP",
  "meta": {
    "builderVariant": "mcp",
    "aiBuilderAssisted": true
  },
  "name": "Enrich LinkedIn profiles in Google Sheets",
  "tags": [],
  "nodes": [
    {
      "id": "946b6e64-1fa4-48d7-b553-d094fce64024",
      "name": "When clicking 'Execute workflow'",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -400,
        -784
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "5db608e9-0b68-409f-9d2e-e755cc3863d2",
      "name": "Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        -96,
        -784
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "cfg-col",
              "name": "linkedin_url_column",
              "type": "string",
              "value": "LinkedIn URL"
            },
            {
              "id": "cfg-actor",
              "name": "apify_actor_id",
              "type": "string",
              "value": "yZnhB5JewWf9xSmoM"
            },
            {
              "id": "cfg-find",
              "name": "find_contacts",
              "type": "boolean",
              "value": false
            },
            {
              "id": "cfg-batch",
              "name": "batch_size",
              "type": "number",
              "value": 1
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "18c2f37c-7c3e-43f0-ac71-537877f964b1",
      "name": "Get profiles to enrich",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        304,
        -784
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "1cSqRAiFCd1vYcg5wutbkPKsd9m7OgOprkPA5fOATI1M"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "ef3780ca-e7c9-414b-9ab1-f5b0ef87cdd9",
      "name": "Enrichment complete",
      "type": "n8n-nodes-base.noOp",
      "position": [
        800,
        -992
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "3d8418fe-eb78-42ed-ac91-f7f2a3ed34c8",
      "name": "Fetch LinkedIn profile (Apify)",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1024,
        -768
      ],
      "parameters": {
        "url": "=https://api.apify.com/v2/acts/{{ $('Configuration').first().json.apify_actor_id }}/run-sync-get-dataset-items",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"urls\": [\n    {\n      \"url\": {{ JSON.stringify($json[$('Configuration').first().json.linkedin_url_column]) }}\n    }\n  ],\n  \"findContacts\": {{ $('Configuration').first().json.find_contacts }},\n  \"findContacts.contactCompassToken\": \"\"\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "5c7ae80c-4727-4dfe-8e08-738c8fa1691f",
      "name": "Update profile row",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1264,
        -768
      ],
      "parameters": {
        "columns": {
          "value": {
            "City": "={{ $json.geoLocationName }}",
            "Skills": "={{ [...new Set(($json.skills || []).map(s => s.name))].map(s => '\u2022 ' + s).join('\\n') }}",
            "Country": "={{ $json.geoCountryName }}",
            "Summary": "={{ $json.summary }}",
            "Headline": "={{ $json.headline }}",
            "Job title": "={{ $json.jobTitle }}",
            "Last name": "={{ $json.lastName }}",
            "Positions": "={{ ($json.positions || []).map(p => '\u2022 ' + (p.title || (p.positions && p.positions[0] && p.positions[0].title) || 'N/A') + ' \u2014 ' + ((p.company && p.company.name) || 'N/A') + ' (' + (p.totalDuration || 'N/A') + ')').join('\\n') }}",
            "Educations": "={{ ($json.educations || []).map(e => '\u2022 ' + (e.degreeName || e.fieldOfStudy || 'N/A') + ' \u2014 ' + (e.schoolName || 'N/A') + ' (' + ((e.timePeriod && e.timePeriod.startDate && e.timePeriod.startDate.year) || '') + '\u2013' + ((e.timePeriod && e.timePeriod.endDate && e.timePeriod.endDate.year) || 'present') + ')').join('\\n') }}",
            "First name": "={{ $json.firstName }}",
            "row_number": "={{ $('Loop over profiles').item.json.row_number }}",
            "Is verified": "={{ $json.isVerified }}",
            "Company name": "={{ $json.companyName }}",
            "Certifications": "={{ ($json.certifications || []).map(c => '\u2022 ' + c.name + ' (' + c.issuer + ')').join('\\n') }}",
            "Follower count": "={{ $json.followerCount }}",
            "Company Linkedin URL": "={{ $json.companyLinkedinUrl }}"
          },
          "schema": [
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "LinkedIn URL",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "LinkedIn URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "First name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "First name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Last name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Last name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Headline",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Headline",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Job title",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Job title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Company name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Company name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Company Linkedin URL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Company Linkedin URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Country",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Country",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "City",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "City",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Summary",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Summary",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Follower count",
              "type": "number",
              "display": true,
              "required": false,
              "displayName": "Follower count",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Is verified",
              "type": "boolean",
              "display": true,
              "required": false,
              "displayName": "Is verified",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Skills",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Skills",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Positions",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Positions",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Educations",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Educations",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Certifications",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Certifications",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "row_number"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "1cSqRAiFCd1vYcg5wutbkPKsd9m7OgOprkPA5fOATI1M"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "0d4c3f48-1718-4977-b846-629e293c12d3",
      "name": "Loop over profiles",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        592,
        -784
      ],
      "parameters": {
        "options": {},
        "batchSize": "={{ $('Configuration').first().json.batch_size }}"
      },
      "typeVersion": 3
    },
    {
      "id": "c8bcd89e-66cb-437a-959d-b6d2eb970115",
      "name": "Main note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1376,
        -1040
      ],
      "parameters": {
        "width": 820,
        "height": 1804,
        "content": "# Enrich LinkedIn profiles in Google Sheets\n\n# \ud83d\udce5  [Open full documentation on Notion](https://automatisation.notion.site/Course-Enrich-LinkedIn-profiles-in-Google-Sheets-39b3d6550fd98193aa8dc58f2a1e42a6)\n\nAutomatically enrich a list of LinkedIn profile URLs stored in Google Sheets with detailed professional data \u2014 no manual copy-pasting.\n\n## How it works\n1. Runs on a manual click (swap for a Schedule trigger to automate).\n2. **Configuration** centralizes every adjustable setting in one place.\n3. **Get profiles to enrich** reads the rows from your Google Sheet.\n4. **Loop over profiles** iterates one row at a time to respect Apify rate limits.\n5. **Fetch LinkedIn profile (Apify)** sends the URL to the Apify LinkedIn scraper and returns full profile data.\n6. **Update profile row** writes the enriched data (name, headline, job title, company, location, skills, positions, education, certifications, followers\u2026) back to the same row.\n\n## Setup\n- Connect your **Google Sheets** credential on *Get profiles to enrich* and *Update profile row*, then pick your spreadsheet and tab.\n- Add an **Apify** credential (Header Auth \u2014 Name `Authorization`, Value `Bearer YOUR_APIFY_TOKEN`) on *Fetch LinkedIn profile (Apify)*.\n- Make sure your sheet has a **LinkedIn URL** column filled with valid profile URLs.\n- Open **Configuration** and set the column name, Apify actor ID, and batch size.\n\n## Requirements\n- Google account with Google Sheets access\n- Apify account with access to a LinkedIn Profile Scraper actor\n\n## Customization\n- Change **batch_size** in Configuration to speed up or slow down requests (avoid Apify rate limits).\n- Replace the Manual trigger with a **Schedule** trigger to enrich new rows automatically.\n- Adjust the mapped columns in *Update profile row* to match your own sheet.\n\n---\nNeed help customizing?\nContact me for consulting and support : [Linkedin](https://www.linkedin.com/in/doctor-firass/)\n\n# MY NEW YOUTUBE CHANNEL\n\ud83d\udc49 [Subscribe to my new YouTube channel](https://www.youtube.com/@DrFiras_AI). Here I'll share videos and Shorts with practical tutorials and FREE templates for n8n.\n\n[![The AI Doctor](https://www.dr-firas.com/the-ai-doctor.png)](https://www.youtube.com/@DrFiras_AI)"
      },
      "typeVersion": 1
    },
    {
      "id": "044f06bd-30c9-486a-81e4-e9e4b9b32604",
      "name": "Config note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -192,
        -1008
      ],
      "parameters": {
        "color": 7,
        "width": 336,
        "height": 432,
        "content": "## 1 \u00b7 Configuration (edit here)\nSet `linkedin_url_column`, `apify_actor_id`, `find_contacts` and `batch_size`. Every downstream node reads from here."
      },
      "typeVersion": 1
    },
    {
      "id": "985545fd-76ac-47a7-9540-f224497c6a47",
      "name": "Read note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        256,
        -1008
      ],
      "parameters": {
        "color": 7,
        "width": 460,
        "height": 432,
        "content": "## 2 \u00b7 Read rows & loop\nRead every LinkedIn URL row from your Google Sheet, then loop over them one by one to respect Apify rate limits."
      },
      "typeVersion": 1
    },
    {
      "id": "8e182a8b-e7fa-4177-959a-f17d9eeec907",
      "name": "Enrich note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        960,
        -928
      ],
      "parameters": {
        "color": 7,
        "width": 520,
        "height": 332,
        "content": "## 3 \u00b7 Enrich & update\nFor each row, call the Apify LinkedIn scraper and write the enriched profile back to the matching row (matched on `row_number`)."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": true,
    "executionOrder": "v1"
  },
  "versionId": "351f9f43-aaa7-4435-aa9f-d9970dfee0df",
  "nodeGroups": [],
  "connections": {
    "Configuration": {
      "main": [
        [
          {
            "node": "Get profiles to enrich",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop over profiles": {
      "main": [
        [
          {
            "node": "Enrichment complete",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Fetch LinkedIn profile (Apify)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update profile row": {
      "main": [
        [
          {
            "node": "Loop over profiles",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get profiles to enrich": {
      "main": [
        [
          {
            "node": "Loop over profiles",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch LinkedIn profile (Apify)": {
      "main": [
        [
          {
            "node": "Update profile row",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking 'Execute workflow'": {
      "main": [
        [
          {
            "node": "Configuration",
            "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 reads LinkedIn profile URLs from Google Sheets, calls the Apify LinkedIn scraper to fetch profile details, and writes enriched fields (name, headline, job title, company, location, skills, positions, education, certifications, and follower data) back to the same…

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

More Web Scraping workflows → · Browse all categories →

Related workflows

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

Web Scraping

04 - Firecrawl URL List Mini-Batch to Resilient Analyzer. Uses googleSheets, httpRequest, executeWorkflowTrigger. Event-driven trigger; 42 nodes.

Google Sheets, HTTP Request, Execute Workflow Trigger
Web Scraping

Automate LinkedIn lead generation by scraping comments from targeted posts and enriching profiles with detailed data

Form Trigger, HTTP Request, Google Sheets
Web Scraping

This automated n8n workflow scrapes job listings from Upwork using Apify, processes and cleans the data, and generates daily email reports with job summaries. The system uses Google Sheets for data st

Google Sheets, HTTP Request, Gmail
Web Scraping

Transform LinkedIn profile URLs into comprehensive enriched lead profiles, quickly and automatically.

HTTP Request, Google Sheets
Web Scraping

Transform any website into a structured knowledge repository with this intelligent crawler that extracts hyperlinks from the homepage, intelligently filters images and content pages, and aggregates fu

HTTP Request, Google Sheets