This workflow corresponds to n8n.io template #13584 — we link there as the canonical source.
This workflow follows the Agent → Google Sheets 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 →
{
"id": "22HogRsAuRyWszhC",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "LinkedIn Job Search Automation with Claude AI",
"tags": [],
"nodes": [
{
"id": "98cfe668-e941-41b0-81a9-9adf9effedc8",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-432,
-112
],
"parameters": {
"width": 760,
"height": 1100,
"content": "## LinkedIn Job Search Automation with Claude AI\n\nThis AI-powered workflow automatically searches LinkedIn for relevant jobs, scores them using Claude AI based on your profile, sends personalized applications or connection requests, and logs everything to a Google Sheet for tracking.\n\n### How it works\n\n1. **Trigger** - Runs on a schedule or via webhook to start a new job search\n2. **Search LinkedIn** - Fetches job listings based on keywords, location, and filters\n3. **Filter & Deduplicate** - Removes already-applied or seen jobs\n4. **Analyze with Claude AI** - Scores each job against your resume/profile\n5. **Decision Gate** - Only proceeds with jobs above your score threshold\n6. **Apply or Connect** - Sends Easy Apply or connection request to recruiter\n7. **Log Results** - Records all actions in Google Sheets for tracking\n\n### Setup Steps\n\n1. Import this workflow into your n8n instance\n2. Configure credentials:\n - **LinkedIn OAuth2** - LinkedIn Developer Portal\n - **Anthropic API** - For Claude AI job scoring\n - **Google Sheets** - To track applications\n3. Update your profile/resume text in the `Build Search Context` node\n4. Set your job keywords and location preferences\n5. Activate the workflow\n\n### Sample Trigger Payload\n```json\n{\n \"keywords\": \"Product Manager\",\n \"location\": \"Bangalore, India\",\n \"experienceLevel\": \"mid-senior\",\n \"jobType\": \"full-time\",\n \"scoreThreshold\": 70\n}\n```\n\n### Features\n\n- **AI-powered job scoring** based on your skills and experience\n- **Duplicate prevention** - tracks seen and applied jobs\n- **Auto Easy Apply** for matching jobs\n- **Recruiter outreach** with personalized messages\n- **Full audit log** in Google Sheets"
},
"typeVersion": 1
},
{
"id": "dc1eda1a-5166-4963-abbf-c1ba32330c2e",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
348,
296
],
"parameters": {
"color": 4,
"width": 456,
"height": 328,
"content": "## 1. Trigger & Input Validation"
},
"typeVersion": 1
},
{
"id": "82414155-40a9-4cf6-97b2-a25f19d334a9",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
844,
-60
],
"parameters": {
"color": 4,
"width": 808,
"height": 684,
"content": "## 2. Fetch & Filter Jobs"
},
"typeVersion": 1
},
{
"id": "e02d5cdb-6bab-463a-a56e-8b5a390cd04e",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1712,
320
],
"parameters": {
"color": 4,
"width": 712,
"height": 284,
"content": "## 3. AI Scoring & Decision"
},
"typeVersion": 1
},
{
"id": "b9260824-9aa7-40fa-bd3b-e1f4efd6b841",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2480,
208
],
"parameters": {
"color": 4,
"width": 1200,
"height": 492,
"content": "## 4. Apply, Outreach & Log"
},
"typeVersion": 1
},
{
"id": "496796ff-6f97-4271-9140-5123c088f695",
"name": "Receive Job Search Request",
"type": "n8n-nodes-base.webhook",
"position": [
416,
464
],
"parameters": {
"path": "linkedin-job-search",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2
},
{
"id": "9410eb78-deb5-46bf-80fb-9e5da83fa6dc",
"name": "Validate Input and Build Search Params",
"type": "n8n-nodes-base.code",
"position": [
640,
464
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Extract search parameters from request\nconst body = $input.item.json.body || $input.item.json;\n\n// Required fields\nconst required = ['keywords', 'location'];\nconst missing = required.filter(f => !body[f]);\nif (missing.length > 0) {\n throw new Error(`Missing required fields: ${missing.join(', ')}`);\n}\n\n// Default values and normalization\nconst searchParams = {\n keywords: body.keywords.trim(),\n location: body.location.trim(),\n experienceLevel: body.experienceLevel || 'mid-senior',\n jobType: body.jobType || 'full-time',\n datePosted: body.datePosted || 'past-week',\n remote: body.remote || false,\n scoreThreshold: parseInt(body.scoreThreshold) || 70,\n maxApplications: parseInt(body.maxApplications) || 10,\n sendConnectionRequest: Boolean(body.sendConnectionRequest),\n easyApplyOnly: Boolean(body.easyApplyOnly !== false)\n};\n\n// Candidate profile (customize with your own details)\nconst candidateProfile = {\n name: body.candidateName || 'YOUR_NAME',\n currentTitle: body.currentTitle || 'YOUR_CURRENT_TITLE',\n yearsExperience: body.yearsExperience || 5,\n skills: body.skills || ['JavaScript', 'Python', 'Product Management', 'Data Analysis', 'Agile'],\n education: body.education || 'B.Tech Computer Science',\n summary: body.profileSummary || 'Experienced professional seeking new opportunities in the tech industry.'\n};\n\n// Experience level mapping to LinkedIn API codes\nconst expLevelMap = {\n 'internship': '1',\n 'entry': '2',\n 'associate': '3',\n 'mid-senior': '4',\n 'director': '5',\n 'executive': '6'\n};\n\n// Job type mapping\nconst jobTypeMap = {\n 'full-time': 'F',\n 'part-time': 'P',\n 'contract': 'C',\n 'temporary': 'T',\n 'internship': 'I',\n 'volunteer': 'V'\n};\n\nreturn {\n json: {\n searchParams,\n candidateProfile,\n linkedInFilters: {\n f_E: expLevelMap[searchParams.experienceLevel] || '4',\n f_JT: jobTypeMap[searchParams.jobType] || 'F',\n f_TPR: 'r604800',\n f_LF: searchParams.remote ? '2' : undefined,\n f_EA: searchParams.easyApplyOnly ? 'true' : undefined\n },\n metadata: {\n requestId: `LJSR-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n startedAt: new Date().toISOString(),\n applicationsCount: 0\n }\n }\n};"
},
"typeVersion": 2
},
{
"id": "7af17870-28d8-410f-b0ce-e04e4ca72ac1",
"name": "Fetch LinkedIn Job Listings",
"type": "n8n-nodes-base.httpRequest",
"position": [
864,
272
],
"parameters": {
"url": "https://api.linkedin.com/v2/jobSearch",
"options": {
"timeout": 15000
},
"sendQuery": true,
"sendHeaders": true,
"authentication": "predefinedCredentialType",
"queryParameters": {
"parameters": [
{
"name": "keywords",
"value": "={{ $json.searchParams.keywords }}"
},
{
"name": "location",
"value": "={{ $json.searchParams.location }}"
},
{
"name": "f_E",
"value": "={{ $json.linkedInFilters.f_E }}"
},
{
"name": "f_JT",
"value": "={{ $json.linkedInFilters.f_JT }}"
},
{
"name": "f_TPR",
"value": "={{ $json.linkedInFilters.f_TPR }}"
},
{
"name": "count",
"value": "25"
},
{
"name": "start",
"value": "0"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "X-Restli-Protocol-Version",
"value": "2.0.0"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"nodeCredentialType": "linkedInOAuth2Api"
},
"credentials": {
"linkedInOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2,
"continueOnFail": true
},
{
"id": "a3773374-7fcf-4761-be73-799cc11094f7",
"name": "Fetch Individual Job Details",
"type": "n8n-nodes-base.httpRequest",
"position": [
864,
464
],
"parameters": {
"url": "=https://api.linkedin.com/v2/jobs/{{ $json.jobId }}",
"options": {
"timeout": 10000
},
"sendHeaders": true,
"authentication": "predefinedCredentialType",
"headerParameters": {
"parameters": [
{
"name": "X-Restli-Protocol-Version",
"value": "2.0.0"
}
]
},
"nodeCredentialType": "linkedInOAuth2Api"
},
"credentials": {
"linkedInOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2,
"continueOnFail": true
},
{
"id": "2db8558d-1baa-4e0f-9ad3-33b719f8a0e3",
"name": "Parse and Normalize Job Listings",
"type": "n8n-nodes-base.code",
"position": [
1088,
440
],
"parameters": {
"jsCode": "// Get raw LinkedIn job response\nconst jobsResponse = $('Fetch LinkedIn Job Listings').first().json;\nconst searchContext = $('Validate Input and Build Search Params').first().json;\n\nconst jobs = [];\n\n// Handle LinkedIn API response structure\nconst rawJobs = jobsResponse.elements || jobsResponse.jobs || jobsResponse.data || [];\n\nfor (const job of rawJobs) {\n try {\n const parsed = {\n jobId: job.entityUrn?.replace('urn:li:jobPosting:', '') || job.id || '',\n title: job.title || job.jobPostingTitle || 'Unknown Title',\n companyName: job.companyDetails?.company?.name || job.formattedEmployerName || 'Unknown Company',\n companyId: job.companyDetails?.company?.entityUrn?.replace('urn:li:company:', '') || '',\n location: job.formattedLocation || job.workplaceTypes?.[0] || searchContext.searchParams.location,\n description: job.description?.text || job.jobDescription || '',\n descriptionSnippet: (job.description?.text || '').substring(0, 500),\n isEasyApply: Boolean(job.easyApplyEnabled || job.applyMethod?.easyApplyJobApplicationFormCommon),\n jobUrl: `https://www.linkedin.com/jobs/view/${job.entityUrn?.replace('urn:li:jobPosting:', '') || job.id}/`,\n postedAt: job.listedAt ? new Date(job.listedAt).toISOString() : new Date().toISOString(),\n applicantsCount: job.applies || 0,\n salary: job.salaryInsights?.salaryRange?.min\n ? `${job.salaryInsights.salaryRange.min}-${job.salaryInsights.salaryRange.max} ${job.salaryInsights.salaryRange.currencyCode}`\n : 'Not disclosed',\n skills: job.skills?.map(s => s.name) || [],\n seniorityLevel: job.expLevelId || searchContext.searchParams.experienceLevel,\n employmentType: job.employmentStatus || searchContext.searchParams.jobType,\n remote: job.workplaceTypes?.includes('REMOTE') || false\n };\n\n if (parsed.jobId && parsed.title) {\n jobs.push({ json: { job: parsed, searchContext } });\n }\n } catch (err) {\n console.log('Error parsing job:', err.message);\n }\n}\n\nif (jobs.length === 0) {\n throw new Error('No valid job listings found. Check LinkedIn API credentials and search parameters.');\n}\n\nconsole.log(`Parsed ${jobs.length} jobs from LinkedIn`);\nreturn jobs;"
},
"typeVersion": 2
},
{
"id": "aedb66a1-564f-4425-a9f0-8e398d474621",
"name": "Check Already Applied (Google Sheets)",
"type": "n8n-nodes-base.googleSheets",
"position": [
1312,
440
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "id",
"value": "="
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "="
},
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"name": "<your credential>"
}
},
"typeVersion": 4.5,
"continueOnFail": true
},
{
"id": "5b625a70-7933-4c0a-8f6e-7ad9f2249d52",
"name": "Skip Already Seen Jobs",
"type": "n8n-nodes-base.if",
"position": [
1536,
440
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "number",
"operation": "equals"
},
"leftValue": "={{ $json.length || 0 }}",
"rightValue": 0
}
]
}
},
"typeVersion": 2
},
{
"id": "b8080a67-de60-4ec8-a7fc-bd3119b536e4",
"name": "Score Job with Claude AI",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1760,
440
],
"parameters": {
"text": "=You are an expert career coach and resume analyst. Score the following job posting against the candidate profile and return a JSON evaluation.\n\n**Candidate Profile:**\n- Name: {{ $json.searchContext.candidateProfile.name }}\n- Current Title: {{ $json.searchContext.candidateProfile.currentTitle }}\n- Years of Experience: {{ $json.searchContext.candidateProfile.yearsExperience }}\n- Skills: {{ $json.searchContext.candidateProfile.skills.join(', ') }}\n- Education: {{ $json.searchContext.candidateProfile.education }}\n- Summary: {{ $json.searchContext.candidateProfile.summary }}\n\n**Job Posting:**\n- Title: {{ $json.job.title }}\n- Company: {{ $json.job.companyName }}\n- Location: {{ $json.job.location }}\n- Description: {{ $json.job.descriptionSnippet }}\n- Required Skills: {{ $json.job.skills.join(', ') }}\n- Seniority: {{ $json.job.seniorityLevel }}\n- Remote: {{ $json.job.remote }}\n- Salary: {{ $json.job.salary }}\n\n**Scoring Criteria:**\n1. Skills match (0-30 points) - How well candidate skills align with job requirements\n2. Experience level fit (0-25 points) - Years of experience vs role expectations\n3. Title relevance (0-20 points) - How closely current/target title matches\n4. Location/remote compatibility (0-15 points)\n5. Company fit (0-10 points) - Company size, industry, reputation\n\n**Response Format (JSON only, no markdown):**\n{\n \"totalScore\": 82,\n \"breakdown\": {\n \"skillsMatch\": 25,\n \"experienceFit\": 20,\n \"titleRelevance\": 18,\n \"locationFit\": 12,\n \"companyFit\": 7\n },\n \"matchedSkills\": [\"list of matching skills\"],\n \"missingSkills\": [\"list of skills candidate lacks\"],\n \"pros\": [\"top reasons this is a good fit\"],\n \"cons\": [\"main concerns or gaps\"],\n \"shouldApply\": true,\n \"coverLetterHook\": \"One compelling opening sentence for a cover letter\",\n \"connectionMessage\": \"A short personalized LinkedIn connection message (under 300 chars)\"\n}",
"options": {
"systemMessage": "You are a career coach that evaluates job-candidate fit and responds in JSON format only. Never include markdown code blocks or additional text outside the JSON."
},
"promptType": "define"
},
"typeVersion": 1.6
},
{
"id": "32fdfbf9-f7f0-4f47-a93a-b8a03aabbf88",
"name": "Claude AI Model",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"position": [
1832,
664
],
"parameters": {
"model": "=claude-sonnet-4-20250514",
"options": {
"temperature": 0.3
}
},
"credentials": {
"anthropicApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "955d64a8-f686-4b5f-8a50-d6bf20621288",
"name": "Parse AI Score and Decide",
"type": "n8n-nodes-base.code",
"position": [
2112,
440
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const aiResponse = $input.item.json;\nlet aiText = aiResponse.response || aiResponse.output || aiResponse.text || '';\n\n// Handle content array format from Anthropic\nif (aiResponse.content && Array.isArray(aiResponse.content)) {\n aiText = aiResponse.content[0]?.text || '';\n}\n\n// Clean JSON from any markdown code blocks\nconst cleanText = aiText\n .replace(/```json\\s*/g, '')\n .replace(/```\\s*/g, '')\n .trim();\n\nlet aiScore;\ntry {\n aiScore = JSON.parse(cleanText);\n} catch (error) {\n throw new Error(`Failed to parse AI response: ${error.message}. Response was: ${cleanText}`);\n}\n\n// Pull job and search context from upstream\nconst jobData = $('Skip Already Seen Jobs').item.json;\nconst scoreThreshold = jobData.searchContext?.searchParams?.scoreThreshold || 70;\n\nreturn {\n json: {\n job: jobData.job,\n searchContext: jobData.searchContext,\n aiScore,\n scoreThreshold,\n meetsThreshold: (aiScore.totalScore || 0) >= scoreThreshold,\n processedAt: new Date().toISOString()\n }\n};"
},
"typeVersion": 2
},
{
"id": "8b09e7f3-9810-4606-bf72-59bf12213427",
"name": "Check Score Threshold",
"type": "n8n-nodes-base.if",
"position": [
2336,
440
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": false,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "boolean",
"operation": "true"
},
"leftValue": "={{ $json.meetsThreshold }}"
}
]
}
},
"typeVersion": 2
},
{
"id": "1ebcd2fe-afc0-415e-91b3-93d0b0c2f7b7",
"name": "Submit Easy Apply Application",
"type": "n8n-nodes-base.httpRequest",
"position": [
2560,
344
],
"parameters": {
"url": "https://api.linkedin.com/v2/jobs/{{ $json.job.jobId }}/apply",
"method": "POST",
"options": {
"timeout": 15000
},
"jsonBody": "={\n \"jobPostingUrn\": \"urn:li:jobPosting:{{ $json.job.jobId }}\",\n \"applicationData\": {\n \"resumeText\": \"{{ $json.searchContext.candidateProfile.summary }}\",\n \"coverLetter\": \"{{ $json.aiScore.coverLetterHook }} I am excited to apply for the {{ $json.job.title }} position at {{ $json.job.companyName }}.\",\n \"contactInfo\": {\n \"name\": \"{{ $json.searchContext.candidateProfile.name }}\"\n }\n }\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"headerParameters": {
"parameters": [
{
"name": "X-Restli-Protocol-Version",
"value": "2.0.0"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"nodeCredentialType": "linkedInOAuth2Api"
},
"credentials": {
"linkedInOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2,
"continueOnFail": true
},
{
"id": "1d2c0f66-06f1-45f4-a26f-f0e93ad96246",
"name": "Send Recruiter Connection Request",
"type": "n8n-nodes-base.httpRequest",
"position": [
2784,
352
],
"parameters": {
"url": "https://api.linkedin.com/v2/invitations",
"method": "POST",
"options": {
"timeout": 10000
},
"jsonBody": "={\n \"invitee\": {\n \"com.linkedin.voyager.growth.invitation.InviteeProfile\": {\n \"profileId\": \"{{ $json.job.companyId }}\"\n }\n },\n \"message\": \"{{ $json.aiScore.connectionMessage }}\",\n \"trackingId\": \"{{ $json.searchContext.metadata.requestId }}\"\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"headerParameters": {
"parameters": [
{
"name": "X-Restli-Protocol-Version",
"value": "2.0.0"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"nodeCredentialType": "linkedInOAuth2Api"
},
"credentials": {
"linkedInOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2,
"continueOnFail": true
},
{
"id": "2d335fe0-355b-4d83-a9e6-9ca8a3840a98",
"name": "Format Applied Job Result",
"type": "n8n-nodes-base.code",
"position": [
3008,
344
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const jobData = $('Parse AI Score and Decide').item.json;\nconst applyResponse = $('Submit Easy Apply Application').item.json;\nconst connectionResponse = $('Send Recruiter Connection Request').item.json;\n\nconst applicationSuccess = !applyResponse.error && (applyResponse.status === 200 || applyResponse.id);\nconst connectionSuccess = !connectionResponse.error && (connectionResponse.id || connectionResponse.createdAt);\n\nreturn {\n json: {\n status: 'APPLIED',\n jobId: jobData.job.jobId,\n jobTitle: jobData.job.title,\n company: jobData.job.companyName,\n location: jobData.job.location,\n jobUrl: jobData.job.jobUrl,\n salary: jobData.job.salary,\n aiScore: jobData.aiScore.totalScore,\n matchedSkills: jobData.aiScore.matchedSkills,\n missingSkills: jobData.aiScore.missingSkills,\n pros: jobData.aiScore.pros,\n cons: jobData.aiScore.cons,\n applicationSubmitted: applicationSuccess,\n connectionRequestSent: connectionSuccess,\n appliedAt: new Date().toISOString(),\n requestId: jobData.searchContext.metadata.requestId\n }\n};"
},
"typeVersion": 2
},
{
"id": "7da61876-fc9e-41a6-abad-ee3e0512fcb6",
"name": "Format Skipped Job Result",
"type": "n8n-nodes-base.code",
"position": [
3008,
536
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const jobData = $input.item.json;\n\nreturn {\n json: {\n status: 'SKIPPED_LOW_SCORE',\n jobId: jobData.job.jobId,\n jobTitle: jobData.job.title,\n company: jobData.job.companyName,\n location: jobData.job.location,\n jobUrl: jobData.job.jobUrl,\n salary: jobData.job.salary,\n aiScore: jobData.aiScore.totalScore,\n scoreThreshold: jobData.scoreThreshold,\n matchedSkills: jobData.aiScore.matchedSkills,\n missingSkills: jobData.aiScore.missingSkills,\n reason: `Score ${jobData.aiScore.totalScore} below threshold of ${jobData.scoreThreshold}`,\n processedAt: new Date().toISOString(),\n requestId: jobData.searchContext.metadata.requestId\n }\n};"
},
"typeVersion": 2
},
{
"id": "b9bf9f93-e782-41e1-9816-be4cbcb3b8fa",
"name": "Log All Results to Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
3232,
440
],
"parameters": {
"columns": {
"value": {},
"schema": [],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "id",
"value": "="
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "="
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.5,
"continueOnFail": true
},
{
"id": "fe51ad52-a980-4eee-b9d5-4c3bf4da9b7e",
"name": "Send Summary Response",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
3456,
440
],
"parameters": {
"options": {
"responseHeaders": {
"entries": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"respondWith": "json",
"responseBody": "={{ JSON.stringify($json, null, 2) }}"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "b9ca1fac-36b1-46a2-ae5e-8996211179a8",
"connections": {
"Claude AI Model": {
"ai_languageModel": [
[
{
"node": "Score Job with Claude AI",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Check Score Threshold": {
"main": [
[
{
"node": "Submit Easy Apply Application",
"type": "main",
"index": 0
}
],
[
{
"node": "Format Skipped Job Result",
"type": "main",
"index": 0
}
]
]
},
"Skip Already Seen Jobs": {
"main": [
[
{
"node": "Score Job with Claude AI",
"type": "main",
"index": 0
}
]
]
},
"Score Job with Claude AI": {
"main": [
[
{
"node": "Parse AI Score and Decide",
"type": "main",
"index": 0
}
]
]
},
"Format Applied Job Result": {
"main": [
[
{
"node": "Log All Results to Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Format Skipped Job Result": {
"main": [
[
{
"node": "Log All Results to Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Parse AI Score and Decide": {
"main": [
[
{
"node": "Check Score Threshold",
"type": "main",
"index": 0
}
]
]
},
"Receive Job Search Request": {
"main": [
[
{
"node": "Validate Input and Build Search Params",
"type": "main",
"index": 0
}
]
]
},
"Fetch LinkedIn Job Listings": {
"main": [
[
{
"node": "Parse and Normalize Job Listings",
"type": "main",
"index": 0
}
]
]
},
"Submit Easy Apply Application": {
"main": [
[
{
"node": "Send Recruiter Connection Request",
"type": "main",
"index": 0
}
]
]
},
"Log All Results to Google Sheets": {
"main": [
[
{
"node": "Send Summary Response",
"type": "main",
"index": 0
}
]
]
},
"Parse and Normalize Job Listings": {
"main": [
[
{
"node": "Check Already Applied (Google Sheets)",
"type": "main",
"index": 0
}
]
]
},
"Send Recruiter Connection Request": {
"main": [
[
{
"node": "Format Applied Job Result",
"type": "main",
"index": 0
}
]
]
},
"Check Already Applied (Google Sheets)": {
"main": [
[
{
"node": "Skip Already Seen Jobs",
"type": "main",
"index": 0
}
]
]
},
"Validate Input and Build Search Params": {
"main": [
[
{
"node": "Fetch LinkedIn Job Listings",
"type": "main",
"index": 0
},
{
"node": "Fetch Individual Job Details",
"type": "main",
"index": 0
},
{
"node": "Parse and Normalize Job Listings",
"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.
anthropicApigoogleApigoogleSheetsOAuth2ApilinkedInOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This AI-powered workflow automatically searches LinkedIn for relevant jobs, scores them using Claude AI based on your profile, sends personalized applications or connection requests, and logs everything to a Google Sheet for tracking. Trigger - Runs on a schedule or via webhook…
Source: https://n8n.io/workflows/13584/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
⏺ 🚀 How it works
Airtable Operations System: Leads, AI Agent, Outreach, Sync, Canva, Make/Zapier Bridge. Uses airtable, anthropic, slack, agent. Webhook trigger; 82 nodes.
Fully automates your service order pipeline from incoming booking to supplier confirmation — with built-in SLA enforcement and automatic escalation if a supplier goes silent. 📥 Receives orders via web
A complete WhatsApp AI chatbot that handles class bookings, cancellations, FAQ responses, schedule lookups, location queries, waitlist management, booking reminders, and staff notifications — all thro
A complete WhatsApp AI chatbot that handles class bookings, cancellations, FAQ responses, schedule lookups, location queries, waitlist management, booking reminders, survey, and staff notifications —