Google Analytics email verification with BillionVerify
Google Analytics provides deep insights into website traffic and user behaviour. By connecting BillionVerify to your Google Analytics workflows via n8n, Integrately, or the REST API, you can verify emails collected through tracked goals and conversion events before they enter your marketing stack.
Why verify before the send
Analytics platforms often feed email addresses collected from on-site forms directly into CRM systems and email campaigns. If those addresses are invalid, disposable, or catch-all, your conversion data looks healthy while your actual deliverability suffers. BillionVerify ensures only real addresses flow from your analytics-driven funnels into follow-up communications.
Ready-to-use n8n workflow
Import this workflow into n8n β it verifies every address with BillionVerify before Google Analytics sends, so only deliverable contacts are emailed. Install the BillionVerify community node first, then add your API key. Adapted from this n8n template
{
"name": "Marketing analytics reports with Google Analytics, Sheets, Slides & email alerts + BillionVerify",
"nodes": [
{
"id": "43a2a58a-a76f-4b86-bbfc-2274c8a9b2dc",
"name": "Weekly/Monthly Schedule",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-448,
192
],
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtDay": [
1
],
"triggerAtHour": 9
},
{
"field": "months",
"triggerAtHour": 9
}
]
}
},
"typeVersion": 1.2
},
{
"id": "3770762f-89b8-4575-9ccd-c2b636651eee",
"name": "Workflow Configuration",
"type": "n8n-nodes-base.set",
"position": [
-224,
192
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "gaPropertyId",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Google Analytics Property ID__>"
},
{
"id": "id-2",
"name": "adPlatformApiUrl",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Ad Platform API endpoint URL__>"
},
{
"id": "id-3",
"name": "crmApiUrl",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__CRM API endpoint URL__>"
},
{
"id": "id-4",
"name": "reportSpreadsheetId",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Google Sheets ID for report data__>"
},
{
"id": "id-5",
"name": "slidesTemplateId",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Google Slides template ID__>"
},
{
"id": "id-6",
"name": "reportRecipients",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Comma-separated email addresses__>"
},
{
"id": "id-7",
"name": "slackChannel",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Slack channel ID for error notifications__>"
},
{
"id": "id-8",
"name": "reportPeriodDays",
"type": "number",
"value": 7
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "7f1e4958-8b6e-4575-ac41-adb6581c3d9a",
"name": "Get Google Analytics Data",
"type": "n8n-nodes-base.googleAnalytics",
"position": [
0,
0
],
"parameters": {
"endDate": "={{ $now.minus({ days: 1 }).toFormat('yyyy-MM-dd') }}",
"dateRange": "custom",
"startDate": "={{ $now.minus({ days: $('Workflow Configuration').first().json.reportPeriodDays }).toFormat('yyyy-MM-dd') }}",
"metricsGA4": {
"metricValues": [
{
"listName": "active1DayUsers"
},
{
"listName": "sessions"
},
{
"listName": "screenPageViews"
},
{
"name": "conversions",
"listName": "other"
}
]
},
"propertyId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Workflow Configuration').first().json.gaPropertyId }}"
},
"dimensionsGA4": {
"dimensionValues": [
{}
]
},
"additionalFields": {}
},
"typeVersion": 2
},
{
"id": "9f9cc333-a289-406e-a632-49642d764f1a",
"name": "Get Ad Platform Data",
"type": "n8n-nodes-base.httpRequest",
"position": [
0,
192
],
"parameters": {
"url": "={{ $('Workflow Configuration').first().json.adPlatformApiUrl }}",
"options": {},
"sendQuery": true,
"authentication": "predefinedCredentialType",
"queryParameters": {
"parameters": [
{
"name": "start_date",
"value": "={{ $now.minus({ days: $('Workflow Configuration').first().json.reportPeriodDays }).toFormat('yyyy-MM-dd') }}"
},
{
"name": "end_date",
"value": "={{ $now.minus({ days: 1 }).toFormat('yyyy-MM-dd') }}"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "0ad1b7a4-e29f-4206-b5e3-a2a516560422",
"name": "Get CRM Data",
"type": "n8n-nodes-base.httpRequest",
"position": [
0,
384
],
"parameters": {
"url": "={{ $('Workflow Configuration').first().json.crmApiUrl }}",
"options": {},
"sendQuery": true,
"authentication": "predefinedCredentialType",
"queryParameters": {
"parameters": [
{
"name": "start_date",
"value": "={{ $now.minus({ days: $('Workflow Configuration').first().json.reportPeriodDays }).toFormat('yyyy-MM-dd') }}"
},
{
"name": "end_date",
"value": "={{ $now.minus({ days: 1 }).toFormat('yyyy-MM-dd') }}"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "bd9aae8e-6342-4efa-a349-2ad4e645b9f8",
"name": "Calculate KPIs (MAU, LTV, CAC)",
"type": "n8n-nodes-base.code",
"position": [
256,
192
],
"parameters": {
"jsCode": "const gaData = $input.first().json;\nconst adData = $input.all()[1]?.json || {};\nconst crmData = $input.all()[2]?.json || {};\nconst mau = gaData.activeUsers || 0;\nconst totalAdSpend = adData.totalSpend || 0;\nconst newCustomers = crmData.newCustomers || 1;\nconst cac = totalAdSpend / newCustomers;\nconst totalRevenue = crmData.totalRevenue || 0;\nconst totalCustomers = crmData.totalCustomers || 1;\nconst ltv = totalRevenue / totalCustomers;\nconst sessions = gaData.sessions || 0;\nconst conversions = gaData.conversions || 0;\nconst conversionRate = sessions > 0 ? (conversions / sessions * 100).toFixed(2) : 0;\nreturn [{\n json: {\n reportDate: new Date().toISOString(),\n periodStart: $now.minus({ days: $('Workflow Configuration').first().json.reportPeriodDays }).toFormat('yyyy-MM-dd'),\n periodEnd: $now.minus({ days: 1 }).toFormat('yyyy-MM-dd'),\n mau: mau,\n cac: parseFloat(cac.toFixed(2)),\n ltv: parseFloat(ltv.toFixed(2)),\n ltvCacRatio: parseFloat((ltv / cac).toFixed(2)),\n sessions: sessions,\n conversions: conversions,\n conversionRate: parseFloat(conversionRate),\n totalAdSpend: totalAdSpend,\n newCustomers: newCustomers,\n totalRevenue: totalRevenue\n }\n}];"
},
"typeVersion": 2
},
{
"id": "a88d2469-2882-4db4-86e1-018abaaf0f32",
"name": "Write Data to Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
496,
192
],
"parameters": {
"columns": {
"value": {},
"schema": [],
"mappingMode": "autoMapInputData",
"matchingColumns": [
"reportDate"
]
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "KPI Data"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Workflow Configuration').first().json.reportSpreadsheetId }}"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "credential-id",
"name": "googleSheetsOAuth2Api Credential"
}
},
"typeVersion": 4.7
},
{
"id": "3fa10a78-3c7f-46e4-a693-10c9fd6fb376",
"name": "Create Google Slides Report",
"type": "n8n-nodes-base.googleSlides",
"position": [
736,
192
],
"parameters": {
"title": "={{ 'Analytics Report - ' + $now.toFormat('yyyy-MM-dd') }}"
},
"typeVersion": 2
},
{
"id": "c976799f-8feb-4b1f-ad17-ce11f9393a5a",
"name": "Check for Errors",
"type": "n8n-nodes-base.if",
"position": [
960,
192
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "id-1",
"operator": {
"type": "string",
"operation": "notExists"
},
"leftValue": "={{ $json.error }}"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "1c52b591-2f9e-43e6-a07d-e4be6578d9c2",
"name": "Send Report Email",
"type": "n8n-nodes-base.gmail",
"position": [
1216,
64
],
"webhookId": "6ca702a2-e5bd-4ef3-94f8-b50afa6cf12b",
"parameters": {
"sendTo": "={{ $('Workflow Configuration').first().json.reportRecipients }}",
"message": "=<h2>Analytics Report</h2>\n<p><strong>Period:</strong> {{ $json.periodStart }} to {{ $json.periodEnd }}</p>\n\n<h3>Key Performance Indicators</h3>\n<ul>\n <li><strong>MAU (Monthly Active Users):</strong> {{ $json.mau }}</li>\n <li><strong>CAC (Customer Acquisition Cost):</strong> ${{ $json.cac }}</li>\n <li><strong>LTV (Lifetime Value):</strong> ${{ $json.ltv }}</li>\n <li><strong>LTV:CAC Ratio:</strong> {{ $json.ltvCacRatio }}</li>\n <li><strong>Conversion Rate:</strong> {{ $json.conversionRate }}%</li>\n</ul>\n\n<h3>Additional Metrics</h3>\n<ul>\n <li><strong>Sessions:</strong> {{ $json.sessions }}</li>\n <li><strong>Conversions:</strong> {{ $json.conversions }}</li>\n <li><strong>New Customers:</strong> {{ $json.newCustomers }}</li>\n <li><strong>Total Ad Spend:</strong> ${{ $json.totalAdSpend }}</li>\n <li><strong>Total Revenue:</strong> ${{ $json.totalRevenue }}</li>\n</ul>\n\n<p>View the full report in <a href=\"https://docs.google.com/presentation/d/{{ $('Create Google Slides Report').first().json.presentationId }}\">Google Slides</a></p>",
"options": {
"attachmentsUi": {
"attachmentsBinary": [
{}
]
}
},
"subject": "={{ 'Weekly/Monthly Analytics Report - ' + $now.toFormat('yyyy-MM-dd') }}"
},
"credentials": {
"gmailOAuth2": {
"id": "credential-id",
"name": "gmailOAuth2 Credential"
}
},
"typeVersion": 2.1
},
{
"id": "05820f46-c77c-43a6-b5a6-02829ba141ed",
"name": "Send Error Notification",
"type": "n8n-nodes-base.slack",
"position": [
1200,
432
],
"webhookId": "46ac626d-f7a4-47fd-9f7c-5a72530a897b",
"parameters": {
"text": "={{ 'π¨ Analytics Report Generation Failed\\n\\n*Error:* ' + ($json.error || 'Unknown error occurred') + '\\n*Time:* ' + $now.toISO() }}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Workflow Configuration').first().json.slackChannel }}"
},
"otherOptions": {},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"id": "credential-id",
"name": "slackOAuth2Api Credential"
}
},
"typeVersion": 2.3
},
{
"id": "03a6ec52-853c-4d50-a644-750e1c5e25b7",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1296,
-288
],
"parameters": {
"width": 768,
"height": 1056,
"content": "## Automate and Distribute Weekly and Monthly Marketing Analytics Reports\n\n### Who's it for?\nThis workflow is designed for marketing teams, data analysts, and business owners who need to consistently track key performance indicators (KPIs). It saves hours of manual data collection and reporting, ensuring stakeholders receive timely updates automatically.\n\n### What it does\nThis workflow automates the entire process of creating and distributing regular analytics reports. On a recurring weekly and monthly schedule, it:\n1. **Fetches Data:** Gathers the latest data from Google Analytics (users, sessions, conversions), your advertising platform (ad spend), and your CRM (new customers, revenue).\n2. **Calculates KPIs:** Processes the raw data to calculate essential business metrics, including Monthly Active Users (MAU), Customer Acquisition Cost (CAC), Lifetime Value (LTV), LTV:CAC ratio, and conversion rates.\n3. **Logs Historical Data:** Appends the newly calculated KPIs to a Google Sheet, creating a historical record for trend analysis.\n4. **Generates a Report:** Creates a new Google Slides presentation to serve as the main report.\n5. **Distributes the Report:** Emails a summary of the key metrics to a predefined list of recipients, including a link to the full Google Slides report.\n6. **Provides Error Alerts:** If any step in the process fails, it sends an immediate notification to a designated Slack channel so you can address the issue quickly.\n\n### How to set up\n1. **Configure Credentials:** Add your credentials for Google Analytics, Google Sheets, Google Slides, Gmail, Slack, and the HTTP Request nodes (for your ad platform and CRM).\n2. **Fill in Placeholders:** In the \"Workflow Configuration\" node, replace all placeholder values with your specific information:\n * `gaPropertyId`: Your Google Analytics Property ID.\n * `adPlatformApiUrl`: The API endpoint for your advertising platform.\n * `crmApiUrl`: The API endpoint for your CRM.\n * `reportSpreadsheetId`: The ID of the Google Sheet where data will be stored.\n * `slidesTemplateId`: The ID of your Google Slides report template.\n * `reportRecipients`: A comma-separated list of email addresses for report distribution.\n * `slackChannel`: The Slack channel ID for error notifications.\n3. **Activate Workflow:** Turn the workflow on. It will now run based on the schedule defined in the \"Weekly/Monthly Schedule\" trigger node.\n\n### How to customize the workflow\n* **Adjust Schedule:** Modify the \"Weekly/Monthly Schedule\" node to change the reporting frequency (e.g., daily, bi-weekly).\n* **Change Reporting Period:** In the \"Workflow Configuration\" node, change the `reportPeriodDays` value to adjust the lookback window (e.g., set to `30` for a monthly report).\n* **Customize KPIs:** Edit the Javascript in the \"Calculate KPIs (MAU, LTV, CAC)\" node to add or modify metrics.\n* **Enhance the Report:** Expand the \"Create Google Slides Report\" node to dynamically add charts and data from the calculated KPIs into the slides."
},
"typeVersion": 1
},
{
"id": "464e2f71-bf7f-4b0c-a372-658644e63da3",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1136,
288
],
"parameters": {
"color": 6,
"height": 304,
"content": " **Provides Error Alerts:** If any step in the process fails, it sends an immediate notification to a designated Slack channel so you can address the issue quickly."
},
"typeVersion": 1
},
{
"id": "9c4b764d-0985-414a-9b9d-c2fc5f9291b4",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1152,
-64
],
"parameters": {
"color": 5,
"height": 288,
"content": " **Distributes the Report:** Emails a summary of the key metrics to a predefined list of recipients, including a link to the full Google Slides report."
},
"typeVersion": 1
},
{
"id": "f003852c-edb9-4446-98d6-264b3ca254ce",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
672,
16
],
"parameters": {
"color": 4,
"height": 352,
"content": " **Generates a Report:** Creates a new Google Slides presentation to serve as the main report."
},
"typeVersion": 1
},
{
"id": "8fe51cfa-4897-4d79-bc78-f03afc5c6011",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-64,
-160
],
"parameters": {
"color": 3,
"height": 688,
"content": " **Fetches Data:** Gathers the latest data from Google Analytics (users, sessions, conversions), your advertising platform (ad spend), and your CRM (new customers, revenue)."
},
"typeVersion": 1
},
{
"id": "5b686967-717b-40f9-80fb-e8c7935245d2",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
192,
16
],
"parameters": {
"color": 7,
"height": 352,
"content": " **Calculates KPIs:** Processes the raw data to calculate essential business metrics, including Monthly Active Users (MAU), Customer Acquisition Cost (CAC), Lifetime Value (LTV), LTV:CAC ratio, and conversion rates."
},
"typeVersion": 1
},
{
"id": "646db3f3-eda5-4b58-94fb-611e5426ae0f",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
432,
16
],
"parameters": {
"color": 6,
"height": 352,
"content": " **Logs Historical Data:** Appends the newly calculated KPIs to a Google Sheet, creating a historical record for trend analysis."
},
"typeVersion": 1
},
{
"parameters": {
"operation": "verify",
"email": "={{ $('Workflow Configuration').first().json.reportRecipients }}",
"additionalOptions": {}
},
"type": "n8n-nodes-billionverify.billionVerify",
"typeVersion": 1,
"position": [
856,
64
],
"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": [
1036,
64
],
"name": "IF deliverable"
}
],
"connections": {
"Get CRM Data": {
"main": [
[
{
"node": "Calculate KPIs (MAU, LTV, CAC)",
"type": "main",
"index": 0
}
]
]
},
"Check for Errors": {
"main": [
[
{
"node": "Verify Email (BillionVerify)",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Error Notification",
"type": "main",
"index": 0
}
]
]
},
"Get Ad Platform Data": {
"main": [
[
{
"node": "Calculate KPIs (MAU, LTV, CAC)",
"type": "main",
"index": 0
}
]
]
},
"Workflow Configuration": {
"main": [
[
{
"node": "Get Google Analytics Data",
"type": "main",
"index": 0
},
{
"node": "Get Ad Platform Data",
"type": "main",
"index": 0
},
{
"node": "Get CRM Data",
"type": "main",
"index": 0
}
]
]
},
"Weekly/Monthly Schedule": {
"main": [
[
{
"node": "Workflow Configuration",
"type": "main",
"index": 0
}
]
]
},
"Get Google Analytics Data": {
"main": [
[
{
"node": "Calculate KPIs (MAU, LTV, CAC)",
"type": "main",
"index": 0
}
]
]
},
"Create Google Slides Report": {
"main": [
[
{
"node": "Check for Errors",
"type": "main",
"index": 0
}
]
]
},
"Write Data to Google Sheets": {
"main": [
[
{
"node": "Create Google Slides Report",
"type": "main",
"index": 0
}
]
]
},
"Calculate KPIs (MAU, LTV, CAC)": {
"main": [
[
{
"node": "Write Data to Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Verify Email (BillionVerify)": {
"main": [
[
{
"node": "IF deliverable",
"type": "main",
"index": 0
}
]
]
},
"IF deliverable": {
"main": [
[
{
"node": "Send Report Email",
"type": "main",
"index": 0
}
],
[]
]
}
},
"settings": {
"executionOrder": "v1"
}
}Workflow templates with Google Analytics
Ready-to-use workflows that verify emails before Google Analytics sends.
How it works
- 1
Connect BillionVerify to your Google Analytics-driven workflows using n8n, Integrately, or the BillionVerify REST API.
- 2
Trigger a verification call when an email is captured through an analytics-tracked event, such as a newsletter sign-up or contact form submission.
- 3
BillionVerify evaluates the address across multiple checks including domain validity, MX records, catch-all detection, and disposable provider matching.
- 4
Route verified addresses to your CRM or email platform, and flag or discard addresses that fail verification.
- 5
Use verification pass/fail rates as an additional signal alongside your Analytics conversion data to assess form and audience quality.
When to use this
Verify emails from tracked conversion goals
When a Google Analytics goal fires on form submission, use BillionVerify to validate the captured email before it reaches your CRM or email list, preventing invalid addresses from inflating conversion counts and polluting contact data.
Protect retargeting and newsletter lists
Audience segments built from analytics data often include emails from multiple touch points. Running them through BillionVerify before exporting to an email tool removes disposable and non-existent addresses that would generate hard bounces.
FAQ
How does BillionVerify connect to Google Analytics?
BillionVerify integrates via n8n or Integrately automations that trigger on form events tracked by Analytics, or through direct API calls from your data pipeline wherever emails are captured.
Will verifying emails affect my Analytics conversion tracking?
No. Verification happens after the conversion event is recorded in Analytics. It only affects what enters your CRM or email list, not the Analytics data itself.
What is a catch-all address and why does it matter?
A catch-all domain accepts any email sent to it, making it impossible to confirm a specific mailbox exists. BillionVerify flags these so you can decide whether to include or exclude them from your campaigns.
Verify emails in Google Analytics
Create a free account, grab your API key, and stop bounces before they happen.
Get started free