PDF Generator API email verification with BillionVerify
PDF Generator API is a developer tool for generating polished PDF documents from templates and data sources. When those documents include contact lists, invoices, or mailing outputs, pairing it with BillionVerify ensures every email address embedded or exported is valid before it ever reaches a recipient's inbox.
Why verify before the send
Documents generated at scale often pull email data from CRMs, spreadsheets, or form submissions — sources that accumulate invalid, disposable, or role-based addresses over time. Running BillionVerify before generation or dispatch protects sender reputation, cuts bounce rates, and prevents wasted document-generation cycles on unreachable contacts.
Ready-to-use n8n workflow
Import this workflow into n8n — it verifies every address with BillionVerify before PDF Generator API sends, so only deliverable contacts are emailed. Install the BillionVerify community node first, then add your API key. Adapted from this n8n template
{
"name": "Generate, encrypt, and send invoices with PDF Generator API & Google Suite + BillionVerify",
"nodes": [
{
"id": "e30f9a26-b270-41ea-b732-95df22a8b3ed",
"name": "Generate Invoice ID",
"type": "n8n-nodes-base.code",
"position": [
480,
208
],
"parameters": {
"jsCode": "function generateOrderNumber(length = 8) {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n let result = 'INVOICE-';\n for (let i = 0; i < length; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return result;\n}\n\nreturn [\n {\n json: {\n order_number: generateOrderNumber()\n }\n }\n];\n"
},
"typeVersion": 2
},
{
"id": "5fb09b61-d55e-4b78-bdd8-cfc997737434",
"name": "Check if ID Already Exists",
"type": "n8n-nodes-base.googleSheets",
"position": [
688,
208
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1915774434,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1WO-vIxG5lSWWF7_BwDDjLSfEbwNkFtIcMSgFRKAoUCU/edit#gid=1915774434",
"cachedResultName": "Sheet2"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1WO-vIxG5lSWWF7_BwDDjLSfEbwNkFtIcMSgFRKAoUCU",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1WO-vIxG5lSWWF7_BwDDjLSfEbwNkFtIcMSgFRKAoUCU/edit?usp=drivesdk",
"cachedResultName": "n8n pokus x"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "credential-id",
"name": "googleSheetsOAuth2Api Credential"
}
},
"typeVersion": 4.5,
"alwaysOutputData": true
},
{
"id": "7a7132cf-2847-4dc6-812c-036339b6d30d",
"name": "If Does not Exist",
"type": "n8n-nodes-base.if",
"position": [
912,
208
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "cee7659a-cea3-494a-b4f3-c76d035a3a32",
"operator": {
"type": "string",
"operation": "empty",
"singleValue": true
},
"leftValue": "={{ $json.row_number }}",
"rightValue": ""
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "23696cc6-71e0-4a5f-a391-5116024ad19d",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
128,
0
],
"parameters": {
"color": 3,
"height": 352,
"content": "## Pinned TEST data \nThis pinned data simulates the test payload (JSON) from the Webhook. It contains sample customer and line item details needed to test the invoice generation."
},
"typeVersion": 1
},
{
"id": "32b3abc7-9cc3-4586-8bc2-10234c1071f2",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
416,
128
],
"parameters": {
"width": 656,
"height": 288,
"content": "## Generate a random INVOICE number and check for duplicities"
},
"typeVersion": 1
},
{
"id": "d0c8d1a6-02df-4038-af24-ee607f67a1ae",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1152,
16
],
"parameters": {
"color": 5,
"width": 224,
"height": 528,
"content": "## Generate a document and Encrypt"
},
"typeVersion": 1
},
{
"id": "1d61d3f5-251f-43b2-9d75-e916fc04c2ca",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
416,
448
],
"parameters": {
"color": 4,
"width": 624,
"height": 272,
"content": "## Upload the file and send the invoice to the customer"
},
"typeVersion": 1
},
{
"id": "e6b468a5-abc2-4a81-b7ec-a1fc133b7cfa",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
192,
208
],
"webhookId": "4707540d-382e-45b2-a385-4ee35b447c27",
"parameters": {
"path": "4707540d-382e-45b2-a385-4ee35b447c27",
"options": {}
},
"typeVersion": 2.1
},
{
"id": "c4a87e74-50e3-4e67-a313-9503502987e7",
"name": "Generate a PDF document",
"type": "@pdfgeneratorapi/n8n-nodes-pdf-generator-api.pdfGeneratorApi",
"position": [
1216,
128
],
"parameters": {
"data": "={\n \"order_number\": \"{{ $('Generate Invoice ID').item.json.order_number }}\",\n \"name\": \"{{ $('Webhook').item.json.name }}\",\n \"company\": \"{{ $('Webhook').item.json.company }}\",\n \"address1\": \"{{ $('Webhook').item.json.address1 }}\",\n \"city\": \"{{ $('Webhook').item.json.city }}\",\n \"additional_fee\": \"{{ $('Webhook').item.json.additional_fee }}\",\n \"payment_qr_data\": \"{{ $('Webhook').item.json.payment_qr_data }}\",\n \"line_items\": {{ $('Webhook').item.json.line_items.toJsonString() }}\n}",
"templateId": {
"__rl": true,
"mode": "list",
"value": "496040",
"cachedResultName": "n8n Invoice Example (ID: 496040)"
},
"documentOutput": "url",
"additionalFields": {}
},
"credentials": {
"pdfGeneratorApi": {
"id": "credential-id",
"name": "pdfGeneratorApi Credential"
}
},
"typeVersion": 1
},
{
"id": "44d10eb3-8b32-465d-8482-2bcd0791dd26",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
912,
-224
],
"parameters": {
"color": 5,
"width": 464,
"height": 224,
"content": "## PDF Generator API\nThe PDF Generator API node connects to the pdfgeneratorapi.com service. In this workflow, it dynamically generates a PDF document (like an invoice) by populating a custom document template—which can be downloaded from this workflow's description—using data passed from earlier steps. After generation, it uses a separate 'pdfServices' operation to encrypt the PDF with a password, ensuring the file is secure before it's sent to the customer."
},
"typeVersion": 1
},
{
"id": "afa73496-801f-4ad4-a412-045466d88175",
"name": "Upload file",
"type": "n8n-nodes-base.googleDrive",
"position": [
496,
560
],
"parameters": {
"name": "={{ $('Generate Invoice ID').item.json.order_number }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive",
"cachedResultUrl": "https://drive.google.com/drive/my-drive",
"cachedResultName": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "16TmHxVNxPHVoXZX5_an_dPAeFCx_eGKb",
"cachedResultUrl": "https://drive.google.com/drive/folders/16TmHxVNxPHVoXZX5_an_dPAeFCx_eGKb",
"cachedResultName": "n8n_folder"
},
"inputDataFieldName": "={{ $json.filename }}"
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "credential-id",
"name": "googleDriveOAuth2Api Credential"
}
},
"typeVersion": 3
},
{
"id": "52a1e363-9295-4772-bdce-bbbe4027ebb9",
"name": "Send a message + file",
"type": "n8n-nodes-base.gmail",
"position": [
736,
560
],
"webhookId": "c45e05bd-18c5-4b7d-963a-f5eccfdccaef",
"parameters": {
"sendTo": "={{ $('Webhook').item.json.email }}",
"message": "=Dear {{ $('Webhook').item.json.name}},\n\nPlease find your invoice ({{ $('Generate Invoice ID').item.json.order_number }}) attached.\n\nThe document is encrypted with your customer_id as a password.\n\nPayment details are included on the invoice. Please don't hesitate to reach out if you have any questions.\n\nWe appreciate your business.\n\nBest regards,",
"options": {
"attachmentsUi": {
"attachmentsBinary": [
{
"property": "={{ $('Encrypt PDF document').item.json.filename }}"
}
]
}
},
"subject": "=Here's your {{ $('Generate Invoice ID').item.json.order_number }}",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"id": "credential-id",
"name": "gmailOAuth2 Credential"
}
},
"typeVersion": 2.1,
"alwaysOutputData": false
},
{
"id": "2093fdde-1ea0-4237-8bba-d52c014b50b3",
"name": "Encrypt PDF document",
"type": "@pdfgeneratorapi/n8n-nodes-pdf-generator-api.pdfGeneratorApi",
"position": [
1216,
352
],
"parameters": {
"fileUrl": "={{ $json.response }}",
"resource": "pdfServices",
"operation": "encrypt",
"outputFormat": "file",
"ownerPassword": "={{ $('Webhook').item.json.customer_id }}"
},
"credentials": {
"pdfGeneratorApi": {
"id": "credential-id",
"name": "pdfGeneratorApi Credential"
}
},
"typeVersion": 1
},
{
"parameters": {
"operation": "verify",
"email": "={{ $('Webhook').item.json.email }}",
"additionalOptions": {}
},
"type": "n8n-nodes-billionverify.billionVerify",
"typeVersion": 1,
"position": [
376,
560
],
"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": [
556,
560
],
"name": "IF deliverable"
}
],
"connections": {
"Webhook": {
"main": [
[
{
"node": "Generate Invoice ID",
"type": "main",
"index": 0
}
]
]
},
"Upload file": {
"main": [
[
{
"node": "Verify Email (BillionVerify)",
"type": "main",
"index": 0
}
]
]
},
"If Does not Exist": {
"main": [
[
{
"node": "Generate a PDF document",
"type": "main",
"index": 0
}
],
[
{
"node": "Generate Invoice ID",
"type": "main",
"index": 0
}
]
]
},
"Generate Invoice ID": {
"main": [
[
{
"node": "Check if ID Already Exists",
"type": "main",
"index": 0
}
]
]
},
"Encrypt PDF document": {
"main": [
[
{
"node": "Upload file",
"type": "main",
"index": 0
}
]
]
},
"Generate a PDF document": {
"main": [
[
{
"node": "Encrypt PDF document",
"type": "main",
"index": 0
}
]
]
},
"Check if ID Already Exists": {
"main": [
[
{
"node": "If Does not Exist",
"type": "main",
"index": 0
}
]
]
},
"Verify Email (BillionVerify)": {
"main": [
[
{
"node": "IF deliverable",
"type": "main",
"index": 0
}
]
]
},
"IF deliverable": {
"main": [
[
{
"node": "Send a message + file",
"type": "main",
"index": 0
}
],
[]
]
}
},
"settings": {
"executionOrder": "v1"
}
}Workflow templates with PDF Generator API
Ready-to-use workflows that verify emails before PDF Generator API sends.
How it works
- 1
Connect BillionVerify to your PDF Generator API workflow using the n8n community node, Integrately's 1-click integration, or the BillionVerify REST API.
- 2
Before triggering document generation, pass each recipient's email address to BillionVerify for verification.
- 3
BillionVerify checks for invalid syntax, non-existent mailboxes, disposable domains, role addresses, and catch-all servers.
- 4
Filter out addresses flagged as invalid or risky — only verified contacts proceed to the PDF generation and delivery step.
- 5
Review verification results and deliverability scores in your BillionVerify dashboard to monitor ongoing list health.
When to use this
Clean contact lists before bulk PDF dispatch
Before generating invoices or reports for a contact list, verify every recipient email with BillionVerify. Remove invalid and disposable addresses so each generated PDF goes to a real inbox, reducing both bounce rates and wasted API calls.
Validate leads captured via PDF forms
When users submit their email through a PDF-based form or landing page, route that address through BillionVerify in real time. Catch typos, catch-all domains, and throwaway emails before they enter your database or trigger follow-up workflows.
Protect automated reporting pipelines
Scheduled reports sent as PDFs to client or subscriber lists benefit from periodic list hygiene. Use BillionVerify to scrub the distribution list before each send cycle, ensuring your sender reputation stays intact as the list grows.
FAQ
Can I verify emails in real time before each PDF is generated?
Yes. Using the BillionVerify REST API, you can verify a single email address synchronously within your workflow before the document generation step is triggered, adding minimal latency.
Does BillionVerify detect disposable or temporary email addresses?
Absolutely. BillionVerify identifies disposable and temporary email providers and flags them so you can exclude them from PDF delivery lists or form capture flows.
Which connection method works best for developer-tool workflows?
The REST API gives the most control and is easiest to embed directly in code. The n8n community node is ideal if your PDF generation pipeline already runs inside n8n automation workflows.
What happens to catch-all domain addresses during verification?
BillionVerify identifies catch-all domains and labels them separately. You can choose to exclude them, treat them as risky, or accept them based on your own deliverability risk tolerance.
Verify emails in PDF Generator API
Create a free account, grab your API key, and stop bounces before they happen.
Get started free