This workflow corresponds to n8n.io template #10080 — we link there as the canonical source.
This workflow follows the Emailsend → 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": "pHbBtdjeo2u8avrY",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "AI Candidate Screening & Interview Scheduler",
"tags": [],
"nodes": [
{
"id": "6bb2e121-0353-43a0-96f3-1e881f9ea9e9",
"name": "Webhook - Receive Application",
"type": "n8n-nodes-base.webhook",
"notes": "\ud83d\udce5 ENTRY POINT\n\nThis webhook receives job applications from candidates.\n\nExpected data:\n- Candidate Name\n- Email\n- Phone\n- Resume (URL or text)\n- Cover Letter\n- Years of Experience\n- Skills\n\nURL: https://your-n8n-instance.com/webhook/job-application",
"position": [
-1008,
1552
],
"parameters": {
"path": "job-application",
"options": {},
"responseMode": "responseNode"
},
"typeVersion": 1
},
{
"id": "8fa4ef36-d737-446c-a4aa-ca7eef8654dc",
"name": "Sticky Note - Workflow Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
-832,
576
],
"parameters": {
"color": 3,
"width": 350,
"height": 400,
"content": "## \ud83d\udccb Workflow Overview\n\nThis workflow automates the complete recruitment process:\n\n1\ufe0f\u20e3 Receive applications via webhook\n2\ufe0f\u20e3 Store in database/spreadsheet\n3\ufe0f\u20e3 AI evaluates candidate fit\n4\ufe0f\u20e3 Score and rank candidates\n5\ufe0f\u20e3 Send notifications\n6\ufe0f\u20e3 Schedule interviews for qualified candidates\n\n**Role:** Automation Specialist\n**AI Used:** OpenAI GPT for evaluation"
},
"typeVersion": 1
},
{
"id": "a34130de-94c4-4760-8883-3b778afe6319",
"name": "Google Sheets - Store Application",
"type": "n8n-nodes-base.googleSheets",
"notes": "\ud83d\udcbe DATA STORAGE\n\nStores all application data in Google Sheets for:\n- Easy tracking and management\n- Historical record keeping\n- Team collaboration\n- Backup of all applications\n\nAlternative: Can use Airtable, PostgreSQL, or MySQL instead",
"position": [
-784,
1552
],
"parameters": {
"columns": {
"value": {},
"schema": [],
"mappingMode": "autoMapInputData",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "=Applications"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "=34yuhedwqre"
},
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"name": "<your credential>"
}
},
"typeVersion": 4
},
{
"id": "47f948e2-6945-4b41-95fb-7ffc04d488af",
"name": "Sticky Note - Storage Info",
"type": "n8n-nodes-base.stickyNote",
"position": [
-848,
1136
],
"parameters": {
"color": 5,
"width": 220,
"height": 584,
"content": "## \ud83d\udcca Database Storage\n\nApplications are stored with:\n- Timestamp\n- Contact information\n- Experience details\n- Skills list\n- Resume link\n- Current status\n\nThis creates an applicant tracking system (ATS)"
},
"typeVersion": 1
},
{
"id": "dc349940-72dc-49bf-b44f-68510c5e923a",
"name": "OpenAI - AI Candidate Evaluation",
"type": "@n8n/n8n-nodes-langchain.openAi",
"notes": "\ud83e\udd16 AI EVALUATION ENGINE\n\nUses GPT-4 to:\n- Analyze candidate qualifications\n- Match skills against job requirements\n- Identify strengths and gaps\n- Provide objective scoring (0-100)\n- Generate hiring recommendation\n\nBenefits:\n- Consistent evaluation criteria\n- Unbiased initial screening\n- Faster processing\n- Detailed insights",
"position": [
-560,
1552
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "id",
"value": "=add your model"
},
"options": {
"temperature": 0.3
},
"messages": {
"values": [
{
"content": "=Your name is Rayan and you are an expert technical recruiter evaluating candidates for an Automation Specialist position.\n\nJob Requirements:\n- 3+ years of experience in automation\n- Strong skills in n8n, Make.com, or Zapier\n- Programming: Python, JavaScript\n- API integration experience\n- Workflow design expertise\n- Problem-solving abilities\n\nCandidate Information:\nName: {{ $json.body.name }}\nExperience: {{ $json.body.experience }} years\nSkills: {{ $json.body.skills }}\nResume Summary: {{ $json.body.resume }}\n\nEvaluate this candidate and provide:\n1. Overall Score (0-100)\n2. Strengths (3-5 points)\n3. Weaknesses (2-3 points)\n4. Recommendation (Strong Hire / Hire / Maybe / Reject)\n5. Key concerns or highlights\n\nFormat your response as JSON:\n{\n \"score\": 85,\n \"recommendation\": \"Hire\",\n \"strengths\": [\"...\"],\n \"weaknesses\": [\"...\"],\n \"summary\": \"...\"\n}"
}
]
}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "a99cf7ab-03db-4a7e-98fe-4a8025a03cd2",
"name": "Sticky Note - AI Process",
"type": "n8n-nodes-base.stickyNote",
"position": [
-608,
1136
],
"parameters": {
"color": 5,
"width": 204,
"height": 584,
"content": "## \ud83e\udde0 AI Evaluation\n\nThe AI analyzes:\n\u2713 Experience level match\n\u2713 Technical skills alignment\n\u2713 Automation tool proficiency\n\u2713 Programming capabilities\n\u2713 Overall candidate fit\n\nOutput: Structured evaluation report"
},
"typeVersion": 1
},
{
"id": "2a7f8223-ee02-4c1a-90c4-9cda4ac86831",
"name": "Code - Process Evaluation",
"type": "n8n-nodes-base.code",
"notes": "\u2699\ufe0f DATA PROCESSING\n\nThis node:\n- Parses AI evaluation response\n- Extracts structured data (score, recommendation)\n- Combines candidate + evaluation data\n- Determines next step (Interview or Reject)\n- Handles errors gracefully\n\nThreshold: Score \u2265 70 \u2192 Interview",
"position": [
-336,
1552
],
"parameters": {
"jsCode": "// Parse AI response and structure data\nconst aiResponse = $input.first().json.message.content;\nlet evaluation;\n\ntry {\n // Extract JSON from AI response\n const jsonMatch = aiResponse.match(/\\{[\\s\\S]*\\}/);\n evaluation = JSON.parse(jsonMatch[0]);\n} catch (error) {\n // Fallback if JSON parsing fails\n evaluation = {\n score: 50,\n recommendation: \"Needs Review\",\n strengths: [\"Unable to parse\"],\n weaknesses: [\"AI response format error\"],\n summary: aiResponse\n };\n}\n\n// Get original application data\nconst applicationData = $('Webhook - Receive Application').first().json.body;\n\n// Combine all data\nreturn {\n json: {\n candidate: {\n name: applicationData.name,\n email: applicationData.email,\n phone: applicationData.phone,\n experience: applicationData.experience,\n skills: applicationData.skills\n },\n evaluation: {\n score: evaluation.score,\n recommendation: evaluation.recommendation,\n strengths: evaluation.strengths,\n weaknesses: evaluation.weaknesses,\n summary: evaluation.summary,\n evaluatedAt: new Date().toISOString()\n },\n decision: evaluation.score >= 70 ? \"Interview\" : \"Reject\"\n }\n};"
},
"typeVersion": 2
},
{
"id": "890d9265-4b7c-4cee-8541-08ac6dd7832d",
"name": "IF - Check Score Threshold",
"type": "n8n-nodes-base.if",
"notes": "\ud83d\udd00 DECISION POINT\n\nRoutes candidates based on evaluation:\n\n\u2705 TRUE (Score \u2265 70):\n- Send interview invitation\n- Schedule meeting\n- Update status to 'Interview Scheduled'\n\n\u274c FALSE (Score < 70):\n- Send rejection email\n- Update status to 'Rejected'\n- Archive application",
"position": [
-112,
1552
],
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ $json.decision }}",
"value2": "Interview",
"operation": "equals"
}
]
}
},
"typeVersion": 1
},
{
"id": "d9d8619f-79bf-47d8-b0fd-7f7e9d1054e1",
"name": "Sticky Note - Decision Logic",
"type": "n8n-nodes-base.stickyNote",
"position": [
-368,
1216
],
"parameters": {
"color": 5,
"width": 380,
"height": 496,
"content": "## \ud83c\udfaf Scoring Logic\n\nScore \u2265 70: Qualified for interview\nScore < 70: Not a fit\n\nThis threshold can be adjusted based on:\n- Role requirements\n- Application volume\n- Hiring urgency"
},
"typeVersion": 1
},
{
"id": "5ee3c07a-d3b2-4c73-aadc-54ef03bf7ec9",
"name": "Email - Interview Invitation",
"type": "n8n-nodes-base.emailSend",
"notes": "\u2709\ufe0f INTERVIEW INVITATION\n\nSends personalized email to qualified candidates:\n- Congratulatory message\n- Evaluation highlights\n- Next steps information\n- Request for confirmation\n\nAlternative: Use SendGrid, Gmail, or Outlook node",
"position": [
112,
1456
],
"parameters": {
"text": "=Dear {{ $json.candidate.name }},\n\nCongratulations! We were impressed with your application for the Automation Specialist position.\n\nEvaluation Summary:\n- Overall Score: {{ $json.evaluation.score }}/100\n- Recommendation: {{ $json.evaluation.recommendation }}\n\nStrengths:\n{{ $json.evaluation.strengths.join('\\n- ') }}\n\nWe would like to invite you for an interview. Our team will reach out shortly to schedule a convenient time.\n\nPlease reply to confirm your continued interest.\n\nBest regards,\nHR Team",
"options": {},
"subject": "Interview Invitation - Automation Specialist Position",
"toEmail": "={{ $json.candidate.email }}",
"fromEmail": "user@example.com"
},
"credentials": {
"smtp": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "695c0973-9c31-47a2-88ec-24b7989089b4",
"name": "Email - Rejection Notice",
"type": "n8n-nodes-base.emailSend",
"notes": "\u2709\ufe0f REJECTION NOTICE\n\nSends professional rejection email:\n- Respectful and kind tone\n- Thanks candidate for interest\n- Encourages future applications\n- Maintains company reputation\n\nBest practice: Always send closure to candidates",
"position": [
336,
1648
],
"parameters": {
"text": "=Dear {{ $json.candidate.name }},\n\nThank you for your interest in the Automation Specialist position at our company.\n\nAfter careful review of your application, we have decided to move forward with other candidates whose experience more closely matches our current requirements.\n\nWe appreciate the time you invested in your application and encourage you to apply for future opportunities that align with your skills.\n\nWe wish you the best in your job search.\n\nBest regards,\nHR Team",
"options": {},
"subject": "Application Update - Automation Specialist Position",
"toEmail": "={{ $json.candidate.email }}",
"fromEmail": "user@example.com"
},
"credentials": {
"smtp": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "37081a08-cac7-403e-a6a1-f67b00efd078",
"name": "Google Calendar - Schedule Interview",
"type": "n8n-nodes-base.googleCalendar",
"notes": "\ud83d\udcc5 INTERVIEW SCHEDULING\n\nAutomatically creates calendar event:\n- Scheduled 3 days in advance\n- 1-hour duration\n- Includes candidate details\n- Adds evaluation summary\n- Invites candidate + hiring manager\n- Sends calendar invites\n\nAlternative: Use Calendly API integration",
"position": [
336,
1456
],
"parameters": {
"end": "={{ $now.plus(3, 'days').set({ hour: 11, minute: 0 }).toISO() }}",
"start": "={{ $now.plus(3, 'days').set({ hour: 10, minute: 0 }).toISO() }}",
"calendar": {
"__rl": true,
"mode": "id",
"value": "=9ikjnhy65trfdser4"
},
"additionalFields": {}
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "56ed8c49-514c-47e2-a83e-e453ce7894ea",
"name": "Sticky Note - Email Logic",
"type": "n8n-nodes-base.stickyNote",
"position": [
64,
1152
],
"parameters": {
"color": 5,
"width": 428,
"height": 656,
"content": "## \ud83d\udce7 Email Notifications\n\nTwo paths:\n\n1\ufe0f\u20e3 HIGH SCORE:\n- Interview invitation\n- Positive feedback\n- Schedule interview\n\n2\ufe0f\u20e3 LOW SCORE:\n- Professional rejection\n- Kind closure\n- Future encouragement"
},
"typeVersion": 1
},
{
"id": "56eeb778-14d9-41db-b9a6-279d8c4d9027",
"name": "Update Sheet - Interview Status",
"type": "n8n-nodes-base.googleSheets",
"notes": "\ud83d\udcdd STATUS UPDATE - INTERVIEW\n\nUpdates Google Sheet with:\n- Status: 'Interview Scheduled'\n- AI evaluation score\n- Recommendation level\n- Interview date\n\nThis keeps the ATS current for HR team tracking",
"position": [
560,
1456
],
"parameters": {
"columns": {
"value": {},
"schema": [],
"mappingMode": "autoMapInputData",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": "Applications",
"documentId": {
"__rl": true,
"mode": "id",
"value": "=koi8uhbvfgtyuj"
},
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"name": "<your credential>"
}
},
"typeVersion": 4
},
{
"id": "7e36df56-3674-4f34-af49-e3809b946f4b",
"name": "Update Sheet - Rejection Status",
"type": "n8n-nodes-base.googleSheets",
"notes": "\ud83d\udcdd STATUS UPDATE - REJECTION\n\nUpdates Google Sheet with:\n- Status: 'Rejected'\n- AI evaluation score\n- Recommendation (for records)\n- Rejection date\n\nMaintains complete audit trail",
"position": [
560,
1648
],
"parameters": {
"columns": {
"value": {},
"schema": [],
"mappingMode": "autoMapInputData",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "id",
"value": "=Applications"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "=hgt567ikmnhjuio9"
},
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"name": "<your credential>"
}
},
"typeVersion": 4
},
{
"id": "140accea-6390-4317-ae76-cfad1da6b1ee",
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"notes": "\ud83d\udce4 WEBHOOK RESPONSE\n\nSends confirmation back to application form:\n- Success status\n- Confirmation message\n- Processing status\n\nThis closes the webhook connection and confirms receipt to the applicant",
"position": [
784,
1552
],
"parameters": {
"options": {},
"respondWith": "json",
"responseBody": "={{ {\"success\": true, \"message\": \"Application received and processed\", \"candidateName\": $json.candidate.name, \"status\": $json.decision} }}"
},
"typeVersion": 1
},
{
"id": "2611d5c3-fedf-4a2b-ac0b-21a42ad532eb",
"name": "Sticky Note - Completion",
"type": "n8n-nodes-base.stickyNote",
"position": [
528,
1088
],
"parameters": {
"color": 5,
"width": 396,
"height": 728,
"content": "## \ud83c\udf89 Workflow Complete!\n\nFinal steps:\n1. Status updated in database\n2. Emails sent to candidate\n3. Calendar scheduled (if interview)\n4. Response sent to form\n\n**Metrics to Track:**\n- Applications received\n- Average AI score\n- Interview rate\n- Time to process"
},
"typeVersion": 1
},
{
"id": "80c5dc1a-90c0-4323-8fa9-a92811241fba",
"name": "Sticky Note - Setup Instructions",
"type": "n8n-nodes-base.stickyNote",
"position": [
-400,
672
],
"parameters": {
"color": 4,
"width": 398,
"height": 412,
"content": "## \ud83d\udd27 Configuration Required\n\n**Environment Variables:**\n- GOOGLE_SHEET_ID: Your Google Sheet ID\n\n**Credentials Needed:**\n1. Google Sheets OAuth2\n2. OpenAI API Key\n3. SMTP Email Account\n4. Google Calendar OAuth2\n\n**Customize:**\n- Job requirements in AI prompt\n- Score threshold (currently 70)\n- Email templates\n- Interview scheduling time"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "1f088f30-607a-4797-9576-0dd517138820",
"connections": {
"Email - Rejection Notice": {
"main": [
[
{
"node": "Update Sheet - Rejection Status",
"type": "main",
"index": 0
}
]
]
},
"Code - Process Evaluation": {
"main": [
[
{
"node": "IF - Check Score Threshold",
"type": "main",
"index": 0
}
]
]
},
"IF - Check Score Threshold": {
"main": [
[
{
"node": "Email - Interview Invitation",
"type": "main",
"index": 0
}
],
[
{
"node": "Email - Rejection Notice",
"type": "main",
"index": 0
}
]
]
},
"Email - Interview Invitation": {
"main": [
[
{
"node": "Google Calendar - Schedule Interview",
"type": "main",
"index": 0
}
]
]
},
"Webhook - Receive Application": {
"main": [
[
{
"node": "Google Sheets - Store Application",
"type": "main",
"index": 0
}
]
]
},
"Update Sheet - Interview Status": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
},
"Update Sheet - Rejection Status": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
},
"OpenAI - AI Candidate Evaluation": {
"main": [
[
{
"node": "Code - Process Evaluation",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets - Store Application": {
"main": [
[
{
"node": "OpenAI - AI Candidate Evaluation",
"type": "main",
"index": 0
}
]
]
},
"Google Calendar - Schedule Interview": {
"main": [
[
{
"node": "Update Sheet - Interview Status",
"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.
googleApigoogleCalendarOAuth2ApiopenAiApismtp
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Streamline your hiring process with intelligent AI-powered candidate screening and automated interview scheduling. This workflow receives applications via webhook, evaluates candidates using OpenAI's GPT model, scores them against job requirements, stores data in Google Sheets,…
Source: https://n8n.io/workflows/10080/ — 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.
Consulting firms in strategy, management, or IT who want to automate client onboarding and internal task assignment.
Watch on Youtube▶️
Imagine your recruitment process transformed into a sleek, efficient, AI-powered assembly line for talent. That's exactly what this system creates. It automates the heavy lifting, allowing your human
This workflow helps solar sales teams reactivate cold leads automatically using value-first SMS follow-ups, AI-powered sentiment detection, real-time alerts, and CRM tracking.
Automate your landscaping business’s lead follow-up and booking with this AI-powered GoHighLevel workflow. Designed by Hyrum Hurst, AI Automation Engineer at QuarterSmart, this template takes every ne