← All Productivity Workflows
BillionVerifyGoogle Calendar

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

  1. 1
    Check Every 5 MinutesTrigger· n8n

    Starts the workflow — on a schedule, a webhook, or manually while you test.

  2. 2
    Webhook: Submit Interview ResultSource· n8n

    Provides or transforms the contact data flowing through the workflow.

  3. 3
    Get Calendar EventsSource· n8n

    Provides or transforms the contact data flowing through the workflow.

  4. 4
    Update Sheet with ResultSource· n8n

    Provides or transforms the contact data flowing through the workflow.

  5. 5
    Filter Upcoming InterviewsLogic· n8n

    Routes items based on the workflow logic.

  6. 6
    Check if PassedLogic· n8n

    Branches on the verification result: only deliverable addresses continue to the send; the rest are skipped and flagged.

  7. 7
    Add to Google SheetSource· n8n

    Provides or transforms the contact data flowing through the workflow.

  8. 8
    Verify 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.

  9. 9
    Verify 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.

  10. 10
    Verify 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.

  11. 11
    IF deliverableLogic· n8n

    Branches on the verification result: only deliverable addresses continue to the send; the rest are skipped and flagged.

  12. 12
    IF deliverable 2Logic· n8n

    Branches on the verification result: only deliverable addresses continue to the send; the rest are skipped and flagged.

  13. 13
    IF deliverable 3Logic· n8n

    Branches on the verification result: only deliverable addresses continue to the send; the rest are skipped and flagged.

  14. 14
    Send Reminder to CandidateSend· n8n

    Sends only to verified, deliverable addresses. Swap in your own provider node if you send elsewhere.

  15. 15
    Email Candidate - PassedSend· n8n

    Sends only to verified, deliverable addresses. Swap in your own provider node if you send elsewhere.

  16. 16
    Email Candidate - FailedSend· n8n

    Sends only to verified, deliverable addresses. Swap in your own provider node if you send elsewhere.

  17. 17
    Verify 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.

  18. 18
    IF deliverable 4Logic· n8n

    Branches on the verification result: only deliverable addresses continue to the send; the rest are skipped and flagged.

  19. 19
    Email 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.

verify-emails-in-google-calendar.json
{
  "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