LinkedIn to Google Sheets, ranked job leads ready
Your job search (or recruiting) usually doesn’t fail because of effort. It fails because the process is messy: too many tabs, too many “maybe” roles, and too much copy-paste that still misses the good ones.
This LinkedIn jobs scoring automation hits job seekers hardest, but recruiters and people running career services feel it too. You’ll go from “I found 40 listings” to “I have 8 strong fits” in one tracker you can actually act on.
You’ll set up an n8n workflow that scrapes fresh LinkedIn roles via Apify, has OpenAI score relevance against your resume and preferences, and appends only new matches into Google Sheets (no duplicates). Then you can tune it for your exact filtering style.
How This Automation Works
Here’s the complete workflow you’ll be setting up:
n8n Workflow Template: LinkedIn to Google Sheets, ranked job leads ready
flowchart LR
subgraph sg0["On form submission Flow"]
direction LR
n0@{ icon: "mdi:database", form: "rounded", label: "existing_jobs", pos: "b", h: 48 }
n1["<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/>Compile_parm_sets"]
n2["<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/>rm_existing_jobs"]
n3["<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/>filtering jobs"]
n4["<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/>Filter & Dedup Jobs"]
n5@{ icon: "mdi:database", form: "rounded", label: "Add Jobs", pos: "b", h: 48 }
n6["<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/>Fetch LinkedIn Jobs"]
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/form.svg' width='40' height='40' /></div><br/>On form submission"]
n8@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If Jobs", pos: "b", h: 48 }
n9@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If Jobs1", 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/merge.svg' width='40' height='40' /></div><br/>Enrich input 1"]
n11@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If Jobs2", pos: "b", h: 48 }
n12@{ icon: "mdi:robot", form: "rounded", label: "Scoring Jobs", pos: "b", h: 48 }
n8 --> n12
n9 --> n0
n9 --> n10
n11 --> n5
n12 --> n3
n0 --> n2
n10 --> n2
n3 --> n9
n2 --> n11
n1 --> n6
n7 --> n1
n6 --> n4
n4 --> n8
n4 --> n10
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 n7 trigger
class n12 ai
class n8,n9,n11 decision
class n0,n5 database
class n6 api
class n1,n3,n4 code
classDef customIcon fill:none,stroke:none
class n1,n2,n3,n4,n6,n7,n10 customIcon
Why This Matters: Job leads pile up, clarity doesn’t
Job boards and LinkedIn make it easy to find listings and weirdly hard to find the right listings. You search, you open 20 tabs, you skim, you save a few, and then you do it all again tomorrow. The time cost isn’t just the browsing. It’s the re-reading, the second guessing, and the “did I already evaluate this one?” feeling that drains your focus. And if you’re tracking roles for clients, the busywork quietly eats your billable hours.
It adds up fast. Here’s where it breaks down.
- You end up relying on keywords, which misses great fits that use different phrasing for the same skills.
- Manual tracking in a spreadsheet leads to duplicates, and duplicates lead to wasted review time.
- Filtering by “easy” criteria (location, title) crowds out what actually matters: responsibilities and alignment with your background.
- Even when you find strong roles, you lose momentum because the process is too slow to repeat daily.
What You’ll Build: LinkedIn scraping + AI scoring into Sheets
This workflow turns job research into a simple intake and a clean output. You submit a short form with your target job titles, location, work mode, experience level, date posted, your resume text, and what you care about (your ranking criteria). n8n uses those inputs to build the right search parameters, then calls an Apify LinkedIn Jobs actor to fetch fresh listings. Each job is cleaned up and merged into a consistent format, then OpenAI scores it from 0 to 100 based on your resume and preferences. Finally, only the roles that pass your relevancy threshold are compared against what’s already in your Google Sheet, and only net-new jobs get appended.
The workflow starts with a form submission and immediately pulls LinkedIn job listings via Apify using an HTTP request. OpenAI evaluates fit and produces a clear score, then n8n filters, deduplicates, and writes the best matches into Google Sheets so your tracker stays current.
What You’re Building
| What Gets Automated | What You’ll Achieve |
|---|---|
|
|
Expected Results
Say you review about 30 new LinkedIn roles a day. Manually, you might spend 3 minutes opening, skimming, and deciding per job, plus another 30 minutes logging the “maybes” into a sheet, so you’re near 2 hours. With this workflow, you spend about 10 minutes filling out the form (or reusing the same preferences) and then wait while Apify and OpenAI do the heavy lifting. You typically end up with maybe 8–12 ranked roles in Google Sheets, already deduped, ready to apply.
Before You Start
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Google Sheets for your job tracker database.
- Apify to fetch LinkedIn Jobs listings at scale.
- OpenAI API key (get it from your OpenAI account dashboard).
Skill level: Intermediate. You’ll connect a few credentials, paste API keys, and validate that the Sheet columns match what the workflow writes.
Want someone to build this for you? Talk to an automation expert (free 15-minute consultation).
Step by Step
You submit one form. The workflow starts from an n8n Form Trigger where you paste resume text, pick filters like location and date posted, and set a target relevancy score.
Your criteria becomes a search request. n8n assembles query parameters (job titles, working mode, contract type, and similar filters) and sends them to an Apify LinkedIn Jobs actor through an HTTP Request.
Listings get cleaned and scored. Returned jobs are normalized so titles, URLs, company names, and locations follow a consistent structure. Then the OpenAI scoring node evaluates each job from 0 to 100 against your resume and ranking criteria, which makes the list sortable and filterable.
Only the right jobs make it into Sheets. n8n filters out low-scoring roles, merges job details, checks your Google Sheet for existing rows, and appends only new records. Your tracker stays readable because it’s not re-adding yesterday’s leads.
You can easily modify the relevancy threshold to be stricter (or looser) based on your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Form Submission Trigger
This workflow starts when a user submits a form that captures job preferences and scoring criteria.
- Add and open Form Submission Trigger.
- Set Form Title to
Jobs Scraperand Form Description toProvide your preferences to extract the relevant jobs. The Google Sheet should follow this template. - Under Options, set Path to
jobs-scraperand Button Label toFind Jobs. - Keep Response Mode as
lastNodeand set the submit confirmation toYour request processed successfully. - Ensure the form fields include title, location, Contract Type, Experience Level, Working Mode, Date Posted, Target Relevancy Score(out of 100), Link to your Google Sheet (jobs will be added here), Your Resume, and Your Job Instructions/Preferences.
Step 2: Connect Google Sheets
These nodes read existing jobs and append new ones to your sheet to avoid duplicates.
- Open Retrieve Sheet Jobs and set Document ID to
={{ $('Form Submission Trigger').first().json["Link to your Google Sheet (jobs will be added here)"] }}. - Set Sheet Name to
Jobs Tracker. - In Options → Data Location on Sheet, set Range to
C:Cand Range Definition tospecifyRangeA1. - Open Append Jobs to Sheet and set Document ID to
={{ $('Form Submission Trigger').first().json["Link to your Google Sheet (jobs will be added here)"] }}. - Confirm Operation is
appendand the column mappings include fields like id, Score, Job Title, and Company Name. - Credential Required: Connect your googleSheetsOAuth2Api credentials in Append Jobs to Sheet.
Step 3: Set Up Query Building and LinkedIn Request
This section turns form inputs into API parameters and requests job listings.
- Open Assemble Query Params and keep the JavaScript logic as-is to map the form values into API parameters and row limits.
- In Request LinkedIn Listings, set URL to
https://api.apify.com/v2/acts/BHzefUZlZRKWxkTck/run-sync-get-dataset-itemsand Method toPOST. - Set JSON Body to
={{ $json }}, and enable Send Body and Send Headers. - In Header Parameters, set Accept to
application/jsonand Authorization to=Bearer [CONFIGURE_YOUR_TOKEN].
[CONFIGURE_YOUR_TOKEN] with a valid Apify token; otherwise Request LinkedIn Listings will return authentication errors.Step 4: Configure Job Cleansing, Scoring, and Parallel Paths
These nodes clean the dataset, score jobs with AI, and branch into parallel enrichment and validation flows.
- Open Cleanse Job Listings and keep the JavaScript to deduplicate, filter blacklisted companies, and remove jobs without companyUrl.
- Ensure Cleanse Job Listings outputs to both Check For Listings and Merge Job Details in parallel.
- Open Score Jobs with AI and set Model to
gpt-4o-mini, and keep JSON Output enabled. - Verify the system prompt in Score Jobs with AI includes resume and preferences using expressions like
{{ $('Form Submission Trigger').first().json['Your Resume'] }}and{{ $('Form Submission Trigger').first().json["Your Job Instructions/Preferences"] }}. - Open Filter Scored Results and keep the logic that filters by
Target Relevancy Score(out of 100). - Confirm Verify Scored Output outputs to both Retrieve Sheet Jobs and Merge Job Details in parallel.
Step 5: Configure Merge, Validation, and Output
This path merges job details, removes existing records, validates, and appends to the sheet.
- Open Merge Job Details and keep Mode as
combine, Join Mode asenrichInput1, and Fields to Match asid. - Open Exclude Existing Records and keep Join Mode as
keepNonMatcheswith Fields to Match set toid. - Confirm Exclude Existing Records receives input from both Retrieve Sheet Jobs and Merge Job Details.
- In Validate New Records, keep the not-empty condition on
={{ $json }}so only valid rows proceed. - Ensure Validate New Records outputs to Append Jobs to Sheet.
Step 6: Test and Activate Your Workflow
Run a full test to ensure the form, API request, AI scoring, and sheet updates work end-to-end.
- Click Execute Workflow and submit the Form Submission Trigger form with realistic job preferences and a valid Google Sheet URL.
- Verify Request LinkedIn Listings returns items and Cleanse Job Listings outputs non-duplicate jobs.
- Confirm Score Jobs with AI outputs JSON with id and relevancy_score, and Filter Scored Results filters by your target score.
- Check the Google Sheet: new rows should appear in Jobs Tracker with mapped columns like Job Title, Company Name, and Score.
- When everything looks correct, toggle the workflow to Active to enable production use.
Troubleshooting Tips
- Google Sheets credentials can expire or need specific permissions. If things break, check your n8n Credentials page and confirm the Google account still has access to the target spreadsheet.
- If you’re using Wait nodes or external 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 early or you’ll be editing outputs forever.
Quick Answers
About 30 minutes if your accounts and Sheet are ready.
No. You will connect accounts, paste API keys, and adjust a few filters.
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 OpenAI API costs (often a few cents per batch) and any Apify usage fees for the LinkedIn actor.
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.
Yes, and you probably should. Most people tweak the “Target Relevancy Score” in the form, adjust blacklist logic in the Cleanse Job Listings / Filter & Dedup step, and tailor the prompt in the Score Jobs with AI node to match their role priorities (industry, seniority, tech stack, travel, and so on).
Usually it’s expired OAuth or the sheet URL changed. Reconnect your Google Sheets credential in n8n, then confirm the spreadsheet is accessible to that Google account and the target tab hasn’t been renamed. If the workflow is trying to dedupe by a column that no longer exists, it can also look like a “connection” problem because reads return empty fields. Fix the columns first, then run again.
Most small teams run it daily for tens to a few hundred jobs per run, and it stays stable. On n8n Cloud, volume mainly depends on your plan’s execution limits, while self-hosting is more about server resources and your Apify/OpenAI rate limits. If you push very high volume, add batching so the OpenAI scoring doesn’t time out.
Often, yes, because this kind of workflow needs branching, merges, and deduping logic that gets awkward (and expensive) fast in simpler tools. n8n also makes it easier to keep everything in one place: intake form, API calls, scoring, filtering, and the final Sheets write. Zapier or Make can still work if you keep it basic, like “new job alert to spreadsheet,” but the relevance scoring and duplicate checks are where you’ll feel the limits. If you want help choosing, Talk to an automation expert. It’s a quick call.
This is what “consistent job research” looks like when the boring parts disappear. Set it up once, tune your scoring, and let the sheet stay ready while you focus on applying (or placing) the right people.
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.