This workflow corresponds to n8n.io template #16560 — we link there as the canonical source.
This workflow follows the Apifyn8N Nodes Apify → 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": "QtjqMGF821LVtx7R",
"name": "Scrape job listings daily, score with AI and auto-generate cover letters in Google Sheets",
"tags": [],
"nodes": [
{
"id": "9e3a21a8-b23d-4cf4-a25b-3bbb037a6300",
"name": "Manual trigger",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-624,
-176
],
"parameters": {},
"typeVersion": 1
},
{
"id": "1eded2c8-c807-47bf-b274-8cb6fe6737cf",
"name": "Set: Google Jobs config",
"type": "n8n-nodes-base.set",
"position": [
240,
-96
],
"parameters": {},
"typeVersion": 3.4
},
{
"id": "69a9e296-8fc7-477f-ae61-66ade7c4cbc7",
"name": "Apify: run Google Jobs actor",
"type": "@apify/n8n-nodes-apify.apify",
"onError": "continueErrorOutput",
"position": [
464,
-96
],
"parameters": {},
"typeVersion": 1
},
{
"id": "451555a5-6685-47c9-a1e5-2c0656297fa6",
"name": "Apify: get Google Jobs dataset",
"type": "@apify/n8n-nodes-apify.apify",
"position": [
688,
-112
],
"parameters": {},
"typeVersion": 1
},
{
"id": "bb5b5dcb-a501-46bb-98c0-6eb99717b3e1",
"name": "Code: normalise Google Jobs",
"type": "n8n-nodes-base.code",
"position": [
912,
-96
],
"parameters": {},
"typeVersion": 2
},
{
"id": "ba5aa67b-2010-40a0-a263-16e6fa5f9e03",
"name": "Merge: platform results",
"type": "n8n-nodes-base.merge",
"position": [
1296,
112
],
"parameters": {},
"typeVersion": 3.2
},
{
"id": "7251ea6b-35b3-49c9-abcf-fdab68a6ba8a",
"name": "Set: Career Site API config",
"type": "n8n-nodes-base.set",
"position": [
240,
96
],
"parameters": {},
"typeVersion": 3.4
},
{
"id": "b664d524-2638-43f2-a9bd-9d57583f86df",
"name": "Apify: run Career Site API actor",
"type": "@apify/n8n-nodes-apify.apify",
"onError": "continueErrorOutput",
"position": [
464,
96
],
"parameters": {},
"typeVersion": 1
},
{
"id": "1b8e621c-3dcd-4153-a46f-1a4c94281b97",
"name": "Apify: get Career Site dataset",
"type": "@apify/n8n-nodes-apify.apify",
"position": [
688,
96
],
"parameters": {},
"typeVersion": 1
},
{
"id": "9fbdf0be-4757-4395-b463-29b59bd039a4",
"name": "Code: normalise Career Site API",
"type": "n8n-nodes-base.code",
"position": [
912,
96
],
"parameters": {},
"typeVersion": 2
},
{
"id": "f9cbf2f1-ebec-4271-a9fb-c5d70156456f",
"name": "Schedule trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-592,
112
],
"parameters": {},
"typeVersion": 1.3
},
{
"id": "eb26c803-be4c-4664-bfc0-d05b18808757",
"name": "Set: batch complete",
"type": "n8n-nodes-base.set",
"position": [
-480,
592
],
"parameters": {},
"typeVersion": 3.4
},
{
"id": "02389ace-d81b-4b6c-a017-361662c39bd4",
"name": "Google Sheets: check if job exists",
"type": "n8n-nodes-base.googleSheets",
"position": [
32,
576
],
"parameters": {},
"typeVersion": 4.7,
"alwaysOutputData": true
},
{
"id": "046a2966-0032-4fa9-aa19-f233a50b5ed4",
"name": "Set: restore job data",
"type": "n8n-nodes-base.set",
"position": [
256,
576
],
"parameters": {},
"typeVersion": 3.4
},
{
"id": "8dba7e2b-cd38-41c0-bf89-9cd5ac4f267f",
"name": "IF: already in sheet?",
"type": "n8n-nodes-base.if",
"position": [
464,
576
],
"parameters": {},
"typeVersion": 2.3
},
{
"id": "8fac9b08-d376-4185-ae2e-1a183bf4a2e1",
"name": "Loop: process batch",
"type": "n8n-nodes-base.splitInBatches",
"position": [
-112,
1056
],
"parameters": {},
"typeVersion": 3
},
{
"id": "817eb6cb-a458-4a54-8f9a-4b94cd4e14c6",
"name": "IF: apply URL present?",
"type": "n8n-nodes-base.if",
"position": [
688,
592
],
"parameters": {},
"typeVersion": 2.3
},
{
"id": "e737d5b1-b4bf-458c-bf6a-a15578d29ee9",
"name": "IF: description >= 200 chars?",
"type": "n8n-nodes-base.if",
"position": [
944,
576
],
"parameters": {},
"typeVersion": 2.3
},
{
"id": "f6ed725d-7522-44ff-828a-f39c037c993b",
"name": "IF: mid-level or senior?",
"type": "n8n-nodes-base.if",
"position": [
1184,
560
],
"parameters": {},
"typeVersion": 2.3
},
{
"id": "14178a53-c7b3-4853-a256-544aa74a89be",
"name": "Google Docs: GET base resume",
"type": "n8n-nodes-base.googleDocs",
"position": [
1536,
672
],
"parameters": {},
"executeOnce": true,
"typeVersion": 2
},
{
"id": "3ec567fc-8791-4b06-8e0c-99a6b01ee967",
"name": "OpenAI: score job relevance",
"type": "@n8n/n8n-nodes-langchain.openAi",
"onError": "continueErrorOutput",
"position": [
288,
1088
],
"parameters": {},
"typeVersion": 2.3
},
{
"id": "87c2a95e-ae30-430a-96d3-2589a74d46b8",
"name": "Code: parse + validate score JSON",
"type": "n8n-nodes-base.code",
"position": [
592,
1072
],
"parameters": {},
"typeVersion": 2
},
{
"id": "401dc1e3-3bd1-4af1-bbc6-c79a66a0ed76",
"name": "Filter: valid score only",
"type": "n8n-nodes-base.filter",
"position": [
800,
1072
],
"parameters": {},
"typeVersion": 2.3
},
{
"id": "2d9e63f0-13e2-4e9e-92aa-a4155a52eab2",
"name": "IF: score >= 7?",
"type": "n8n-nodes-base.if",
"position": [
1008,
1072
],
"parameters": {},
"typeVersion": 2.3
},
{
"id": "6fda462c-1437-4fd8-9c7e-a4cee423145c",
"name": "OpenAI: write cover letter",
"type": "@n8n/n8n-nodes-langchain.openAi",
"onError": "continueErrorOutput",
"position": [
-128,
1616
],
"parameters": {},
"typeVersion": 2.3
},
{
"id": "67b6b812-26b0-4ce3-840f-14f528801c48",
"name": "Set: store cover letter",
"type": "n8n-nodes-base.set",
"position": [
256,
1600
],
"parameters": {},
"typeVersion": 3.4
},
{
"id": "8ce3ff89-dd90-44fe-8ed1-80062cd92408",
"name": "IF: score >= 8?",
"type": "n8n-nodes-base.if",
"position": [
448,
1600
],
"parameters": {},
"typeVersion": 2.3
},
{
"id": "8e986237-8cf7-477e-a0f9-9969e61f397f",
"name": "OpenAI: write tailored resume",
"type": "@n8n/n8n-nodes-langchain.openAi",
"onError": "continueErrorOutput",
"position": [
688,
1584
],
"parameters": {},
"typeVersion": 2.3
},
{
"id": "9558ad2b-8e3b-41d7-9d64-6a2556fa10f0",
"name": "Google Docs: create resume doc",
"type": "n8n-nodes-base.googleDocs",
"position": [
1072,
1568
],
"parameters": {},
"typeVersion": 2
},
{
"id": "4b513cf1-d8b4-4602-a910-a245c3d893b5",
"name": "Google Docs: update doc content",
"type": "n8n-nodes-base.googleDocs",
"position": [
1280,
1568
],
"parameters": {},
"typeVersion": 2
},
{
"id": "2f90878b-839b-4b19-a041-126e714687e0",
"name": "HTTP: make resume doc public",
"type": "n8n-nodes-base.httpRequest",
"position": [
1504,
1568
],
"parameters": {},
"typeVersion": 4.4
},
{
"id": "5986dd86-8e1a-40b6-85d9-0022bd060b5a",
"name": "Set: resume URL",
"type": "n8n-nodes-base.set",
"position": [
1728,
1568
],
"parameters": {},
"typeVersion": 3.4
},
{
"id": "8133201a-acd6-4fcf-a115-7cc829450b3d",
"name": "Set: no resume URL",
"type": "n8n-nodes-base.set",
"position": [
928,
1776
],
"parameters": {},
"typeVersion": 3.4
},
{
"id": "6fcbd8c0-cc09-4612-a604-891a93fc6386",
"name": "Google Sheets: append or update row",
"type": "n8n-nodes-base.googleSheets",
"position": [
1936,
1776
],
"parameters": {},
"typeVersion": 4.7
},
{
"id": "c8263a5c-e5e0-45ef-989b-71627bf69ec9",
"name": "Error: catch all",
"type": "n8n-nodes-base.errorTrigger",
"position": [
2240,
-32
],
"parameters": {},
"typeVersion": 1
},
{
"id": "f08476fe-493e-4855-8faa-47a16440ca2a",
"name": "Set: format error message",
"type": "n8n-nodes-base.set",
"position": [
2256,
176
],
"parameters": {},
"typeVersion": 3.4
},
{
"id": "099b93a8-b242-46f6-a27d-8424163da825",
"name": "Merge: error outputs",
"type": "n8n-nodes-base.merge",
"position": [
2224,
432
],
"parameters": {},
"typeVersion": 3.2
},
{
"id": "57ea0a55-05a5-4ddf-886b-6fc3b5f6ee43",
"name": "Gmail: send error notification",
"type": "n8n-nodes-base.gmail",
"position": [
2224,
688
],
"parameters": {},
"typeVersion": 2.2
},
{
"id": "9158f284-8401-4dcb-a53c-8e5790dfcd40",
"name": "Configure Workflow Variables",
"type": "n8n-nodes-base.set",
"notes": "Fill in all five values before activating. This node is disconnected by design.",
"position": [
-208,
-176
],
"parameters": {},
"typeVersion": 3.4
},
{
"id": "be674c62-3de6-4332-9eaf-5dab2a1935e4",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2032,
-256
],
"parameters": {
"content": ""
},
"typeVersion": 1
},
{
"id": "44a45cd1-1472-4f1e-aa19-d5ebf1f3a49b",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-352,
-272
],
"parameters": {
"content": ""
},
"typeVersion": 1
},
{
"id": "b8aa7c26-35b5-4b4f-874c-a9414be77be1",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-784,
-288
],
"parameters": {
"content": ""
},
"typeVersion": 1
},
{
"id": "01fe0b07-9817-4a69-b365-445b1f850c8c",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
160,
-256
],
"parameters": {
"content": ""
},
"typeVersion": 1
},
{
"id": "c60752d4-72e0-46f8-a7e7-ff4572a81310",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
400
],
"parameters": {
"content": ""
},
"typeVersion": 1
},
{
"id": "5f8380b1-dcc4-4989-baae-f0c510555589",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
240,
928
],
"parameters": {
"content": ""
},
"typeVersion": 1
},
{
"id": "6c9b5199-57e6-4c0c-ba3b-64ece1359f77",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-304,
944
],
"parameters": {
"content": ""
},
"typeVersion": 1
},
{
"id": "f6883306-00a3-4444-b72b-063f672cad76",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
-800,
1520
],
"parameters": {
"content": ""
},
"typeVersion": 1
},
{
"id": "d78dab69-112e-4dd5-a595-4a5aec9e2508",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
672,
1392
],
"parameters": {
"content": ""
},
"typeVersion": 1
},
{
"id": "9c3b1d6e-39e5-42ab-8927-8776234e9518",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
-640,
432
],
"parameters": {
"content": ""
},
"typeVersion": 1
},
{
"id": "0f524b81-3037-4c3f-a31d-906aedbbcc00",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
2032,
-176
],
"parameters": {
"content": ""
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"executionOrder": "v1"
},
"versionId": "cc3a371f-bdb5-4cc6-a804-0b73901e180e",
"connections": {
"Manual trigger": {
"main": [
[
{
"node": "Configure Workflow Variables",
"type": "main",
"index": 0
}
]
]
},
"IF: score >= 7?": {
"main": [
[
{
"node": "OpenAI: write cover letter",
"type": "main",
"index": 0
}
],
[
{
"node": "Loop: process batch",
"type": "main",
"index": 0
}
]
]
},
"IF: score >= 8?": {
"main": [
[
{
"node": "OpenAI: write tailored resume",
"type": "main",
"index": 0
}
],
[
{
"node": "Set: no resume URL",
"type": "main",
"index": 0
}
]
]
},
"Set: resume URL": {
"main": [
[
{
"node": "Google Sheets: append or update row",
"type": "main",
"index": 0
}
]
]
},
"Error: catch all": {
"main": [
[
{
"node": "Set: format error message",
"type": "main",
"index": 0
}
]
]
},
"Schedule trigger": {
"main": [
[
{
"node": "Configure Workflow Variables",
"type": "main",
"index": 0
}
]
]
},
"Set: no resume URL": {
"main": [
[
{
"node": "Google Sheets: append or update row",
"type": "main",
"index": 0
}
]
]
},
"Loop: process batch": {
"main": [
[
{
"node": "Set: batch complete",
"type": "main",
"index": 0
}
],
[
{
"node": "Google Sheets: check if job exists",
"type": "main",
"index": 0
}
]
]
},
"Merge: error outputs": {
"main": [
[
{
"node": "Gmail: send error notification",
"type": "main",
"index": 0
}
]
]
},
"IF: already in sheet?": {
"main": [
[
{
"node": "Loop: process batch",
"type": "main",
"index": 0
}
],
[
{
"node": "IF: apply URL present?",
"type": "main",
"index": 0
}
]
]
},
"Set: restore job data": {
"main": [
[
{
"node": "IF: already in sheet?",
"type": "main",
"index": 0
}
]
]
},
"IF: apply URL present?": {
"main": [
[
{
"node": "IF: description >= 200 chars?",
"type": "main",
"index": 0
}
],
[
{
"node": "Loop: process batch",
"type": "main",
"index": 0
}
]
]
},
"Merge: platform results": {
"main": [
[
{
"node": "Loop: process batch",
"type": "main",
"index": 0
}
]
]
},
"Set: Google Jobs config": {
"main": [
[
{
"node": "Apify: run Google Jobs actor",
"type": "main",
"index": 0
}
]
]
},
"Set: store cover letter": {
"main": [
[
{
"node": "IF: score >= 8?",
"type": "main",
"index": 0
}
]
]
},
"Filter: valid score only": {
"main": [
[
{
"node": "IF: score >= 7?",
"type": "main",
"index": 0
}
]
]
},
"IF: mid-level or senior?": {
"main": [
[
{
"node": "Google Docs: GET base resume",
"type": "main",
"index": 0
}
]
]
},
"Set: format error message": {
"main": [
[
{
"node": "Merge: error outputs",
"type": "main",
"index": 0
},
{
"node": "Merge: error outputs",
"type": "main",
"index": 1
}
]
]
},
"OpenAI: write cover letter": {
"main": [
[
{
"node": "Set: store cover letter",
"type": "main",
"index": 0
}
]
]
},
"Code: normalise Google Jobs": {
"main": [
[
{
"node": "Merge: platform results",
"type": "main",
"index": 0
}
]
]
},
"OpenAI: score job relevance": {
"main": [
[
{
"node": "Code: parse + validate score JSON",
"type": "main",
"index": 0
}
]
]
},
"Set: Career Site API config": {
"main": [
[
{
"node": "Apify: run Career Site API actor",
"type": "main",
"index": 0
}
]
]
},
"Apify: run Google Jobs actor": {
"main": [
[
{
"node": "Apify: get Google Jobs dataset",
"type": "main",
"index": 0
}
]
]
},
"Configure Workflow Variables": {
"main": [
[
{
"node": "Set: Google Jobs config",
"type": "main",
"index": 0
},
{
"node": "Set: Career Site API config",
"type": "main",
"index": 0
}
]
]
},
"Google Docs: GET base resume": {
"main": [
[
{
"node": "OpenAI: score job relevance",
"type": "main",
"index": 0
}
]
]
},
"HTTP: make resume doc public": {
"main": [
[
{
"node": "Set: resume URL",
"type": "main",
"index": 0
}
]
]
},
"IF: description >= 200 chars?": {
"main": [
[
{
"node": "IF: mid-level or senior?",
"type": "main",
"index": 0
}
],
[
{
"node": "Loop: process batch",
"type": "main",
"index": 0
}
]
]
},
"OpenAI: write tailored resume": {
"main": [
[
{
"node": "Google Docs: create resume doc",
"type": "main",
"index": 0
}
]
]
},
"Apify: get Career Site dataset": {
"main": [
[
{
"node": "Code: normalise Career Site API",
"type": "main",
"index": 0
}
]
]
},
"Apify: get Google Jobs dataset": {
"main": [
[
{
"node": "Code: normalise Google Jobs",
"type": "main",
"index": 0
}
]
]
},
"Google Docs: create resume doc": {
"main": [
[
{
"node": "Google Docs: update doc content",
"type": "main",
"index": 0
}
]
]
},
"Code: normalise Career Site API": {
"main": [
[
{
"node": "Merge: platform results",
"type": "main",
"index": 1
}
]
]
},
"Google Docs: update doc content": {
"main": [
[
{
"node": "HTTP: make resume doc public",
"type": "main",
"index": 0
}
]
]
},
"Apify: run Career Site API actor": {
"main": [
[
{
"node": "Apify: get Career Site dataset",
"type": "main",
"index": 0
}
]
]
},
"Code: parse + validate score JSON": {
"main": [
[
{
"node": "Filter: valid score only",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets: check if job exists": {
"main": [
[
{
"node": "Set: restore job data",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets: append or update row": {
"main": [
[
{
"node": "Loop: process batch",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow runs on a schedule to scrape job listings via Apify (Google Jobs and Career Site API), scores each role against your base resume using OpenAI, generates tailored cover letter and optionally a tailored resume in Google Docs, and logs the results to Google Sheets…
Source: https://n8n.io/workflows/16560/ — 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.
This workflow is Part 2 of the HR Client Acquisition system and builds on the lead discovery pipeline from the previous workflow:
This tutorial details an end-to-end automation solution for streamlining the lien filing process for Homeowners Associations (HOAs) using an n8n workflow. It significantly reduces manual effort and po
Community nodes are used, and template can only be used on self-hosted n8n instances. Sales Development Representatives (SDRs) Business Development Teams Growth Hackers Startup Founders Marketing Agen
Search → Scrape → Qualify → CRM → Email Draft Automation
This workflow is designed for entrepreneurs, sales teams, marketers, and agencies who want to automate lead discovery and build qualified business contact lists — without manual searching or copying d