Prerequisites
- A Google Cloud project with billing enabled
- A Mailtarget account with API access
- Vertex AI API enabled on your GCP project
- Python 3.10+ installed
- A company domain you own (e.g.
yourcompany.com)
⚠️ Company Domain Required
You must use your own company domain to send emails (e.g. noreply@yourcompany.com). Free email domains like Gmail, Yahoo, Outlook, or any public email provider are not allowed as sending addresses.
Your domain can be hosted on any provider — Google Workspace, Microsoft 365, Cloudflare, or any DNS host. As long as you own the domain and can configure its DNS records, you're good to go.
💡 We strongly recommend using a subdomain (e.g. mail.yourcompany.com) or a new dedicated domain for sending. This keeps your main domain's reputation isolated and gives you a safe environment for testing.
-
1. Set Up Your GCP Environment
Install the Google Cloud CLI and authenticate:
Install gcloud CLI (if not already installed) # https://cloud.google.com/sdk/docs/install # Authenticate gcloud auth login gcloud auth application-default login # Set your project gcloud config set project YOUR_PROJECT_ID # Enable Vertex AI API gcloud services enable aiplatform.googleapis.com
-
2. Get Your Mailtarget API Key
a. Log in to app.mailtarget.co
b. Go to Configuration → API Keys
c. Click Create API Key
d. Copy the key
export MAILTARGET_API_KEY=your_api_key_here
-
-
3. Install Dependencies
pip install google-cloud-aiplatform requests
-
4. Define the Mailtarget Tool
Create a Python function that your Vertex AI agent will use to send emails:
import requestsimport osdef send_email( to_email: str, to_name: str, subject: str, body_html: str, body_text: str = "") -> dict: """Send an email via Mailtarget API. Args: to_email: Recipient email address. to_name: Recipient name. subject: Email subject line. body_html: HTML content of the email. body_text: Plain text fallback (optional). Returns: dict with transmissionId on success, or error details. """ response = requests.post( "https://transmission.mailtarget.co/v1/layang/transmissions", headers={ "Authorization": f"Bearer {os.environ['MAILTARGET_API_KEY']}", "Content-Type": "application/json" }, json={ "to": [{"email": to_email, "name": to_name}], "from": { "email": "noreply@yourcompany.com", "name": "Your Company" }, "subject": subject, "bodyHtml": body_html, "bodyText": body_text, "optionsAttributes": { "openTracking": True, "clickTracking": True, "transactional": True } } ) return response.json()
Replace
noreply@yourcompany.comandYour Companywith your verified sending domain and company name.-
5. Create the Vertex AI Agent
Wire the tool into a Vertex AI agent using the Agent Development Kit (ADK) or LangChain:
Option A: Using Google ADK
from google.adk.agents import Agentagent = Agent( name="email_agent", model="gemini-2.0-flash", description="An agent that sends emails via Mailtarget.", instruction="""You are an email assistant. When asked to send an email, use the send_email tool. Write professional HTML emails with clean formatting. Always confirm the transmissionId after sending.""", tools=[send_email],)# Run the agentresponse = agent.run( "Send a welcome email to john@example.com (John Smith) " "with a friendly onboarding message.")print(response)
### **Option B: Using LangChain**from langchain_google_vertexai import ChatVertexAIfrom langchain.agents import AgentExecutor, create_tool_calling_agentfrom langchain_core.tools import toolfrom langchain_core.prompts import ChatPromptTemplate@tooldef send_email(to_email: str, to_name: str, subject: str, body_html: str, body_text: str = "") -> dict: """Send an email via Mailtarget API.""" import requests, os response = requests.post( "https://transmission.mailtarget.co/v1/layang/transmissions", headers={ "Authorization": f"Bearer {os.environ['MAILTARGET_API_KEY']}", "Content-Type": "application/json" }, json={ "to": [{"email": to_email, "name": to_name}], "from": {"email": "noreply@yourcompany.com", "name": "Your Company"}, "subject": subject, "bodyHtml": body_html, "bodyText": body_text, "optionsAttributes": {"openTracking": True, "clickTracking": True} } ) return response.json()llm = ChatVertexAI(model="gemini-2.0-flash")prompt = ChatPromptTemplate.from_messages([ ("system", "You are an email assistant. Use the send_email " "tool when asked to send emails."), ("human", "{input}"), ("placeholder", "{agent_scratchpad}"),])agent = create_tool_calling_agent(llm, [send_email], prompt)executor = AgentExecutor(agent=agent, tools=[send_email])result = executor.invoke({ "input": "Send a welcome email to john@example.com (John Smith) " "with a friendly onboarding message."})print(result["output"])
-
Deploy to Vertex AI Agent Engine (Production)
For production deployment, use Vertex AI Agent Engine:
import vertexaifrom vertexai import agent_enginesvertexai.init(project="YOUR_PROJECT_ID", location="us-central1")# Deploy the agentremote_agent = agent_engines.create( agent_engine=agent, requirements=["requests"], display_name="Mailtarget Email Agent",)# Query the deployed agentsession = remote_agent.create_session(user_id="user-1")response = remote_agent.stream_query( session=session, message="Send a test email to hello@example.com")for chunk in response: print(chunk)
-
🚀 What You Just Built
Your Vertex AI agent can now autonomously:
- Write email content in any style or tone
- Design HTML emails with proper formatting
- Send via Mailtarget's production infrastructure
- Track opens and clicks automatically
- Scale on Google Cloud's managed runtime
What's Happening Under the Hood
- You tell the agent what to send and who to send it to
- Vertex AI writes the content, builds the HTML, calls the Mailtarget tool
- Mailtarget handles delivery, authentication (SPF/DKIM/DMARC), tracking, and reliability
Advanced: Add More Mailtarget Tools
Extend your agent with additional capabilities:
def list_sending_domains() -> dict: """List all verified sending domains in Mailtarget.""" response = requests.get( "https://transmission.mailtarget.co/v1/domain/sending", headers={"Authorization": f"Bearer {os.environ['MAILTARGET_API_KEY']}"} ) return response.json()def create_template(template_id: str, name: str, html: str) -> dict: """Create a reusable email template in Mailtarget.""" response = requests.post( "https://transmission.mailtarget.co/v1/template", headers={ "Authorization": f"Bearer {os.environ['MAILTARGET_API_KEY']}", "Content-Type": "application/json" }, json={"id": template_id, "name": name, "html": html} ) return response.json()def send_template_email(to_email: str, to_name: str, subject: str, template_id: str, substitution_data: dict) -> dict: """Send an email using a stored Mailtarget template.""" response = requests.post( "https://transmission.mailtarget.co/v1/layang/transmissions", headers={ "Authorization": f"Bearer {os.environ['MAILTARGET_API_KEY']}", "Content-Type": "application/json" }, json={ "to": [{"email": to_email, "name": to_name}], "from": {"email": "noreply@yourcompany.com", "name": "Your Company"}, "subject": subject, "templateId": template_id, "substitutionData": substitution_data } ) return response.json()
Add these to your agent's tools list for full email management capability.
Troubleshooting
| Problem | Fix |
|---|---|
401 Unauthorized | Check your Mailtarget API key is correct and MAILTARGET_API_KEY is set |
400 Bad Request | Verify the from email uses a verified company domain |
| Email not arriving | Check spam folder; verify SPF/DKIM records for your domain |
| Vertex AI permission error | Ensure aiplatform.googleapis.com is enabled and you're authenticated |
| Agent not calling the tool | Check the function docstring — Gemini uses it to decide when to call the tool |
| Free email domain rejected | Use your company domain — Gmail, Yahoo, Outlook, etc. are not allowed |