← All Newsletter & ESP Workflows
BillionVerifyXero

Send automated payment reminders for Xero invoices via Outlook email

Pull contacts, verify each address with BillionVerify, and continue to Xero β€” 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 Xero step removes that risk automatically β€” only deliverable addresses continue, the rest are flagged.

The workflow

BillionVerify β€” verification sits right before the send.

+5
n8n steps
+3
n8n steps

Node by node

  1. 1
    Daily Invoice Check TriggerTriggerΒ· n8n

    Starts the workflow β€” on a schedule, a webhook, or manually while you test.

  2. 2
    Fetch All Xero InvoicesSourceΒ· n8n

    Provides or transforms the contact data flowing through the workflow.

  3. 3
    Filter Out Paid InvoicesLogicΒ· n8n

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

  4. 4
    Calculate Days Until DueSourceΒ· n8n

    Provides or transforms the contact data flowing through the workflow.

  5. 5
    Filter Invoices Due SoonLogicΒ· n8n

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

  6. 6
    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.

  7. 7
    IF deliverableLogicΒ· n8n

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

  8. 8
    Send a message1SendΒ· n8n

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

  9. 9
    Log Reminder in Xero HistorySourceΒ· n8n

    Provides or transforms the contact data flowing through the workflow.

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-xero.json
{
  "name": "Send automated payment reminders for Xero invoices via Outlook email + BillionVerify",
  "nodes": [
    {
      "id": "1a3db5de-8382-402f-b9cb-de802a862c36",
      "name": "Daily Invoice Check Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -560,
        720
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 12
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "52ff9ea5-446b-4690-9314-a30304f22413",
      "name": "Fetch All Xero Invoices",
      "type": "n8n-nodes-base.xero",
      "position": [
        -336,
        720
      ],
      "parameters": {
        "options": {},
        "operation": "getAll",
        "returnAll": true
      },
      "typeVersion": 1
    },
    {
      "id": "10c17a71-9f23-4a11-bd3a-39e319ea242e",
      "name": "Filter Out Paid Invoices",
      "type": "n8n-nodes-base.if",
      "position": [
        -112,
        720
      ],
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{ $json.Status }}",
              "value2": "PAID",
              "operation": "notEqual"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "b4b36361-ddf1-423f-b40f-225e42d951f4",
      "name": "Filter Invoices Due Soon",
      "type": "n8n-nodes-base.if",
      "position": [
        320,
        720
      ],
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{ $json.isDueSoon }}",
              "value2": true
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "14901d07-21a0-41e0-a13d-356a8cd125d3",
      "name": "Calculate Days Until Due",
      "type": "n8n-nodes-base.code",
      "position": [
        128,
        720
      ],
      "parameters": {
        "jsCode": "const today = new Date();\nconst dueDate = new Date($input.item.json.DueDate);\nconst diffTime = dueDate - today;\nconst diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));\n\nreturn {\n  json: {\n    ...$input.item.json,\n    daysUntilDue: diffDays,\n    isDueSoon: diffDays <= 7 && diffDays >= 0\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "46c031b7-eb66-4906-ae88-221d4a0af6f7",
      "name": "Log Reminder in Xero History",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        864,
        704
      ],
      "parameters": {
        "url": "=https://api.xero.com/api.xro/2.0/Invoices/{{ $json.InvoiceID }}/History",
        "method": "PUT",
        "options": {},
        "jsonBody": "={\n  \"HistoryRecords\": [\n    {\n      \"Details\": \"Payment reminder email sent on {{ $now.toFormat('yyyy-MM-dd') }} - Invoice due in {{ $json.daysUntilDue }} days\"\n    }\n  ]\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "xeroOAuth2Api"
      },
      "typeVersion": 4.3
    },
    {
      "id": "3434e3ea-3e5d-46f6-bd26-6a29f2ad9c1a",
      "name": "Workflow Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1136,
        240
      ],
      "parameters": {
        "color": 5,
        "width": 460,
        "height": 1228,
        "content": "## Send Automated Payment Reminders for Overdue Xero Invoices\n\nThis workflow automatically monitors your Xero invoices and sends friendly payment reminders to customers when invoices are due within 7 days. It also logs each reminder in the invoice history for complete audit trails.\n\n### How it works\n* Runs daily at 12 PM to check all invoices in your Xero account\n* Fetches all invoices and filters out those already marked as paid\n* Calculates the number of days until each invoice is due\n* Identifies invoices that are due within the next 7 days\n* Sends personalized email reminders to customers via Microsoft Outlook\n* Logs the reminder activity in Xero's invoice history for tracking\n* Includes invoice number, due date, and amount in the reminder\n\n### Requirements\n* Xero account with API access (free for all Xero users)\n* Microsoft Outlook account (or Office 365) for sending emails\n* Valid email addresses configured for customers in Xero contacts\n* n8n instance with credentials configured for both services\n\n### Setup Instructions\n1. **Configure Xero credentials** in n8n (OAuth2 connection)\n2. **Configure Microsoft Outlook credentials** in n8n (OAuth2)\n3. **Customize the email template** in the 'Send Email Reminder to Customer' node to match your brand voice\n4. **Adjust the reminder threshold** - currently set to 7 days, modify in the 'Calculate Days Until Due' code node if needed\n5. **Test the workflow** with manual execution before enabling the daily schedule\n6. **Activate the workflow** to begin automated reminders\n\n### Customization Ideas\n* **Change the reminder window:** Edit the code node to send reminders at different intervals (e.g., 14 days, 3 days, or when overdue)\n* **Escalating reminders:** Create multiple IF nodes to send different messages based on urgency\n* **Amount-based logic:** Add conditions to send different messages for high-value invoices\n* **Multi-channel notifications:** Add Slack nodes to notify your team when large invoices are due\n* **Payment links:** Include online payment URLs in the email to make it easier for customers to pay\n* **Customer segments:** Filter by customer tags to send different reminder styles\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "3a9b87fd-f9df-4242-9605-4e7c5b1fe672",
      "name": "Step 1 Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -656,
        432
      ],
      "parameters": {
        "color": 7,
        "width": 720,
        "height": 460,
        "content": "## Step 1: Daily Check & Filter\n\nTriggers at noon every day, fetches all invoices from Xero, and filters out invoices that are already marked as paid.\n\n**Customize:** Change the trigger time in the Schedule Trigger node to match your preferred notification schedule."
      },
      "typeVersion": 1
    },
    {
      "id": "1162f84f-e7e9-4fd3-a88b-0e5f0e160257",
      "name": "Step 2 Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        64,
        432
      ],
      "parameters": {
        "color": 7,
        "width": 444,
        "height": 460,
        "content": "## Step 2: Calculate & Identify\n\nUses JavaScript to calculate how many days remain until each invoice is due and flags invoices that are due within the next 7 days.\n\n**Customize:** Change `diffDays <= 7` to a different number to adjust the reminder window."
      },
      "typeVersion": 1
    },
    {
      "id": "a4fac765-aaa8-47c7-af2a-bb8ebe1025c3",
      "name": "Step 3 Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        512,
        432
      ],
      "parameters": {
        "color": 7,
        "width": 544,
        "height": 460,
        "content": "## Step 3: Send & Log Reminders\n\nSends personalized email reminders to customers for invoices due within 7 days, then logs the reminder activity in Xero's invoice history for complete tracking.\n\n**Customize:** Edit the email template to match your brand voice and add payment links or instructions."
      },
      "typeVersion": 1
    },
    {
      "id": "474fe1d1-32d8-4f2f-8255-0072e5310ddc",
      "name": "Send a message1",
      "type": "n8n-nodes-base.microsoftOutlook",
      "position": [
        608,
        704
      ],
      "webhookId": "76158935-3235-4a09-9708-467bb1c2aded",
      "parameters": {
        "subject": "=Payment Reminder - Invoice {{ $json.InvoiceNumber }}",
        "bodyContent": "=Good Morning, \n\nThis is a friendly reminder that you have an invoice that is pending invoice ({{ $json.InvoiceNumber }}) that is due for payment within 7 days.\n\nPlease action at your earliest convenience. \n\nIf you have actioned this within the last 24 hours, please disregard. \n\nRegards, ",
        "toRecipients": "={{ $json.Contact.EmailAddress }}",
        "additionalFields": {}
      },
      "credentials": {
        "microsoftOutlookOAuth2Api": {
          "id": "vbnYPtIaBpjdog1K",
          "name": "WFAN"
        }
      },
      "typeVersion": 2
    },
    {
      "parameters": {
        "operation": "verify",
        "email": "={{ $json.Contact.EmailAddress }}",
        "additionalOptions": {}
      },
      "type": "n8n-nodes-billionverify.billionVerify",
      "typeVersion": 1,
      "position": [
        248,
        704
      ],
      "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": [
        428,
        704
      ],
      "name": "IF deliverable"
    }
  ],
  "connections": {
    "Send a message1": {
      "main": [
        [
          {
            "node": "Log Reminder in Xero History",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch All Xero Invoices": {
      "main": [
        [
          {
            "node": "Filter Out Paid Invoices",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Days Until Due": {
      "main": [
        [
          {
            "node": "Filter Invoices Due Soon",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Invoices Due Soon": {
      "main": [
        [
          {
            "node": "Verify Email (BillionVerify)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Out Paid Invoices": {
      "main": [
        [
          {
            "node": "Calculate Days Until Due",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily Invoice Check Trigger": {
      "main": [
        [
          {
            "node": "Fetch All Xero Invoices",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Verify Email (BillionVerify)": {
      "main": [
        [
          {
            "node": "IF deliverable",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF deliverable": {
      "main": [
        [
          {
            "node": "Send a message1",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    }
  },
  "settings": {
    "availableInMCP": false,
    "executionOrder": "v1"
  }
}

When to use this

  • Cleaning a list before a Xero send or sync.
  • Protecting Xero deliverability and sender reputation.
  • Keeping bounce rates low so your sending is never throttled.

FAQ

Why verify before sending in Xero?

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