← All Newsletter & ESP Workflows
BillionVerifyGumroad

GummyMail - Next Gen Gumroad AutoReply & CRM System

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

The workflow

BillionVerify β€” verification sits right before the send.

+8
n8n steps
+2
n8n steps

Node by node

  1. 1
    Gmail TriggerTriggerΒ· n8n

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

  2. 2
    Google Gemini Chat ModelSourceΒ· n8n

    Provides or transforms the contact data flowing through the workflow.

  3. 3
    Code in JavaScriptSourceΒ· n8n

    Provides or transforms the contact data flowing through the workflow.

  4. 4
    Get many database pagesSourceΒ· n8n

    Provides or transforms the contact data flowing through the workflow.

  5. 5
    IfLogicΒ· n8n

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

  6. 6
    Create a database pageSourceΒ· n8n

    Provides or transforms the contact data flowing through the workflow.

  7. 7
    Stop and ErrorSourceΒ· n8n

    Provides or transforms the contact data flowing through the workflow.

  8. 8
    AI AgentSourceΒ· n8n

    Provides or transforms the contact data flowing through the workflow.

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

  10. 10
    IF deliverableLogicΒ· n8n

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

  11. 11
    Send a messageSendΒ· 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-gumroad.json
{
  "name": "GummyMail - Next Gen Gumroad AutoReply & CRM System + BillionVerify",
  "nodes": [
    {
      "id": "f6bbafa7-a682-4714-9bd5-ca8f5e6d20fd",
      "name": "Gmail Trigger",
      "type": "n8n-nodes-base.gmailTrigger",
      "position": [
        0,
        0
      ],
      "parameters": {
        "filters": {
          "q": "New sale of "
        },
        "pollTimes": {
          "item": [
            {
              "mode": "everyHour"
            }
          ]
        }
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "credential-id",
          "name": "gmailOAuth2 Credential"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "c8c48cc8-1b6a-4d53-a486-c4f30054deff",
      "name": "Create a database page",
      "type": "n8n-nodes-base.notion",
      "position": [
        1008,
        -16
      ],
      "parameters": {
        "options": {},
        "resource": "databasePage",
        "databaseId": {
          "__rl": true,
          "mode": "list",
          "value": "2c411b7d-dc06-80fc-87e9-db7d5c714c1e",
          "cachedResultUrl": "https://www.notion.so/2c411b7ddc0680fc87e9db7d5c714c1e",
          "cachedResultName": "Gumroad Leads"
        },
        "propertiesUi": {
          "propertyValues": [
            {
              "key": "Name|title",
              "title": "={{ $('Code in JavaScript').item.json.name }}"
            },
            {
              "key": "email|rich_text",
              "textContent": "={{ $('Code in JavaScript').item.json.email }}"
            },
            {
              "key": "Product|rich_text",
              "textContent": "={{ $('Code in JavaScript').item.json.product }}"
            },
            {
              "key": "Purchase Date|rich_text",
              "textContent": "={{ $('Code in JavaScript').item.json.purchaseDate }}"
            },
            {
              "key": "Quantity|rich_text",
              "textContent": "={{ $('Code in JavaScript').item.json.quantity }}"
            },
            {
              "key": "UniqueKey|rich_text",
              "textContent": "={{ $('Code in JavaScript').item.json.uniqueKey }}"
            }
          ]
        }
      },
      "credentials": {
        "notionApi": {
          "id": "credential-id",
          "name": "notionApi Credential"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "a09a6310-d570-4e65-81aa-cc7ae72996d6",
      "name": "Code in JavaScript",
      "type": "n8n-nodes-base.code",
      "position": [
        240,
        0
      ],
      "parameters": {
        "jsCode": "// Robust Gumroad email parser for n8n Code node\n// Normalise whitespace so fields that are on same line still parse correctly.\nconst raw = ($json.snippet || \"\");\nconst text = raw.replace(/\\s+/g, \" \").trim() + \" \"; // collapse whitespace and add trailing space\n\nfunction find(pattern, fallback = \"\") {\n  const m = text.match(pattern);\n  return m ? m[1].trim() : fallback;\n}\n\n// Product: words after $price until a dash, \"View\", \"Email\", \"Quantity\", or known keyword\nlet product = find(/\\$\\d+\\s+([A-Za-z0-9][A-Za-z0-9\\s\\-\\+&]*?)(?=\\s+(?:-|View|Email|Quantity|Product|Referrer|Name|UTM|$))/i);\nif (product) product = product.replace(/\\s+(?:Order|Product price)$/i, \"\").trim();\n\n// Name: accept Customer X Email, Name X next-keyword, Buyer X, or Name at end.\n// Works for multi-word names and when name is last field.\nlet name = \"\";\nconst namePatterns = [\n  /Customer\\s+(.+?)(?=\\s+(?:Email|Quantity|UTM|Referrer|Product|Name|$))/i,\n  /Name\\s+(.+?)(?=\\s+(?:Product|Email|Quantity|Referrer|UTM|$))/i,\n  /Buyer\\s+(.+?)(?=\\s+(?:Email|Quantity|Referrer|Product|UTM|$))/i,\n];\nfor (const p of namePatterns) {\n  const m = text.match(p);\n  if (m && m[1]) { name = m[1].trim(); break; }\n}\n\n// Email, Quantity, Referrer (stop at next keyword)\nconst email = find(/Email\\s+([^\\s]+)/i);\nconst quantity = find(/Quantity\\s+(\\d+)/i);\nlet referrer = find(/Referrer\\s+(.+?)(?=\\s+(?:Name|Email|Quantity|Product|UTM|$))/i);\n\n// purchaseDate from Gmail internalDate if present\nlet purchaseDate = \"\";\nif ($json.internalDate) {\n  purchaseDate = new Date(Number($json.internalDate)).toISOString();\n}\n\n// unique key: fallbacks to avoid undefined\nconst uniqueKey = `${email || \"no-email\"}-${product || \"no-product\"}-${purchaseDate || \"no-date\"}`;\n\nreturn [\n  {\n    json: {\n      product: product || \"\",\n      name: name || \"\",\n      email: email || \"\",\n      quantity: quantity || \"\",\n      referrer: referrer || \"\",\n      purchaseDate,\n      uniqueKey\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "cf3b7bec-90ec-4861-956c-cf981792bad7",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1280,
        -16
      ],
      "parameters": {
        "text": "=You are an email writing assistant. Write a short, warm, professional, and emotionally positive email to a customer who has just purchased one of my digital products on Gumroad.\n\nUse the following customer details:\n- Name: {{ $json.name }}\n- Product Purchased: {{ $json.property_product }}\n\nWrite the email as if it is coming directly from me (Paul). The tone should be:\n- friendly but professional\n- genuinely appreciative\n- concise (5–7 sentences max)\n- emotionally positive and reassuring\n- no unnecessary marketing fluff\n\nInclude:\n- a warm thank-you for their purchase from Gumroad \n- a sentence appreciating their trust  \n- a brief one-line description of what the product helps with  \n- reassurance that they can reach me anytime for help  \n- a positive closing note wishing them success with the product  \n\nDo NOT include subject lines unless I ask separately.\nReturn only the email body in clean paragraph form.",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 3
    },
    {
      "id": "cc162afe-bcb7-472e-8bf1-f6927e3740e7",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        1280,
        256
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "id": "credential-id",
          "name": "googlePalmApi Credential"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "8e9de348-c81b-4719-a4c7-f357638f5599",
      "name": "Send a message",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1648,
        -16
      ],
      "webhookId": "093a6f85-cd54-496a-a355-cdb71b92d908",
      "parameters": {
        "sendTo": "={{ $('Code in JavaScript').item.json.email }}",
        "message": "={{ $json.output }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "Thank you for supporting my work ❀️",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "credential-id",
          "name": "gmailOAuth2 Credential"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "b6afd0bb-e744-49e1-abbb-06018be0d6e1",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        688,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "41dd1ae9-c8bb-4e72-9148-3702cb72297f",
              "operator": {
                "type": "number",
                "operation": "equals"
              },
              "leftValue": "={{ Object.keys($json).length }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "e49a189b-319f-4d44-afc4-1a4e346ca01a",
      "name": "Stop and Error",
      "type": "n8n-nodes-base.stopAndError",
      "notes": "Error when duplictes is detected.",
      "position": [
        880,
        240
      ],
      "parameters": {
        "errorMessage": "The Data already exsists"
      },
      "notesInFlow": true,
      "typeVersion": 1
    },
    {
      "id": "cbfb4691-8738-4fc7-b1c4-6d8359fdb6ce",
      "name": "Get many database pages",
      "type": "n8n-nodes-base.notion",
      "position": [
        464,
        0
      ],
      "parameters": {
        "simple": false,
        "filters": {
          "conditions": [
            {
              "key": "UniqueKey|rich_text",
              "condition": "equals",
              "richTextValue": "={{ $json.uniqueKey }}"
            }
          ]
        },
        "options": {},
        "resource": "databasePage",
        "operation": "getAll",
        "databaseId": {
          "__rl": true,
          "mode": "list",
          "value": "2c411b7d-dc06-80fc-87e9-db7d5c714c1e",
          "cachedResultUrl": "https://www.notion.so/2c411b7ddc0680fc87e9db7d5c714c1e",
          "cachedResultName": "Gumroad Leads"
        },
        "filterType": "manual"
      },
      "credentials": {
        "notionApi": {
          "id": "credential-id",
          "name": "notionApi Credential"
        }
      },
      "notesInFlow": false,
      "typeVersion": 2.2,
      "alwaysOutputData": true
    },
    {
      "id": "f07a92a1-f032-490d-be55-19b6fadb4bdd",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -64,
        -336
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 512,
        "content": "## Request Authentication\nListens for Gumroad purchase emails and extracts buyer and product information.\n\n### Action Required\nAuthenticate Gmail\nEnsure Gumroad purchase emails are received in this inbox"
      },
      "typeVersion": 1
    },
    {
      "id": "59bc2cc5-a46e-481c-9130-08624ef95410",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        400,
        -336
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 512,
        "content": "## Customer Lookup\n\nChecks the Notion database for existing customers and stops execution if a duplicate is found.\n\n## Action Required\n- Connect your Notion account\n- Select the correct customer database\n"
      },
      "typeVersion": 1
    },
    {
      "id": "9d46503d-783a-4359-ad67-130673589713",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1248,
        -336
      ],
      "parameters": {
        "color": 7,
        "width": 544,
        "height": 512,
        "content": "## AI Reply & Delivery\nGenerates a personalized thank-you email using AI and sends it to the buyer automatically.\n\n### Outcome\n- Instant post-purchase engagement\n- Professional buyer experience\n- Fully automated workflow completion"
      },
      "typeVersion": 1
    },
    {
      "id": "1639dd58-ddcd-4734-b0da-86a92104b461",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        880,
        -336
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 512,
        "content": "## Create Customer Record\n\nCreates a new customer record in Notion for first-time buyers.\n\n### What it stores:\n- Buyer details\n- Product purchased\n- Purchase value\n- Timestamp"
      },
      "typeVersion": 1
    },
    {
      "id": "b1493b9a-309f-4859-94cb-48c50b970f42",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -912,
        -240
      ],
      "parameters": {
        "width": 576,
        "height": 320,
        "content": "# Mirai MailFlow\nThis workflow automates post-purchase communication for Gumroad creators.\n\nWhen a Gumroad purchase email arrives in Gmail, the workflow extracts buyer and product details, checks for duplicate customers, stores the purchase in Notion, and sends a personalized thank-you email using AI.\n\nSetup requires connecting Gmail, Notion, and an AI model.\nWorks on cloud and self-hosted n8n. Setup takes ~5–10 minutes."
      },
      "typeVersion": 1
    },
    {
      "parameters": {
        "operation": "verify",
        "email": "={{ $('Code in JavaScript').item.json.email }}",
        "additionalOptions": {}
      },
      "type": "n8n-nodes-billionverify.billionVerify",
      "typeVersion": 1,
      "position": [
        1288,
        -16
      ],
      "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": [
        1468,
        -16
      ],
      "name": "IF deliverable"
    }
  ],
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Create a database page",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Stop and Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Verify Email (BillionVerify)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail Trigger": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send a message": {
      "main": [
        []
      ]
    },
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "Get many database pages",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create a database page": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get many database pages": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Verify Email (BillionVerify)": {
      "main": [
        [
          {
            "node": "IF deliverable",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF deliverable": {
      "main": [
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}

When to use this

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

FAQ

Why verify before sending in Gumroad?

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