Automate LinkedIn Profile Discovery with n8n
Finding LinkedIn profiles for a long list of contacts in Google Sheets can quickly turn into repetitive, manual work. With n8n, you can turn this into a reliable, automated workflow that searches for LinkedIn URLs, validates them, and writes them back to your sheet.
This tutorial walks you through an n8n workflow template that connects Google Sheets and Airtop to automate LinkedIn profile discovery. You will learn how each node works, how to configure it, and how to handle errors, rate limits, and edge cases in a clean and maintainable way.
What you will learn
By the end of this guide, you will be able to:
- Build an n8n workflow that reads contact data from Google Sheets
- Use Airtop to run a Google search for each contact and extract a LinkedIn profile URL
- Parse the Airtop response in a Code node and merge it with the original row data
- Update the correct row in Google Sheets with the LinkedIn URL and a validation status
- Test, validate, and harden the workflow with rate limiting, error handling, and compliance best practices
Why automate LinkedIn profile discovery?
Manual LinkedIn lookups do not scale. For every contact you typically:
- Search their name (and maybe company) on Google or directly on LinkedIn
- Open multiple results to find the correct profile
- Copy and paste the URL into your spreadsheet or CRM
Automating profile discovery with n8n helps you:
- Save time by processing many rows automatically instead of one by one
- Keep your Google Sheets contact list enriched with consistent, verified LinkedIn URLs
- Scale lead enrichment for sales, recruiting, or marketing workflows
- Feed LinkedIn URLs into downstream automations such as CRM updates or outreach sequences
How the n8n workflow is structured
The template uses a simple, linear workflow with five core nodes:
- Manual Trigger – starts the workflow manually while you test, or can be replaced by a Cron node for scheduled runs
- Google Sheets (Read) – reads contact data from your sheet, including a field like Person Info
- Airtop – runs a Google search using the person info and extracts a LinkedIn URL
- Code – parses the Airtop response, merges it with the original row data, and prepares the payload for updating
- Google Sheets (Update) – writes the LinkedIn URL and validation status back to the correct row
On the n8n canvas this appears as a straight flow:
Manual Trigger → Google Sheets (Read) → Airtop → Code → Google Sheets (Update)
Key concepts before you start
1. Person Info as your search input
Your Google Sheet should contain a column that combines the person’s name and optionally their company. In the workflow this is referred to as Person Info, for example:
John Smith, Acme CorpJane Doe Product Manager
This value is used to build the Google search query that Airtop will process.
2. Tracking row numbers
To update the right row later, you need a way to identify it. You can:
- Add a dedicated row_number column in your sheet, or
- Use the row index that n8n returns when reading from Google Sheets
This identifier is passed through the workflow so the update node can target the correct row.
3. Validated status
It is useful to include a Validated column in your sheet. This lets you:
- Mark rows where a LinkedIn URL was found and accepted
- Flag rows where no profile was found or where manual review is needed
Step-by-step: building the workflow in n8n
Step 1 – Configure the trigger
Start with a Manual Trigger node:
- Add a Manual Trigger node as the first node in your workflow.
- Use this trigger while developing and testing so you can run the workflow on demand.
Once your workflow is stable, you can replace the Manual Trigger with a:
- Cron node to run on a schedule (for example every hour or once per day), or
- Webhook trigger if you want to start the workflow from an external system
For large datasets, plan to run the workflow in batches to stay within rate limits and avoid timeouts.
Step 2 – Read contact data from Google Sheets
Next, add a Google Sheets node to read your contacts:
- Set the operation to Read or Read Rows.
- Connect your Google account using OAuth with Google Drive access.
- Select the correct spreadsheet and sheet tab.
- Ensure your sheet has clear header rows so n8n can map column names reliably.
Recommended columns:
- Person Info – name plus optional company or role
- row_number – a unique identifier for each row (or rely on n8n’s row index)
- LinkedIn URL – initially empty, will be filled by the workflow
- Validated – can be left empty initially, will be updated to show status
Make sure the Google Sheets node output includes Person Info and the row identifier, because both are needed in later steps.
Step 3 – Use Airtop to search for a LinkedIn profile
The Airtop node takes the person info and runs a Google search, then uses an extraction prompt to return only a LinkedIn profile URL.
3.1 Build the Google search URL
In the Airtop node, use a field (for example a URL or text field) that builds a Google search query from the Person Info value. The template uses:
=https://www.google.com/search?q={{ encodeURI($json['Person Info']) }}
This expression does the following:
- Takes the
Person Infovalue from the current item - Encodes it safely for use in a URL
- Appends it to a Google search URL
3.2 Prompt Airtop to extract only a LinkedIn URL
Configure the Airtop prompt so that the model knows exactly what to return. The template uses:
=This is Google Search results. the first results should be the Linkedin Page of {{ $json['Person Info'] }}
Return the Linkedin URL and nothing else.
If you cannot find the Linkedin URL, return an empty string.
A valid Linkedin profile URL starts with "https://www.linkedin.com/in/"
This prompt instructs Airtop to:
- Look at Google search results for the person
- Return only a LinkedIn profile URL that starts with
https://www.linkedin.com/in/ - Return an empty string if no suitable profile is found
3.3 Tips for the Airtop step
- You can replace Airtop with a search engine API or a headless browser node if you prefer a different approach to fetching search results.
- To avoid being blocked by Google, consider adding delays or processing rows in smaller batches.
- Monitor your Airtop usage and any applicable limits.
Step 4 – Parse Airtop response in a Code node
After Airtop returns a result, use a Code node to prepare a clean JSON object that combines:
- The LinkedIn URL (or empty string) from Airtop
- The original row data from the Google Sheets read node
Example JavaScript used in the template:
const linkedInProfile = $json.data.modelResponse
const rowData = $('Person info').item.json
return { json: { ...rowData, 'LinkedIn URL': linkedInProfile
}};
What this script does step by step:
linkedInProfilereads themodelResponsefrom the Airtop node, which should be either a LinkedIn URL or an empty string.rowDatafetches the original row JSON from the node that provided Person Info (the Google Sheets read node).- The returned object spreads
rowDataand adds a new field called LinkedIn URL that holds the Airtop result.
After this node, each item contains all the fields from the original row plus the new LinkedIn URL field. This makes it easy for the update node to write everything back to the correct row.
Step 5 – Update the row in Google Sheets
Finally, add a second Google Sheets node configured to update existing rows.
- Set the operation to Update or Update Rows.
- Use the same spreadsheet and sheet as in the read node.
- Choose row_number (or your chosen identifier) as the matching column so n8n knows which row to update.
- Map the LinkedIn URL field from the Code node output to the corresponding column in your sheet.
- Set the Validated column to a value such as
true,found, or a more detailed status.
You can either:
- Use auto-mapping if your column names match the field names in the JSON, or
- Manually map each field if your sheet uses custom column names
Testing and validating your workflow
Before running the workflow on hundreds or thousands of rows, test it carefully with a small sample.
Run a small test batch
Start with 5 to 10 rows and check:
- That the Airtop search returns the correct LinkedIn profile URLs for each contact
- That the right rows are updated in Google Sheets based on
row_numberor the row index - That the Code node behaves correctly when Airtop returns an empty string
Add simple validation rules
To avoid writing incorrect URLs into your sheet, add a basic check:
- If the returned URL does not start with
https://www.linkedin.com/in/, treat it as invalid. - In such cases, leave the LinkedIn URL cell empty and set Validated to something like
manual review.
This gives you a clear list of contacts that need human attention while still automating the majority of the work.
Handling rate limits, errors, and edge cases
Rate limiting and batching
- Insert a Wait node between items or between batches to slow down requests and avoid search engine throttling.
- Process your sheet in chunks (for example 50 or 100 rows per run) instead of the entire dataset at once.
- Monitor how long each run takes and adjust batch sizes accordingly.
Empty or missing results
- If Airtop cannot find a LinkedIn URL, it should return an empty string as defined in the prompt.
- Write an empty string into the LinkedIn URL column and set Validated to
not foundor a similar label. - You can later filter rows with
not foundand decide whether to retry or handle them manually.
False positives and ambiguous profiles
- Always check that the URL starts with
https://www.linkedin.com/in/, not a company page or other LinkedIn path. - Optionally, extend your validation by checking whether the name or company in the search snippet matches your sheet data before accepting the URL.
Error handling patterns in n8n
- Use a Try / Catch pattern in your workflow to catch node errors and continue processing other rows.
- Configure n8n’s built-in error workflow to log failures, send notifications, or write error details to a separate sheet.
- Ensure that transient errors (like network timeouts) do not break the entire run.
Privacy, compliance, and best practices
Automating LinkedIn profile discovery involves personal data and third-party services, so keep these guidelines in mind:
- Review and respect LinkedIn and search engine Terms of Service. Automated scraping can violate platform policies.
- If you process data of EU residents, follow GDPR requirements, including lawful basis for processing and data minimization.
- Use the discovered data only for legitimate business purposes such as recruiting or B2B outreach.
- Maintain clear opt-out options for individuals who no longer wish to be contacted.
Scaling and integrating with other tools
Once your workflow is stable and accurate, you can extend it into a larger automation system.
Ideas for downstream integrations
- CRM enrichment: Send the LinkedIn URLs to tools like HubSpot, Salesforce, or Pipedrive to update contact records.
- Personalized outreach: Trigger email sequences or LinkedIn InMail campaigns using your outreach platform of choice.
- Data enrichment services: Call APIs like Clearbit or ZoomInfo to add company, role, or firmographic details based on the LinkedIn URL.
Scaling considerations
- Run the workflow on a schedule using a Cron node so new or changed rows are processed automatically.
- If you rely on search APIs, monitor quota usage and consider multiple API keys if permitted by the provider.
- Use logging or dashboards to track how many profiles are found, how many fail, and how long runs take.
Troubleshooting checklist
If something is not working as expected, walk through this list:
- Empty or incorrect LinkedIn URLs:
- Review your Airtop prompt to ensure it clearly instructs the model to return only a profile URL.
- Check that the Code node is reading
$json.data.modelResponsecorrectly.
- Rows not updating in Google Sheets:
- Confirm that
row_number(or your chosen identifier) is present and correctly mapped. - Verify that your Google Sheets node has the right spreadsheet, sheet, and permissions.
- Confirm that
- Slow runs or temporary blocks:
- Add Wait nodes or delays between items.
- Reduce batch size so fewer rows are processed per run.
- Consider using a dedicated search API instead of direct Google search pages.
- Authentication or credential errors:
- Reconnect your Google OAuth credentials for Google Sheets and Google Drive.
- Check and refresh Airtop credentials or API keys if needed.
Recap: how the template works
