Google Sheets + LinkedIn: clean company URLs fast
Your Google Sheet says “Acme Inc.” but LinkedIn has five “Acme” pages, two regional duplicates, and one old profile that still ranks in search. So you guess. Then your CRM fills up with the wrong URLs, reps message the wrong companies, and reporting gets messy.
This LinkedIn URL automation hits sales ops first, because clean data is their job. But BDRs doing list building and research assistants cleaning exports feel it too. The outcome is simple: you go from “company name only” to “verified LinkedIn company URL” inside your sheet, in one run.
This workflow uses Bright Data search plus an AI parser to pick the most likely official LinkedIn company page, then writes the results back to Google Sheets. You’ll see how it works, what you need, and where teams usually trip up.
How This Automation Works
See how this solves the problem:
n8n Workflow Template: Google Sheets + LinkedIn: clean company URLs fast
flowchart LR
subgraph sg0["When clicking ‘Test workflow’ Flow"]
direction LR
n0@{ icon: "mdi:play-circle", form: "rounded", label: "When clicking ‘Test workflow’", pos: "b", h: 48 }
n1@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Over Items", pos: "b", h: 48 }
n2@{ icon: "mdi:brain", form: "rounded", label: "Google Gemini Chat Model", pos: "b", h: 48 }
n3@{ icon: "mdi:robot", form: "rounded", label: "Structured Output Parser", pos: "b", h: 48 }
n4@{ icon: "mdi:swap-horizontal", form: "rounded", label: "LinkedIn Profile is Found?", pos: "b", h: 48 }
n5["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/merge.svg' width='40' height='40' /></div><br/>Merge"]
n6@{ icon: "mdi:swap-vertical", form: "rounded", label: "Add Unique Result", pos: "b", h: 48 }
n7["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Snapshot Progress"]
n8["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>HTTP Request- Post API call .."]
n9@{ icon: "mdi:cog", form: "rounded", label: "Wait - Polling Bright Data", pos: "b", h: 48 }
n10["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>HTTP Request - Getting data .."]
n11@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Checking status of Snapshot ..", pos: "b", h: 48 }
n12["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Code - Parse and Organize JS.."]
n13["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Code - Prepare Request Body .."]
n14@{ icon: "mdi:swap-vertical", form: "rounded", label: "Add Empty result", pos: "b", h: 48 }
n15@{ icon: "mdi:swap-vertical", form: "rounded", label: "Extract Body from Response", pos: "b", h: 48 }
n16@{ icon: "mdi:database", form: "rounded", label: "Append Results to Google She..", pos: "b", h: 48 }
n17@{ icon: "mdi:database", form: "rounded", label: "Read Company Names from Goog..", pos: "b", h: 48 }
n18@{ icon: "mdi:robot", form: "rounded", label: "Extract LinkedIn Url", pos: "b", h: 48 }
n19["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Bright Data Web Request - Go.."]
n20@{ icon: "mdi:swap-vertical", form: "rounded", label: "Edit Company Search URL", pos: "b", h: 48 }
n5 --> n1
n1 --> n13
n1 --> n20
n14 --> n5
n6 --> n5
n7 --> n11
n18 --> n4
n20 --> n19
n2 -.-> n18
n3 -.-> n18
n15 --> n18
n4 --> n6
n4 --> n14
n9 --> n7
n0 --> n17
n12 --> n16
n8 --> n9
n13 --> n8
n17 --> n1
n10 --> n12
n11 --> n9
n11 --> n10
n19 --> n15
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n0 trigger
class n3,n18 ai
class n2 aiModel
class n4,n11 decision
class n16,n17 database
class n7,n8,n10,n19 api
class n12,n13 code
classDef customIcon fill:none,stroke:none
class n5,n7,n8,n10,n12,n13,n19 customIcon
The Challenge: Finding the Right LinkedIn Company Page
Cleaning company URLs sounds trivial until you’re 200 rows deep and every search result looks “close enough.” You open a tab, search, click around, double-check the logo, compare follower counts, then paste the URL back into the sheet. Then you do it again. After a while, you stop verifying as carefully because you’re trying to get the list done before the next campaign goes out. That’s when mistakes creep in: duplicate pages, “showcase” pages instead of the parent company, or a similarly named business in another country.
It adds up fast. And the damage usually shows up later, when you’re least interested in debugging data entry.
- Manual searching turns into hours of tab hopping, especially when a list has lots of similar names.
- People paste whatever looks right, which means your outreach can target the wrong company page.
- LinkedIn URLs change, pages get merged, and your spreadsheet gets stale the moment it’s “done.”
- It’s hard to scale because there’s no consistent method, only individual judgment calls.
The Fix: Google Sheets → Verified LinkedIn URLs, Automatically
This workflow starts with a list of company names in Google Sheets and produces a clean, structured output sheet with each company’s most likely official LinkedIn URL. You run it manually (on purpose), so you can control batch size, test on small lists, and avoid surprise usage costs. For each company, n8n generates a Google search query that focuses on LinkedIn company pages, then fetches the search results through Bright Data’s Web Unlocker. Next, an AI model (Google Gemini in the template, but it’s swappable) reads the HTML and extracts the best matching LinkedIn company profile URL. Results are merged, “not found” rows are still recorded, and the final data is appended back into a Google Sheet for easy review and downstream enrichment.
The workflow begins when you click run in n8n. It pulls names from your input sheet, loops through them, and runs a consistent search-and-parse routine for each one. Finally, it bundles results for enrichment through a Bright Data dataset snapshot and writes the structured output to your target sheet.
What Changes: Before vs. After
| What This Eliminates | Impact You’ll See |
|---|---|
|
|
Real-World Impact
Say you’ve got 150 companies from a webinar list in Google Sheets. Manually, you might spend about 2 minutes per company between searching, validating, and pasting, which is roughly 5 hours (and that’s if you stay focused). With this workflow, you kick off the run in a minute, let Bright Data fetch results, and let the AI extract URLs while you do other work. You still review the final sheet, but that review is usually a quick scan instead of 150 separate investigations.
Requirements
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Google Sheets for input list and saved outputs.
- Bright Data to fetch Google search results reliably.
- Google Gemini (or another LLM) to interpret HTML and extract the right URL.
- Bright Data API key (get it from your Bright Data dashboard).
Skill level: Intermediate. You’ll connect accounts, paste API keys, and be comfortable editing a couple of nodes (sheet names, columns, and prompts).
Need help implementing this? Talk to an automation expert (free 15-minute consultation).
The Workflow Flow
Manual run from n8n. You start the workflow when you’re ready, which is handy for controlled batch runs and testing on a small sample first.
Read companies from Google Sheets. n8n loads your company names from the specified spreadsheet and prepares them for looping, so each row gets handled consistently.
Search, fetch, and extract the LinkedIn URL. For every company, the workflow builds a targeted Google query (focused on LinkedIn), fetches the HTML through Bright Data, then uses an AI agent + chat model to pull out the most likely official LinkedIn company link. If the workflow can’t find a confident match, it records a blank result instead of silently failing.
Enrich and export to your output sheet. Found URLs are merged, bundled for a Bright Data dataset snapshot enrichment, then appended as structured rows in a separate Google Sheet tab so your team can use it immediately.
You can easily modify the search pattern and the output columns to match your CRM or enrichment provider. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Manual Trigger
This workflow starts manually and then orchestrates two processing branches for company enrichment and LinkedIn URL discovery.
- Add and open Manual Execution Start.
- Leave default settings as-is to allow manual runs.
- Note that Manual Execution Start outputs to Retrieve Sheet Company List to pull the company list.
⚠️ Common Pitfall: This workflow won’t run on a schedule unless you replace Manual Execution Start with a scheduled trigger.
Step 2: Connect Google Sheets
The workflow reads companies from one sheet and appends enriched results to another.
- Open Retrieve Sheet Company List and set Document to
[YOUR_ID]and Sheet todata. - Open Append to Sheets Output and set Document to
[YOUR_ID]and Sheet tooutput. - Keep Operation set to
appendin Append to Sheets Output.
Credential Required: Connect your Google Sheets credentials in Retrieve Sheet Company List and Append to Sheets Output.
⚠️ Common Pitfall: If your sheet columns don’t match the incoming JSON keys, auto-mapping in Append to Sheets Output may misalign values.
Step 3: Configure BrightData Batch Processing and Polling
This branch sends LinkedIn URLs to BrightData, polls for completion, and fetches the snapshot results.
- Open Build BrightData Request and keep the Python code that assembles
companiesfrom incomingurlfields. - In Submit BrightData Batch, set URL to
https://api.brightdata.com/datasets/v3/triggerand Method toPOST. - Set JSON Body to
{{ $json.companies }}and include query parameters: dataset_id =[YOUR_ID], include_errors =true. - In Delay for BrightData Poll, set Amount to
15seconds to throttle polling. - In Check Snapshot Progress, set URL to
=https://api.brightdata.com/datasets/v3/progress/{{ $('Submit BrightData Batch').item.json.snapshot_id }}. - In Verify Snapshot Status, confirm the condition uses
{{ $json.status }}equalsrunning. - In Fetch BrightData Snapshot, set URL to
=https://api.brightdata.com/datasets/v3/snapshot/{{ $json.snapshot_id }}and query format tojson.
⚠️ Common Pitfall: Ensure the Authorization header uses Bearer [CONFIGURE_YOUR_TOKEN] in all BrightData HTTP nodes or requests will fail.
Node Flow Note: Verify Snapshot Status outputs to both Delay for BrightData Poll and Fetch BrightData Snapshot in parallel, enabling continuous polling until completion.
Step 4: Set Up Search Parsing and AI Extraction
This branch builds a Google search query, scrapes results via BrightData, and uses Gemini to extract the official LinkedIn profile.
- In Compose Search URL, set google_search to
=https://www.google.com/search?q=site%3Alinkedin.com+{{ encodeURIComponent($json["name"].trim()) }}. - Configure BrightData Search Request with URL
https://api.brightdata.com/request, MethodPOST, and body parameters: zone =web_unlocker1, url ={{ $json.google_search }}, format =json, data_format =markdown. - In Extract Response Body, set result_body to
{{ $json.body }}. - Open Parse LinkedIn Link, set Text to
{{ $json.result_body }}, and keep the custom prompt for extracting the company LinkedIn profile. - Ensure Gemini Chat Model is connected as the language model for Parse LinkedIn Link with Model set to
models/gemini-2.0-flash-lite. - Keep Structured Output Decoder attached to Parse LinkedIn Link and set the schema example to the provided JSON array with
company_nameandurl. - In LinkedIn Link Exists?, verify the exists check uses
{{ $json.output[0]['url'] }}. - For the success path, set Add Matched Result JSON Output to
{{ $json.output[0] }}. - For the fallback path, set Add Blank Result JSON Output to
{ "company_name": "{{ $('Iterate Through Records').item.json['name']}} (NOT FOUND)", "url": "" }.
Credential Required: Connect your Google Gemini credentials in Gemini Chat Model.
Structured Output Decoder is attached to Parse LinkedIn Link; no separate credentials are required on the parser sub-node.
Node Flow Note: Iterate Through Records outputs to both Build BrightData Request and Compose Search URL in parallel to process enrichment and LinkedIn discovery at the same time.
Step 5: Configure Data Transformation and Output
Snapshot data is normalized and appended to the output sheet. LinkedIn lookup results are merged to keep the batch loop running.
- In Transform Snapshot Payload, keep the Python code that maps BrightData fields such as
name,country_code,employees_in_linkedin,website, andcrunchbase_urlinto clean JSON. - Verify Append to Sheets Output is connected after Transform Snapshot Payload so records are appended to your output sheet.
- Confirm Combine Results merges outputs from Add Matched Result and Add Blank Result before looping back to Iterate Through Records.
⚠️ Common Pitfall: If Transform Snapshot Payload throws “Missing input data,” verify that Fetch BrightData Snapshot returns JSON and includes expected fields.
Step 6: Test and Activate Your Workflow
Run a manual test to validate credentials, BrightData responses, and output mapping before production use.
- Click Execute Workflow on Manual Execution Start to run a test.
- Confirm Retrieve Sheet Company List returns records and Compose Search URL generates a valid Google query.
- Check that Submit BrightData Batch returns a
snapshot_idand that Verify Snapshot Status eventually routes to Fetch BrightData Snapshot. - Verify Append to Sheets Output appends rows in the
outputsheet with transformed fields. - Once validated, activate the workflow using the Active toggle for production use.
Watch Out For
- Bright Data credentials can expire or require product-level access. If requests start failing, check your Bright Data dashboard and the specific API key used in the HTTP Request nodes first.
- If you’re using Wait nodes or external snapshot rendering, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- Default prompts in AI nodes are generic. Add your brand voice and rules (like “prefer /company/ over /showcase/”) early or you’ll be editing outputs forever.
Common Questions
About 30 minutes if your accounts and API keys are ready.
Yes, but someone should be comfortable connecting credentials and editing sheet mappings. No traditional coding is required, unless you want to customize the optional code nodes.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in Bright Data usage plus your AI model costs (Gemini or another provider).
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
You can change the query logic in the “Compose Search URL” node to match your market (for example, adding a country term), and tighten extraction rules in the AI parsing step so it prefers /company/ pages over other LinkedIn URLs. Many teams also customize the “Add Blank Result” path to flag rows for review, or they add an email alert when too many companies come back empty. If you want different output fields, update the transformation/code nodes before the “Append to Sheets Output” node.
Usually it’s an API key issue or a permission mismatch on your Bright Data account. Regenerate the key, update it in the Bright Data HTTP Request nodes, and confirm the Web Unlocker or dataset features are enabled for your plan. If it works for a few companies and then fails, you may be hitting rate limits or temporary blocks, so slowing the batch size can help.
It depends on your Bright Data throughput and your n8n plan, but most teams comfortably run a few hundred companies per batch.
For this job, n8n is usually the more flexible choice because you can loop through rows, branch on “found vs not found,” and handle batch polling without stacking up lots of paid tasks. It’s also easier to keep all the “glue logic” in one place, especially when you’re mixing web scraping-style requests (Bright Data) with an AI parser and multi-step enrichment. Zapier or Make can still work, frankly, but you’ll often end up stitching together several smaller automations, which is harder to debug when results look wrong. If you’re deciding between tools, the best test is simple: can you inspect the raw HTML response and the extracted URL in one run? n8n makes that kind of troubleshooting straightforward. Talk to an automation expert if you’re not sure which fits.
Once you’ve got verified LinkedIn URLs in your sheet, everything downstream gets easier: enrichment, segmentation, even basic deduping. Set it up once, run it whenever a fresh list lands, and stop treating data cleanup like a rite of passage.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.