LinkedIn + Google Sheets: ATS-ready resume feedback
Your resume “looks good,” but the interview invites still don’t show up. Then you paste the same LinkedIn profile into three different tools, skim a job post, guess at keywords, and end up rewriting blind.
Career coaches run into this every week. Recruiters feel it when candidates miss obvious role requirements. And a solo job seeker trying to break into SDR/BDR roles? Same frustration. This ATS resume feedback automation turns a LinkedIn profile plus a job post into clear, ATS-style guidance you can reuse and track.
You’ll see how the workflow validates links, pulls structured profile and job data, runs an AI “recruiter check,” then logs outcomes to Google Sheets so feedback stays consistent from one edit to the next.
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: LinkedIn + Google Sheets: ATS-ready resume feedback
flowchart LR
subgraph sg0["Recruiter Check Flow"]
direction LR
n0@{ icon: "mdi:brain", form: "rounded", label: "Groq Chat Model4", 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/httprequest.dark.svg' width='40' height='40' /></div><br/>Get profile details"]
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/httprequest.dark.svg' width='40' height='40' /></div><br/>Get job details"]
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/webhook.dark.svg' width='40' height='40' /></div><br/>Webhook (GET Form details)"]
n4@{ icon: "mdi:swap-vertical", form: "rounded", label: "Build CV", pos: "b", h: 48 }
n5@{ icon: "mdi:cog", form: "rounded", label: "Combine_CV", pos: "b", h: 48 }
n6@{ icon: "mdi:swap-vertical", form: "rounded", label: "Build JD", pos: "b", h: 48 }
n7@{ icon: "mdi:cog", form: "rounded", label: "Combine_JD", pos: "b", h: 48 }
n8@{ icon: "mdi:swap-vertical", form: "rounded", label: "ATS compare", pos: "b", h: 48 }
n9["<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/>Merge2"]
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/webhook.dark.svg' width='40' height='40' /></div><br/>Respond to Webhook"]
n11@{ icon: "mdi:robot", form: "rounded", label: "Recruiter Check", pos: "b", h: 48 }
n12@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If", pos: "b", h: 48 }
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/webhook.dark.svg' width='40' height='40' /></div><br/>Error_node"]
n14["<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/>ThankYOU message"]
n12 --> n1
n12 --> n2
n12 --> n13
n9 --> n8
n4 --> n5
n6 --> n7
n5 --> n9
n7 --> n9
n8 --> n11
n11 --> n14
n0 -.-> n11
n14 --> n10
n2 --> n6
n1 --> n4
n3 --> n12
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 n11 ai
class n0 aiModel
class n12 decision
class n1,n2,n3,n10,n13 api
class n14 code
classDef customIcon fill:none,stroke:none
class n1,n2,n3,n9,n10,n13,n14 customIcon
The Problem: Resume edits are guesswork without a repeatable ATS lens
Most resume “feedback” isn’t actually feedback. It’s opinion, vibes, and a checklist that changes depending on who looked at it last. If you’re using LinkedIn as your source of truth, the pain gets worse because you’re constantly juggling two inputs (profile and job post), then trying to translate them into ATS-friendly language without losing your voice. The result is slow iteration: you tweak headlines, shuffle bullets, add random keywords, and still don’t know what moved the needle. That back-and-forth costs hours and, frankly, momentum.
It adds up fast. Here’s where it usually breaks down.
- You end up re-reading the same job description multiple times because nothing is structured for comparison.
- Keyword gaps get missed, so your “qualified” profile still looks unrelated to an ATS.
- Advice gets inconsistent across candidates or across weeks, which makes coaching hard to scale.
- Manual copy-paste introduces small errors (wrong company name, outdated metrics) that weaken trust.
The Solution: Compare LinkedIn/CV vs. JD and log ATS-ready guidance
This n8n workflow starts the moment someone submits two links: a LinkedIn profile (or CV page) and a job posting. First, it checks the URLs so you don’t waste API calls on bad inputs. Then it fetches structured profile data and structured job description data via HTTP requests, which is the difference between “AI guessing” and “AI comparing.” After that, the workflow merges the two datasets into a single ATS match payload and sends it into an AI evaluation agent. Finally, it formats the output into a recruiter-friendly message (with matched keywords, missing keywords, and specific optimization tips) and returns it to the user, while also logging the results in Google Sheets so you can track edits and outcomes over time.
The workflow begins at a webhook intake. From there, it gathers profile and job data, assembles clean objects, and runs an ATS-style evaluation using an LLM. At the end, you get a structured response you can paste into coaching notes, plus a row in Google Sheets for history and consistency.
What You Get: Automation vs. Results
| What This Workflow Automates | Results You’ll Get |
|---|---|
|
|
Example: What This Looks Like
Say you’re reviewing 10 SDR resumes a week for one open role. Manually, you might spend about 30 minutes per person rereading the JD, scanning LinkedIn, and writing notes, so around 5 hours weekly. With this workflow, the intake is one webhook submission per candidate (about 1 minute), then a few minutes of processing while n8n fetches data and the AI generates the ATS-style output. You still review and tailor the final advice, but you’re starting from a structured gap analysis, not a blank page.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- GhostGenius API for scraping structured profile and job data
- Google Sheets to log feedback history and outcomes
- Groq API credentials (get it from your Groq account dashboard)
Skill level: Intermediate. You’ll connect credentials, adjust prompts, and map a few fields into Sheets.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
Webhook intake triggers the run. A form (or a simple internal tool) sends two links into n8n: one for the candidate profile and one for the job posting.
URL validation blocks bad inputs. The workflow checks the links first. If they look wrong, it returns a clean error response immediately, so you don’t burn API calls and you don’t log junk to Sheets.
Profile and job data are fetched and cleaned. n8n uses HTTP requests to pull structured CV/LinkedIn data and structured JD data, then aggregates and assembles them into consistent objects you can reuse.
The AI agent performs an ATS-style comparison. The workflow merges CV plus JD, prepares an “ATS match” payload, and sends it to the evaluation agent (Groq chat model). A code step then parses the JSON and formats a recruiter-friendly response.
Results are returned and recorded. The response goes back to the requester, and key outputs can be written to Google Sheets for tracking, follow-ups, and repeatable coaching.
You can easily modify the scoring rubric and output format to match your niche (SDR, product, finance) based on your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Webhook Trigger
Set up the inbound webhook that receives LinkedIn CV and JD URLs from your form.
- Add or open Incoming Form Webhook and set Path to
linkedin. - Set HTTP Method to
POSTand Response Mode toresponseNode. - Enable Authentication with
basicAuth. - Credential Required: Connect your
httpBasicAuthcredentials in Incoming Form Webhook.
Step 2: Connect Profile and Job Data Sources
Configure the API calls that fetch LinkedIn profile and job details, and validate URLs before the calls run.
- In URL Validation Check, ensure both conditions validate LinkedIn URLs: set Left Value to
{{ $json.body.LinkedIn_CV }}and{{ $json.body.LinkedIn_JD }}, and Right Value tolinkedin.com/for both. - Configure Fetch Profile Info with URL
https://api.ghostgenius.fr/v2/profileand add query parameter url ={{ $json.body.LinkedIn_CV }}. - Configure Retrieve Job Info with URL
https://api.ghostgenius.fr/v2/joband add query parameter url ={{ $json.body.LinkedIn_JD }}. - Credential Required: Connect your
httpHeaderAuthcredentials in Fetch Profile Info and Retrieve Job Info. - Credential Required: Connect your
httpBasicAuthcredentials in Fetch Profile Info and Retrieve Job Info.
URL Validation Check outputs to both Fetch Profile Info and Retrieve Job Info in parallel.
⚠️ Common Pitfall: If the form fields are named differently, update {{ $json.body.LinkedIn_CV }} and {{ $json.body.LinkedIn_JD }} to match your actual incoming payload keys.
Step 3: Assemble and Aggregate CV and JD Data
Normalize the fetched data into structured bundles for the ATS evaluation.
- In Assemble CV Data, map fields like headline, summary, and skills using expressions such as
{{ $json.headline }},{{ $json.summary }}, and{{ $json.skills }}. - In Aggregate CV Bundle, set Aggregate to
aggregateAllItemDataand Destination Field Name toCV. - In Compose JD Data, map fields like title, description, and location using expressions such as
{{ $json.title }},{{ $json.description }}, and{{ $json.location }}. - In Aggregate JD Bundle, set Aggregate to
aggregateAllItemDataand Destination Field Name toJD. - In Combine CV and JD, set Mode to
combineand Combine By tocombineAll.
Step 4: Set Up AI Matching with the ATS Agent
Prepare the combined data for analysis and run the ATS evaluation against the Groq model.
- In Prepare ATS Match, set CV to
{{ $json.CV }}and JD to{{ $json.JD }}. - In ATS Evaluation Agent, set Text to the provided prompt string, including
{{ $json.JD.toJsonString() }}and{{ $json.CV.toJsonString() }}. - Ensure Groq Dialogue Engine is connected as the language model for ATS Evaluation Agent.
- Credential Required: Connect your
groqApicredentials in Groq Dialogue Engine (credentials are added to the model node, not the agent).
⚠️ Common Pitfall: The agent is configured to output strict JSON. If you modify the system prompt, keep the schema and formatting rules intact to avoid JSON parsing failures in later steps.
Step 5: Configure Output Responses
Format the ATS analysis into HTML and return the response to the original webhook call, including invalid URL handling.
- In Format Result Message, keep the JavaScript code that parses
item.json.outputand builds thethankYouMessageHTML. - In Return Webhook Reply, set Respond With to
jsonand Response Body to{{ $json }}. - In Invalid URL Response, keep the JSON response body with the
Invalid URLHTML to handle failed validations.
⚠️ Common Pitfall: If Format Result Message encounters invalid JSON, the response will include an error object. Ensure the agent always returns valid JSON strings.
Step 6: Test and Activate Your Workflow
Validate end-to-end execution and enable the workflow for production use.
- Click Execute Workflow and send a POST request to the Incoming Form Webhook URL with
LinkedIn_CVandLinkedIn_JDfields in the body. - Confirm that valid URLs flow through Fetch Profile Info and Retrieve Job Info, then into Assemble CV Data, Compose JD Data, and Combine CV and JD.
- Verify Return Webhook Reply outputs a JSON response containing a
thankYouMessageHTML block. - Toggle the workflow to Active to enable production execution.
Common Gotchas
- GhostGenius API credentials can expire or need specific permissions. If things break, check your GhostGenius dashboard and the headers set in the HTTP Request nodes first.
- 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.
Frequently Asked Questions
About an hour if your API keys are ready.
No. You’ll mainly connect accounts and map fields. The only “code” is optional if you want to heavily customize the formatted output.
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 Groq usage and your scraping API costs from GhostGenius.
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 should. Update the ATS Evaluation Agent instructions to weight SDR signals (quota, outbound volume, meeting set rate, tooling like Salesloft/Outreach). You can also adjust the “Prepare ATS Match” fields so the model always compares the same sections (headline, summary, experience bullets) and returns the same schema for logging.
Usually it’s an auth header issue or an expired key. Regenerate the GhostGenius API key, then update the credentials used by the HTTP Request nodes that call the profile and job endpoints. Also check you’re sending a valid, publicly accessible URL, because private or blocked pages often return incomplete data that breaks downstream parsing.
On a typical n8n Cloud starter plan, plenty for individual job seekers and small coaching batches, but your real limit will usually be API rate limits from the scraping provider and your LLM budget.
Often, yes. This workflow has branching (invalid URL handling), object aggregation, and structured JSON formatting, and those get awkward or expensive in simpler automation tools. n8n also makes it easier to keep the “evaluation rubric” in one place, so you can iterate without rebuilding the whole scenario. If you self-host, you’re not watching task counts like a hawk. Zapier or Make can still work if you only want a lightweight “send links to AI, get a response” flow, but logging structured outputs cleanly is where n8n shines. Talk to an automation expert if you’re not sure which fits.
Once this is set up, you stop reinventing your feedback process for every role and every candidate. The workflow handles the repeatable analysis, and you spend your time on the human part that actually changes outcomes.
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.