Automated Interview Tracker with Google Calendar, Sheets & Gmail Alerts
Pull contacts, verify each address with BillionVerify, and continue to Google Calendar — only deliverable addresses get through.
Why verify before the send
Sending to invalid, risky, catch-all, or disposable addresses spikes your bounce rate and erodes sender reputation. A verification gate before the Google Calendar step removes that risk automatically — only deliverable addresses continue, the rest are flagged.
The workflow
BillionVerify — verification sits right before the send.
Node by node
- 1Check Every 5 MinutesTrigger· n8n
Starts the workflow — on a schedule, a webhook, or manually while you test.
- 2Webhook: Submit Interview ResultSource· n8n
Provides or transforms the contact data flowing through the workflow.
- 3Get Calendar EventsSource· n8n
Provides or transforms the contact data flowing through the workflow.
- 4Update Sheet with ResultSource· n8n
Provides or transforms the contact data flowing through the workflow.
- 5Filter Upcoming InterviewsLogic· n8n
Routes items based on the workflow logic.
- 6Check if PassedLogic· n8n
Branches on the verification result: only deliverable addresses continue to the send; the rest are skipped and flagged.
- 7Add to Google SheetSource· n8n
Provides or transforms the contact data flowing through the workflow.
- 8Verify Email (BillionVerify)Verify· billionverify
The BillionVerify node verifies the address — status (valid / invalid / risky / catch-all / role / disposable), is_deliverable, and a confidence score — before anything is sent.
- 9Verify Email (BillionVerify) 2Verify· billionverify
The BillionVerify node verifies the address — status (valid / invalid / risky / catch-all / role / disposable), is_deliverable, and a confidence score — before anything is sent.
- 10Verify Email (BillionVerify) 3Verify· billionverify
The BillionVerify node verifies the address — status (valid / invalid / risky / catch-all / role / disposable), is_deliverable, and a confidence score — before anything is sent.
- 11IF deliverableLogic· n8n
Branches on the verification result: only deliverable addresses continue to the send; the rest are skipped and flagged.
- 12IF deliverable 2Logic· n8n
Branches on the verification result: only deliverable addresses continue to the send; the rest are skipped and flagged.
- 13IF deliverable 3Logic· n8n
Branches on the verification result: only deliverable addresses continue to the send; the rest are skipped and flagged.
- 14Send Reminder to CandidateSend· n8n
Sends only to verified, deliverable addresses. Swap in your own provider node if you send elsewhere.
- 15Email Candidate - PassedSend· n8n
Sends only to verified, deliverable addresses. Swap in your own provider node if you send elsewhere.
- 16Email Candidate - FailedSend· n8n
Sends only to verified, deliverable addresses. Swap in your own provider node if you send elsewhere.
- 17Verify Email (BillionVerify) 4Verify· billionverify
The BillionVerify node verifies the address — status (valid / invalid / risky / catch-all / role / disposable), is_deliverable, and a confidence score — before anything is sent.
- 18IF deliverable 4Logic· n8n
Branches on the verification result: only deliverable addresses continue to the send; the rest are skipped and flagged.
- 19Email ManagerSend· n8n
Sends only to verified, deliverable addresses. Swap in your own provider node if you send elsewhere.
Workflow JSON
Copy or download this workflow, then import it in n8n (Workflows → Import from File / Paste). Install the BillionVerify community node first, then add your API key credential.
{
"name": "Automated Interview Tracker with Google Calendar, Sheets & Gmail Alerts + BillionVerify",
"nodes": [
{
"id": "40220665-8466-4ca5-a665-59b1b7fb4dcd",
"name": "Check Every 5 Minutes",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
144,
-64
],
"parameters": {
"rule": {
"interval": [
{
"field": "minutes"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "cec5691c-d2e4-4da0-a72f-a5eacc87e4d1",
"name": "Get Calendar Events",
"type": "n8n-nodes-base.googleCalendar",
"position": [
368,
-64
],
"parameters": {
"options": {
"timeMax": "={{ $now.plus({ hours: 1 }).toISO() }}",
"timeMin": "={{ $now.toISO() }}"
},
"calendar": {
"__rl": true,
"mode": "id",
"value": "=76iujhgtr4321eryi8"
},
"operation": "getAll"
},
"credentials": {
"googleCalendarOAuth2Api": {
"id": "credential-id",
"name": "googleCalendarOAuth2Api Credential"
}
},
"typeVersion": 1.2
},
{
"id": "e600def1-33a8-433b-978a-5bd334d4e861",
"name": "Filter Upcoming Interviews",
"type": "n8n-nodes-base.filter",
"position": [
592,
-64
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "condition1",
"operator": {
"type": "dateTime",
"operation": "before",
"singleValue": true
},
"leftValue": "={{ $json.start.dateTime }}",
"rightValue": "={{ $now.plus({ minutes: 5 }).toISO() }}"
},
{
"id": "condition2",
"operator": {
"type": "dateTime",
"operation": "after",
"singleValue": true
},
"leftValue": "={{ $json.start.dateTime }}",
"rightValue": "={{ $now.toISO() }}"
}
]
}
},
"typeVersion": 2
},
{
"id": "871ea2fb-6f24-4291-888c-94c1a47a6518",
"name": "Add to Google Sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
816,
-160
],
"parameters": {
"columns": {
"value": {},
"schema": [],
"mappingMode": "autoMapInputData",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "YOUR_SPREADSHEET_ID"
},
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"id": "credential-id",
"name": "googleApi Credential"
}
},
"typeVersion": 4.5
},
{
"id": "97b38c41-ea45-4e4b-8318-5da4d3c24135",
"name": "Send Reminder to Candidate",
"type": "n8n-nodes-base.gmail",
"position": [
816,
32
],
"webhookId": "4aa88c2f-aa96-4773-a71b-6dd89843b55a",
"parameters": {
"sendTo": "={{ $json.attendees[0].email }}",
"message": "=<h2>Interview Reminder</h2>\n<p>Dear Candidate,</p>\n<p>Your interview is scheduled to start in <strong>5 minutes</strong>.</p>\n<p><strong>Interview:</strong> {{ $json.summary }}<br>\n<strong>Time:</strong> {{ $json.start.dateTime }}<br>\n<strong>Google Meet Link:</strong> <a href=\"{{ $json.hangoutLink }}\">Join Meeting</a></p>\n<p>Please join on time. Good luck!</p>",
"options": {},
"subject": "Interview Reminder - Starting in 5 Minutes"
},
"credentials": {
"gmailOAuth2": {
"id": "credential-id",
"name": "gmailOAuth2 Credential"
}
},
"typeVersion": 2.1
},
{
"id": "53f7164c-9007-4261-8628-24b1bcdac2c7",
"name": "Update Sheet with Result",
"type": "n8n-nodes-base.googleSheets",
"position": [
368,
352
],
"parameters": {
"columns": {
"value": {},
"schema": [],
"mappingMode": "autoMapInputData",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "YOUR_SPREADSHEET_ID"
},
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"id": "credential-id",
"name": "googleApi Credential"
}
},
"typeVersion": 4.5
},
{
"id": "6780349a-d56e-465c-8dc4-4a23a2523dbf",
"name": "Webhook: Submit Interview Result",
"type": "n8n-nodes-base.webhook",
"position": [
144,
352
],
"webhookId": "interview-result-webhook",
"parameters": {
"path": "interview-result",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2
},
{
"id": "4269bbb9-8d74-4d20-8053-260836d36478",
"name": "Check if Passed",
"type": "n8n-nodes-base.if",
"position": [
592,
352
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "passed-condition",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.result }}",
"rightValue": "Pass"
}
]
}
},
"typeVersion": 2
},
{
"id": "e9572ff4-464a-4956-a14e-2c0b1917a3c3",
"name": "Email Candidate - Passed",
"type": "n8n-nodes-base.gmail",
"position": [
816,
256
],
"webhookId": "7b073d4f-6bb9-4b31-aa60-8f9e0cebb3e5",
"parameters": {
"sendTo": "={{ $json.candidateEmail }}",
"message": "=<h2>Congratulations!</h2>\n<p>Dear Candidate,</p>\n<p>We are pleased to inform you that you have <strong>PASSED</strong> the interview.</p>\n<p><strong>Feedback:</strong> {{ $json.feedback }}</p>\n<p>Our team will contact you soon with next steps.</p>\n<p>Best regards,<br>HR Team</p>",
"options": {},
"subject": "🎉 Congratulations! You Passed the Interview"
},
"credentials": {
"gmailOAuth2": {
"id": "credential-id",
"name": "gmailOAuth2 Credential"
}
},
"typeVersion": 2.1
},
{
"id": "11a09ef5-e424-45db-9923-700ca794fc47",
"name": "Email Candidate - Failed",
"type": "n8n-nodes-base.gmail",
"position": [
816,
448
],
"webhookId": "0ea6d946-1e54-47c6-ae97-7cbeb6c0a919",
"parameters": {
"sendTo": "={{ $json.candidateEmail }}",
"message": "=<h2>Interview Result</h2>\n<p>Dear Candidate,</p>\n<p>Thank you for taking the time to interview with us.</p>\n<p>After careful consideration, we have decided not to move forward with your application at this time.</p>\n<p><strong>Feedback:</strong> {{ $json.feedback }}</p>\n<p>We wish you all the best in your future endeavors.</p>\n<p>Best regards,<br>HR Team</p>",
"options": {},
"subject": "Interview Result"
},
"credentials": {
"gmailOAuth2": {
"id": "credential-id",
"name": "gmailOAuth2 Credential"
}
},
"typeVersion": 2.1
},
{
"id": "1d62aabc-dc5b-40d8-9be5-d18eff86a10e",
"name": "Email Manager",
"type": "n8n-nodes-base.gmail",
"position": [
1040,
352
],
"webhookId": "13efb4cd-fe47-4727-a220-2825ea71ee75",
"parameters": {
"sendTo": "user@example.com",
"message": "=<h2>Interview Completed</h2>\n<p><strong>Candidate:</strong> {{ $json.candidateEmail }}<br>\n<strong>Result:</strong> {{ $json.result }}<br>\n<strong>Feedback:</strong> {{ $json.feedback }}</p>\n<p>Updated in Google Sheet.</p>",
"options": {},
"subject": "Interview Result: {{ $json.candidateEmail }}"
},
"credentials": {
"gmailOAuth2": {
"id": "credential-id",
"name": "gmailOAuth2 Credential"
}
},
"typeVersion": 2.1
},
{
"id": "0c077145-df34-4e7d-8bf1-31244f07fca9",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-96,
-336
],
"parameters": {
"color": 3,
"width": 672,
"height": 208,
"content": "## Workflow Overview\n\n- **Check Every 5 Minutes**: Triggers the workflow to run every 5 minutes.\n- **Get Calendar Events**: Retrieves upcoming interview events from Google Calendar.\n- **Filter Upcoming Interviews**: Filters the retrieved events to focus on upcoming interviews.\n- **Add to Google Sheet**: Appends filtered interview details to a Google Sheet.\n- **Send Reminder to Candidate**: Sends an email reminder to the candidate via Gmail.\n"
},
"typeVersion": 1
},
{
"id": "e553920b-784e-4841-b3ec-2fb43307a6a0",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-96,
96
],
"parameters": {
"width": 688,
"height": 224,
"content": "## Workflow Overview\n\n- **Webhook: Submit Interview Result**: Receives interview result data via a webhook.\n- **Update Sheet with Result**: Updates the Google Sheet with the submitted interview result.\n- **Check if Passed**: Evaluates whether the interview result indicates a pass or fail.\n- **Email Candidate - Passed**: Sends a pass notification email to the candidate via Gmail.\n- **Email Manager**: Sends an email update to the manager via Gmail.\n- **Email Candidate - Failed**: Sends a fail notification email to the candidate via Gmail."
},
"typeVersion": 1
},
{
"parameters": {
"operation": "verify",
"email": "={{ $json.attendees[0].email }}",
"additionalOptions": {}
},
"type": "n8n-nodes-billionverify.billionVerify",
"typeVersion": 1,
"position": [
456,
32
],
"name": "Verify Email (BillionVerify)",
"credentials": {
"billionVerifyApi": {
"id": "",
"name": "BillionVerify account"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "is-deliverable",
"leftValue": "={{ $json.is_deliverable }}",
"rightValue": "",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
]
}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
636,
32
],
"name": "IF deliverable"
},
{
"parameters": {
"operation": "verify",
"email": "={{ $json.candidateEmail }}",
"additionalOptions": {}
},
"type": "n8n-nodes-billionverify.billionVerify",
"typeVersion": 1,
"position": [
456,
256
],
"name": "Verify Email (BillionVerify) 2",
"credentials": {
"billionVerifyApi": {
"id": "",
"name": "BillionVerify account"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "is-deliverable",
"leftValue": "={{ $json.is_deliverable }}",
"rightValue": "",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
]
}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
636,
256
],
"name": "IF deliverable 2"
},
{
"parameters": {
"operation": "verify",
"email": "={{ $json.candidateEmail }}",
"additionalOptions": {}
},
"type": "n8n-nodes-billionverify.billionVerify",
"typeVersion": 1,
"position": [
456,
448
],
"name": "Verify Email (BillionVerify) 3",
"credentials": {
"billionVerifyApi": {
"id": "",
"name": "BillionVerify account"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "is-deliverable",
"leftValue": "={{ $json.is_deliverable }}",
"rightValue": "",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
]
}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
636,
448
],
"name": "IF deliverable 3"
},
{
"parameters": {
"operation": "verify",
"email": "={{ $json.email || $json.Email }}",
"additionalOptions": {}
},
"type": "n8n-nodes-billionverify.billionVerify",
"typeVersion": 1,
"position": [
680,
352
],
"name": "Verify Email (BillionVerify) 4",
"credentials": {
"billionVerifyApi": {
"id": "",
"name": "BillionVerify account"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "is-deliverable",
"leftValue": "={{ $json.is_deliverable }}",
"rightValue": "",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
]
}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
860,
352
],
"name": "IF deliverable 4"
}
],
"connections": {
"Check if Passed": {
"main": [
[
{
"node": "Verify Email (BillionVerify) 2",
"type": "main",
"index": 0
}
],
[
{
"node": "Verify Email (BillionVerify) 3",
"type": "main",
"index": 0
}
]
]
},
"Get Calendar Events": {
"main": [
[
{
"node": "Filter Upcoming Interviews",
"type": "main",
"index": 0
}
]
]
},
"Check Every 5 Minutes": {
"main": [
[
{
"node": "Get Calendar Events",
"type": "main",
"index": 0
}
]
]
},
"Email Candidate - Failed": {
"main": [
[
{
"node": "Verify Email (BillionVerify) 4",
"type": "main",
"index": 0
}
]
]
},
"Email Candidate - Passed": {
"main": [
[
{
"node": "Verify Email (BillionVerify) 4",
"type": "main",
"index": 0
}
]
]
},
"Update Sheet with Result": {
"main": [
[
{
"node": "Check if Passed",
"type": "main",
"index": 0
}
]
]
},
"Filter Upcoming Interviews": {
"main": [
[
{
"node": "Add to Google Sheet",
"type": "main",
"index": 0
},
{
"node": "Verify Email (BillionVerify)",
"type": "main",
"index": 0
}
]
]
},
"Webhook: Submit Interview Result": {
"main": [
[
{
"node": "Update Sheet with Result",
"type": "main",
"index": 0
}
]
]
},
"Verify Email (BillionVerify)": {
"main": [
[
{
"node": "IF deliverable",
"type": "main",
"index": 0
}
]
]
},
"IF deliverable": {
"main": [
[
{
"node": "Send Reminder to Candidate",
"type": "main",
"index": 0
}
],
[]
]
},
"Verify Email (BillionVerify) 2": {
"main": [
[
{
"node": "IF deliverable 2",
"type": "main",
"index": 0
}
]
]
},
"IF deliverable 2": {
"main": [
[
{
"node": "Email Candidate - Passed",
"type": "main",
"index": 0
}
],
[]
]
},
"Verify Email (BillionVerify) 3": {
"main": [
[
{
"node": "IF deliverable 3",
"type": "main",
"index": 0
}
]
]
},
"IF deliverable 3": {
"main": [
[
{
"node": "Email Candidate - Failed",
"type": "main",
"index": 0
}
],
[]
]
},
"Verify Email (BillionVerify) 4": {
"main": [
[
{
"node": "IF deliverable 4",
"type": "main",
"index": 0
}
]
]
},
"IF deliverable 4": {
"main": [
[
{
"node": "Email Manager",
"type": "main",
"index": 0
}
],
[]
]
}
},
"settings": {
"executionOrder": "v1"
}
}When to use this
- Cleaning a list before a Google Calendar send or sync.
- Protecting Google Calendar deliverability and sender reputation.
- Keeping bounce rates low so your sending is never throttled.
FAQ
Why verify before sending in Google Calendar?
Verifying first keeps your bounce rate low, which protects your sender reputation and your results.
How do I import this workflow?
Download the JSON, then in n8n go to Workflows → Import from File (or paste it). Install the BillionVerify community node and add your API key credential.
What happens to risky or catch-all addresses?
They are routed to the false branch and excluded from the send. You decide whether to retry, review, or drop them.
Add verification to your workflow
Create a free account, grab your API key, and stop bounces before they happen.
Get started free