Build an AI-Powered Referral Engine
Chain Hunter, Gemini, and Gmail into a self-hosted outreach pipeline.
Introduction
30 Second Summary
Reaching out to professionals at companies you admire takes forever. You have to find the right contacts, write a personalized email for each one, and send them individually. Most people give up before they even start.
In this project, you will build a self-hosted automation engine that takes a company domain, finds decision-makers' emails, writes personalized referral requests using AI, and sends them through your Gmail account.
What You'll Build
A local n8n workflow that chains Hunter's email-finding API, Google Gemini's text generation, and Gmail into a single automated referral pipeline.
By the end of this project, you'll have:
- A self-hosted n8n instance running in Docker on your own machine.
- Configured API credentials for Hunter, Google Gemini, and Gmail OAuth2.
- A complete 5-node workflow that turns a company domain into personalized, sent outreach emails.
- Secret Mission: Add email verification to filter out undeliverable addresses before sending.
Are there any prerequisites?
You need a Gmail account with 2-Step Verification enabled. Basic familiarity with what APIs are is helpful, but you do not need prior experience with any of the tools in this project.
Run n8n Locally with Docker
To build your referral engine, you need a workflow automation tool running on your local machine. n8n is a self-hosted automation platform that lets you visually connect APIs together into powerful workflows.
In this step, you'll install Docker Desktop and use it to run n8n. Docker wraps n8n in a portable container so you don't need to install Node.js or manage dependencies directly.
In this step, get ready to:
- Install Docker Desktop on your machine.
- Launch n8n in a Docker container with persistent storage.
- Create your n8n owner account and open the workflow editor.
Install Docker Desktop
Docker Desktop provides the engine that runs containers on your machine. n8n publishes an official Docker image, so once Docker is ready, launching n8n is a single command.
- Open the Docker Desktop download page in your browser:
- https://www.docker.com/products/docker-desktop/
- Download the installer for your operating system (Mac Apple Silicon, Mac Intel, or Windows).
- Run the installer and follow the on-screen prompts to complete installation.
- Once installed, open Docker Desktop by pressing Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
- Type Docker Desktop and press Enter to launch it.
- Wait for Docker Desktop to finish starting up. You'll see a green "running" indicator in the bottom-left corner of the Docker Desktop window.
What is Docker?
Docker lets you run applications inside isolated containers. A container packages an app with all its dependencies so it runs the same way on every machine.
Instead of installing n8n and its Node.js dependencies directly on your computer, Docker downloads a pre-built n8n image and runs it in a container. Your system stays clean.
- Open your terminal by pressing Cmd+Space (macOS) or the Windows key (Windows), then typing Terminal (macOS) or PowerShell (Windows) and pressing Enter.
- Verify Docker is installed by running this command:
docker --version
✔️ I see a version number
Docker is installed and ready. Move on to the next substep.
ⓧ Command not found
This means Docker Desktop didn't install correctly or isn't running yet.
- Make sure Docker Desktop is fully started (look for the green indicator in the Docker Desktop window).
- Close and reopen your terminal after installing Docker Desktop. The terminal needs a fresh session to find new commands.
- If neither works, restart your computer and open Docker Desktop again before retrying.
Start n8n in Docker
n8n stores your workflows and credentials in a local database. To keep this data safe between restarts, you'll create a Docker volume first. Then you'll launch n8n with a single docker run command.
- Create a persistent data volume for n8n by running this command:
docker volume create n8n_data
What is a Docker volume?
A Docker volume is a named storage area that lives outside the container. When you stop or remove the container, everything inside it disappears. The volume keeps your n8n workflows and credentials safe on your hard drive.
- Confirm the volume was created by running:
docker volume ls
You should see n8n_data listed in the output.
- Launch the n8n container by running this command:
docker run -it --rm --name n8n -p 5678:5678 -e GENERIC_TIMEZONE="[[YOUR_TIMEZONE="e.g. America/New_York"]]" -e TZ="[[YOUR_TIMEZONE="e.g. America/New_York"]]" -e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true -e N8N_RUNNERS_ENABLED=true -v n8n_data:/home/node/.n8n docker.n8n.io/n8nio/n8n
What does this command do?
- -it runs the container interactively so you can see n8n's logs in your terminal.
- --rm automatically removes the container when you stop it. Your data is safe in the volume.
- --name n8n gives the container a friendly name you can reference later.
- -p 5678:5678 maps port 5678 on your machine to port 5678 inside the container, making n8n accessible in your browser.
- -v n8n_data:/home/node/.n8n mounts the volume you just created, so workflows and credentials persist between sessions.
- docker.n8n.io/n8nio/n8n is the official n8n Docker image.
Find your timezone string
Use the IANA timezone format like America/New_York, Europe/London, or Asia/Tokyo. You can find your timezone at wikipedia.org/wiki/List_of_tz_database_time_zones.
After a few seconds, you should see log output in your terminal ending with a line that mentions n8n is ready. Your terminal will stay occupied showing these logs.
Container won't start?
- If you see a "port already in use" error, another process is using port 5678. Close any other servers or containers on that port and try again.
- If Docker says "Cannot connect to the Docker daemon", Docker Desktop is not running. Open Docker Desktop and wait for it to finish starting before retrying.
- help me troubleshoot my n8n Docker container startup error
Verify n8n is running and create your owner account
- Open your web browser and navigate to:
http://localhost:5678
You should see the n8n setup screen asking you to create an owner account.
- Fill in your name, email, and a password to create your owner account.
- Click Next to complete the setup wizard.
Once you finish the setup, you'll land on the n8n workflow editor canvas. This is the visual workspace where you'll build your referral engine.
Page won't load?
- Check that your terminal is still showing n8n logs. If you accidentally closed the terminal window, the container stopped. Rerun the docker run command from above.
- Make sure you're using http:// and not https:// in the URL.
- help me access n8n at localhost:5678
Your automation engine is running. Next up, you'll connect it to Hunter and Gemini so n8n can find contacts and generate emails on your behalf.
Set Up Hunter and Gemini API Credentials
Your n8n instance is up and running. Now it needs permission to talk to the external services that power your referral engine.
In this step, you'll connect three services to n8n: Hunter for finding professional email addresses, Google Gemini for writing personalized emails, and Gmail for sending them.
In this step, get ready to:
- Create a Hunter.io account and configure its API key in n8n.
- Create a Gemini API key and add it to n8n.
- Set up Gmail OAuth2 credentials for sending emails through n8n.
Create a Hunter account and get your API key
Hunter.io finds professional email addresses associated with a company domain. You need a free account to access its API.
- Open your browser and go to hunter.io.
- Click Sign up and create a free account using your email address.
- No credit card is required for the free plan.
What does Hunter's free plan include?
The free plan gives you 50 credits per month with no time limit. A Domain Search costs 1 credit per email found, so one search for a company with 10 results uses 10 credits.
- Once logged in, navigate to the API page on your Hunter dashboard.
- Copy your API secret key from this page. Keep it somewhere safe.
Now add this credential to n8n.
- Switch back to your n8n editor at http://localhost:5678.
- Click the Create button in the upper-left corner of the side menu.
- Select Credential.
- Search for Hunter and select it from the list.
- Paste your Hunter API key into the API Key field.
- Click Save. n8n automatically tests the credential to confirm it connects successfully.
n8n tests credentials on save
When you save a credential, n8n runs an automatic test to verify it works. If you see a green success message, your API key is valid.
Credential test failed?
Double-check that you copied the full API key from the Hunter dashboard without any extra spaces at the start or end.
help me fix my Hunter API credential in n8n
Create a Gemini API key
Google Gemini generates the personalized email text for each contact. You need an API key from Google AI Studio to connect it to n8n.
- Open Google AI Studio in a new browser tab.
- Sign in with your Google account if prompted.
- Click Create API Key.
- Select a new Google Cloud project or an existing one.
- Copy the generated API key.
Is the Gemini API free?
The Gemini API free tier includes free input and output tokens. For this project you only generate a handful of short emails per run, which is well within the free tier limits.
Now add this credential to n8n.
- Switch back to your n8n editor.
- Click the Create button in the upper-left corner of the side menu.
- Select Credential.
- Search for Google Gemini(PaLM) and select it.
- Paste your Gemini API key into the API Key field.
- Click Save. Wait for the green success message confirming the credential works.
Gemini credential test failed?
Make sure you copied the full key without extra spaces. Also confirm the Google Cloud project associated with the key has billing enabled or is using the free tier.
help me fix my Gemini credential in n8n
Set up Gmail OAuth2 credentials
Gmail credentials use OAuth2 instead of a simple API key. This means you need to create a project in the Google Cloud Console, enable the Gmail API, and authorize n8n to send emails on your behalf.
Why OAuth2 instead of an API key?
OAuth2 lets you grant n8n specific permissions to your Gmail account without sharing your password. For self-hosted n8n, you must set up a custom OAuth2 credential because Managed OAuth2 is only available on n8n Cloud.
Start by creating the credential placeholder in n8n so you can grab the redirect URL.
- In your n8n editor, click the Create button in the upper-left corner.
- Select Credential.
- Search for Google OAuth2 single service and select it.
- Copy the OAuth Redirect URL shown in the credential modal. It should be:
http://localhost:5678/rest/oauth2-credential/callback
Keep this n8n credential modal open. You will return to it after setting up Google Cloud.
Now create a Google Cloud Console project and configure OAuth2.
- Open the Google Cloud Console in a new tab.
- Click the project dropdown in the top navigation bar.
- Click New Project.
- Enter a project name (e.g. n8n-referral-engine) and click Create.
- Wait for the project to be created, then select it from the project dropdown.
Next, enable the Gmail API for your project.
- In the left sidebar, go to APIs & Services, then Library.
- Search for Gmail API.
- Click the Gmail API result, then click Enable.
Now configure the OAuth consent screen.
- In the left sidebar, go to APIs & Services, then OAuth consent screen.
- For Audience, select External and click Next.
- Enter your email address in the required contact fields.
- Click Next through the remaining sections and save.
What about test users?
Your app defaults to Testing mode. Only Google accounts you manually add as test users can complete the OAuth flow. Go to APIs & Services then OAuth consent screen then Test users and add the Google account you plan to authenticate with.
In Testing mode, consent and tokens expire after seven days. If your credential stops working later, reconnect it in n8n.
Create the OAuth client credentials.
- In the left sidebar, go to APIs & Services, then Credentials.
- Click + Create credentials, then select OAuth client ID.
- In the Application type dropdown, select Web application.
- Give it a recognizable name (e.g. n8n Gmail).
- Under Authorized redirect URIs, click Add URI.
- Paste the redirect URL you copied from n8n earlier:
http://localhost:5678/rest/oauth2-credential/callback
- Click Create.
- A modal appears showing your Client ID and Client Secret. Copy both values.
Finally, finish the credential in n8n.
- Switch back to the n8n credential modal you left open.
- Paste the Client ID into the Client ID field.
- Paste the Client Secret into the Client Secret field.
- Click Sign in with Google to complete the authentication flow.
- Choose the Google account you added as a test user.
- Grant the requested Gmail permissions.
- Click Save in n8n.
Seeing a redirect_uri_mismatch error?
This means the redirect URI in Google Cloud doesn't exactly match what n8n is sending. Copy the OAuth Redirect URL from your n8n credential panel and paste it exactly into the Authorized redirect URIs field in Google Cloud. Make sure you include http:// (not https://) and the port number 5678.
help me fix my Gmail OAuth2 redirect URI mismatch
All three credentials are now configured and ready. Next up, you'll build the workflow that uses them to find contacts at a target company.
Build the Hunter Domain Search Node
Your credentials are set up and ready to go. Now it's time to build the actual workflow that powers your referral engine.
The first functional piece is Hunter's Domain Search. You give it a company's website domain, and it returns a list of professional email addresses associated with that company.
In this step, get ready to:
- Create a new workflow in n8n with a Manual Trigger node.
- Add and configure a Hunter node to search for email contacts at a target domain.
- Test the node and confirm real contact data flows through.
Create a new workflow
Every automation in n8n starts with a workflow. A workflow is a sequence of connected nodes that pass data from one step to the next.
- Switch back to your n8n editor at http://localhost:5678.
- In the left sidebar, click Workflows to open the Workflows list.
- Click the button to create a new workflow.
- n8n opens a blank canvas. This is where you'll visually connect nodes to build your automation.
- Open the nodes panel by clicking the + icon in the top right corner of the canvas, or press N on your keyboard.
- Search for Manual Trigger.
- Select it when it appears in the search results.
The Manual Trigger node appears on your canvas. This node lets you run the workflow on demand by clicking the Execute workflow button.
What is a Manual Trigger?
A trigger node is the starting point of every n8n workflow. It defines what kicks off the automation.
The Manual Trigger lets you run the workflow whenever you click the execute button. Other trigger types can start workflows on a schedule, when a webhook is received, or when a file changes.
Add the Hunter node
With the trigger in place, you need a node that actually does something. The Hunter node will call the Hunter API to find email addresses at a company domain.
- Click the + connector icon on the right side of the Manual Trigger node to open the nodes panel.
- Search for Hunter.
- Select Hunter when it appears in the results.
- In the Actions section, select the operation to get every email address found on the internet using a given domain name, with sources.
n8n adds the Hunter node to your canvas, connects it to the Manual Trigger, and opens its configuration panel.
- In the Credential to connect with dropdown, select the Hunter credential you set up in the previous step.
- In the Domain field, type intercom.com.
Why intercom.com?
Intercom is a large company with many publicly listed professional email addresses. This makes it a reliable test domain that will return multiple results.
You can swap this for any company domain later. Each email found costs 1 credit from your Hunter free plan (50 credits per month). The free plan returns up to 10 email addresses per domain search.
Test the Hunter node
Time to see if your node is working. You'll execute the workflow and check that Hunter returns real contact data.
- Click the Execute step button inside the Hunter node's details window.
- Wait a few seconds for Hunter to respond.
You should see results appear in the Output panel. Each result contains fields like first name, last name, email address, position, and confidence score.
What should I see?
The Output panel displays up to 10 items from intercom.com. Each item includes an email address, the contact's name, their job title, and a confidence score indicating how likely the address is valid.
You can switch between Table, JSON, and Schema views at the top of the output panel to explore the data in different formats.
- Save your workflow by pressing Cmd+S (macOS) or Ctrl+S (Windows).
Not seeing any results?
- Make sure you selected your Hunter credential in the Credential to connect with dropdown. Without it, the API call will fail.
- Double-check that the domain is typed as intercom.com with no spaces or extra characters.
- Confirm your Hunter account still has credits remaining by checking your dashboard at hunter.io.
Help me troubleshoot why my Hunter node isn't returning results in n8n.
Your first API node is live and pulling real data. Next up, you'll feed these contacts into Google Gemini to generate personalized outreach emails for each one.
Add Gemini to Generate Personalized Emails
Your Hunter node is finding real contacts at a target company. Now you need something to turn that raw contact data into a compelling outreach message.
In this step, you will add a Google Gemini node to your workflow that reads each contact's name, position, and company from the Hunter output, then generates a personalized referral request email.
In this step, get ready to:
- Add the Google Gemini node and connect it to your workflow.
- Write a prompt template using n8n expressions to personalize each email.
- Test the Gemini node and verify it produces natural-sounding emails.
Add the Google Gemini node
The Google Gemini node in n8n lets you send a text prompt to a Gemini model and receive a generated response. You will use its "Message a Model" operation to generate a personalized email for each contact.
- In the n8n workflow editor, click the + button on the right edge of the Hunter node to add a new node.
- In the search bar that appears, type Google Gemini.
- Select the Google Gemini node from the results (not the "Google Gemini Chat Model" sub-node).
- Under Resource, select Text.
- Under Operation, select Message a Model.
- Under Credential to connect with, select your saved Google Gemini(PaLM) API credential from the dropdown.
- Under Model, select a model from the dropdown. n8n dynamically loads the models available to your account.
Why Google Gemini instead of the Chat Model node?
n8n has two Gemini-related nodes. The Google Gemini node is a standalone node with direct operations like "Message a Model." The Google Gemini Chat Model node is a sub-node designed for use inside an AI Agent framework.
For this workflow, the standalone Google Gemini node is simpler. It takes a text prompt in and returns a completion out, which is exactly what you need for generating emails.
Don't see a model in the dropdown?
Make sure you selected the correct Google Gemini(PaLM) credential. If the dropdown is empty, your API key may not have access to any models. Return to Google AI Studio and verify the key is active.
help me troubleshoot why no Gemini models appear in my n8n Google Gemini node dropdown
Write the prompt template with expressions
n8n expressions let you pull data from a previous node's output directly into a text field. You use the {{ $json.fieldName }} syntax to reference fields from the current item flowing through the workflow.
- In the Google Gemini node's Prompt field, click to enter the text area.
- Paste the following prompt template:
Write a concise, personalized referral request email to {{ $json.first_name }} {{ $json.last_name }}, who works as {{ $json.position }} at Intercom.
The email should:
- Be professional but warm
- Mention their role specifically
- Ask if they would be open to a brief conversation or could refer me to the right person
- Be no longer than 150 words
- Not include a subject line
Sign the email as "Alex" (no last name).
What do the expressions do?
Each {{ $json.fieldName }} expression pulls a value from the Hunter node's output for the current contact item. The Hunter Domain Search returns fields like first_name, last_name, and position for each email address it finds.
Because the Hunter node outputs multiple items (one per contact), the Gemini node runs once for each item automatically. Every contact gets their own personalized email.
Customize the prompt to your situation
Feel free to adjust the prompt to match your actual outreach goals. You can change the tone, the ask, or the sign-off name. The key is keeping the expression references intact so each email stays personalized.
Test the Gemini node
- Click Test step on the Google Gemini node to run it with the Hunter output data.
n8n sends the prompt (with each contact's real data filled in) to Gemini and displays the response in the output panel.
- Review the output in the OUTPUT panel on the right side of the node.
- Verify that each output item contains a natural-sounding email that references the contact's name and position.
- Click through multiple items using the arrows in the output panel to confirm personalization differs per contact.
What should I see?
Each output item should contain a short, professional email that mentions the contact by name and references their specific role. The emails should read naturally and differ from one another based on each contact's details.
Seeing an error or empty output?
If you see a 400 error, check that your prompt field does not have any broken expressions. Each expression must be wrapped in {{ }} with the correct field name.
If the output is empty or generic (no personalization), click the expression editor icon next to the prompt field and verify the expressions resolve to real values from the Hunter output.
help me debug why my n8n Google Gemini node returns an error or non-personalized output
Your workflow now finds contacts and writes personalized outreach for each one. Next up, you will connect Gmail to send these emails automatically.
Connect Gmail to Send the Email
Your Gemini node is generating personalized referral emails for each contact Hunter finds. The missing piece is actually delivering those emails to real inboxes.
In this step, you'll connect Gmail as the final node in your workflow. This turns your automation from a draft generator into a complete outreach engine.
In this step, get ready to:
- Add a Gmail node and configure it to send emails.
- Map the recipient, subject, and body fields using data from earlier nodes.
- Run the full pipeline end-to-end and confirm delivery.
Add the Gmail node
The Gmail node is the final piece of the pipeline. It takes the personalized email text from Gemini and sends it to the contact's address from Hunter.
- Click the + button on the right edge of your Google Gemini node to add a new connected node.
- In the search panel, type Gmail and select the Gmail node.
- In the Credential to connect with dropdown, select the Gmail OAuth2 credential you configured earlier.
- Set Resource to Message.
- Set Operation to Send.
What does this configure?
Setting Resource to Message and Operation to Send tells n8n this node will compose and deliver a new email through your Gmail account. Other operations like Reply or Get are for reading or responding to existing threads.
Configure the email fields
The Gmail node needs three pieces of information: who to send to, the subject line, and the email body. You'll use n8n expressions to pull data dynamically from earlier nodes in the workflow.
- Click the To field.
- Click the Expression tab (the toggle to the right of the field).
- Type the following expression to pull the email address from the Hunter node output:
{{ $('Hunter').item.json.value }}
Why reference the Hunter node directly?
The Gmail node sits after the Gemini node, so $json would only give you Gemini's output (the generated email text). To reach the contact's email address from two nodes back, you use $('Hunter').item.json.value to reference the Hunter node's output for the current item.
The value field is what Hunter calls the email address in its Domain Search response.
- Click the Subject field and enter a subject line for your outreach email, for example:
Quick question about your team at {{ $('Hunter').item.json.organization }}
- Click the Email Type dropdown and select Text.
- Click the Message field, switch to the Expression tab, and enter:
{{ $json.text }}
What does $json.text reference?
Since the Gmail node is connected directly after the Gemini node, $json refers to Gemini's output for the current item. The text field contains the generated email body that Gemini produced.
Now disable the n8n branding that gets appended to outgoing emails.
- Scroll down and click Options to expand the additional settings.
- Click Add option.
- Select Append n8n attribution from the list.
- Toggle it off so your emails look professional.
Keep your outreach clean
Disabling the attribution removes a small "Sent with n8n" footer from every email. For professional referral outreach, you want the email to look like it came directly from you.
Run the full workflow
Before sending to real contacts, you'll test the pipeline by sending to yourself first. This confirms the entire chain works without accidentally emailing strangers.
- Temporarily override the To field by replacing the expression with your own email address (you'll switch it back after testing).
- Click Test workflow in the top right corner of the n8n editor to execute the complete pipeline.
- Wait for all four nodes to show green checkmarks indicating successful execution.
- Open your email inbox and confirm the personalized emails arrived.
What should I see?
Each contact from the Hunter results generates one email in your inbox. The email body should be a natural-sounding, personalized referral request that mentions the contact's name and position at Intercom.
You may receive multiple emails (one per contact that Hunter returned). On the free plan, Hunter returns up to 10 email addresses per domain.
- Once you've confirmed delivery, switch the To field back to the Hunter expression:
{{ $('Hunter').item.json.value }}
Emails not arriving?
Check your spam or junk folder. Gmail sometimes filters automated emails from your own account.
If you see a red error on the Gmail node, click it to view the error message. A common issue is the OAuth2 token expiring. Return to Credentials, open your Gmail credential, and click Sign in with Google again to refresh the token.
If Gemini returned empty output, the Gmail node has no message body to send. Go back and test the Gemini node individually to confirm it produces text.
Help me troubleshoot my Gmail node error
Your referral engine is fully operational. You have a complete pipeline that takes a company domain, finds contacts, generates personalized outreach, and delivers it straight to inboxes.
Secret mission
Add Email Verification with a Conditional Branch
Your workflow sends emails to every address Hunter finds. But what if some of those addresses are stale or undeliverable? Bounced emails hurt your sender reputation and waste Gemini API calls. Add a verification gate that checks each address before it reaches personalization.
Clean Up Your Resources
Clean Up Your Resources
This project runs entirely locally via Docker and uses only free-tier services. There are no ongoing costs to worry about.
Decide whether to keep your resources running, pause them to come back later, or delete them entirely.
Resources you used:
- Docker container n8n (running locally, no cost).
- Docker volume n8n_data (persistent local storage, no cost).
- Hunter.io free account (50 credits/month, renews monthly, no cost).
- Google Cloud project with Gemini API key and Gmail OAuth2 client (free tier, no cost).
Keep everything running
No action needed. Choose this if you're still actively building workflows or plan to extend the referral engine soon.
- Your n8n container stays running at http://localhost:5678.
- Your Hunter.io free account renews its 50 credits every month automatically.
- Your Google Cloud project remains active with no charges on the free tier.
Pause - I'll come back to this later
Stop the Docker container to free up system memory. Your workflow data persists in the n8n_data volume so nothing is lost.
- Stop the n8n container by running:
docker stop n8n
- When you're ready to resume, start n8n again with the same docker run command you used in Step 1.
- Your Hunter.io account and Google Cloud project remain active at no cost.
Delete - I don't want to use this again
Remove all project resources and start fresh. This permanently deletes your n8n workflows, credentials, and account data.
- Stop and remove the Docker container and volume by running:
docker stop n8n && docker rm n8n && docker volume rm n8n_data
- Delete your Hunter.io account by going to your Account Settings page, scrolling to the bottom, and clicking I want to delete my account in the Delete Account section. Confirm with your password.
- Delete your Google Cloud project by opening the Google Cloud Console, navigating to the IAM & Admin Settings page, clicking Shut down, entering your project ID, and clicking Shut down anyway. This removes the Gemini API key and Gmail OAuth2 client along with the project.
That's a Wrap!
That's a Wrap!
Nice work! You just built an AI-powered referral engine running entirely on your own machine.
You've learned how to:
- Self-host n8n in Docker and orchestrate multiple API integrations into a single visual workflow.
- Connect the Hunter API to find real professional contacts at any company domain, and use Google Gemini to generate personalized outreach emails.
- Authenticate with Gmail OAuth2 and send automated emails through your own account as part of a complete pipeline.
- Added an email verification gate with a conditional branch to ensure only deliverable addresses receive outreach.
Ready to quiz yourself?