You check your email when you wake up. Your Openclaw agent can do the same, except it works around the clock.
Openclaw is an open-source AI agent that runs on your computer. It connects to your email, calendar, files, and terminal. While you focus on important work, it handles tasks on its own.
Openclaw shines when it comes to email automation. It does more than send messages, it can verify accounts, extract data, manage support tickets, nurture leads, and process invoices.
This guide shares seven real-world ways people use Openclaw email automation in production. Each example includes practical steps using AgentMail's TypeScript SDK for email setup.
Most email services were not designed for agents. Gmail Workspace charges $6 to $18 per inbox each month. SendGrid can only send emails, not receive them. Running your own email server is difficult and unreliable.
Agent-native email infrastructure fixes these problems. It lets you create inboxes with code, supports two-way communication, offers real-time webhooks, and uses usage-based pricing.
Here are some ways you can use it.
AgentMail gives your agents real inboxes. Create inboxes via API. Send and receive Emails with 0 complexity. Free to start.
Use Case 1: Automated Customer Support Responses
The Problem: Customer support emails come in all day and night. People expect replies in less than an hour, but support teams can't keep up as email volume grows.
The Openclaw Solution: Your agent watches the support inbox, sorts incoming messages, answers common questions automatically, and sends complex issues to humans with all the details.
How It Works
- Customer emails support@yourcompany.com
- Webhook triggers your Openclaw agent instantly.
- Agent analyses the message (billing question, technical issue, or refund request?)
- For common issues, the agent drafts and sends a response immediately.
- For complex issues, the agent creates a ticket and notifies the human support team with a summary.
- The agent maintains a conversation thread across multiple exchanges.
Implementation
First, create a dedicated support inbox:
import { AgentMailClient } from "agentmail";
const client = new AgentMailClient({
environment: "https://api.agentmail.to",
apiKey: process.env.AGENTMAIL_API_KEY
});
// Create support inbox
const supportInbox = await client.inboxes.create({
username: "support",
displayName: "Customer Support"
});
console.log(`Support inbox created: ${supportInbox.inbox_id}`);
// Output: support@agentmail.to
Set up a webhook to notify your Openclaw agent when emails arrive:
// Configure webhook for real-time notifications
const webhook = await client.webhooks.create({
url: "https://your-openclaw-server.com/webhook",
events: ["message.received"],
inboxId: supportInbox.inbox_id
});
When your Openclaw agent receives the webhook, it processes the message and responds:
// Your Openclaw agent processes the incoming message
async function handleSupportEmail(incomingMessage) {
// Analyze the message (your custom logic here)
const category = await analyzeSupportRequest(incomingMessage.text);
if (category === "password_reset") {
// Send automated response
await client.inboxes.messages.send(supportInbox.inbox_id, {
to: [incomingMessage.from],
subject: `Re: ${incomingMessage.subject}`,
text: "I've sent you a password reset link to your registered email...",
html: "<p>I've sent you a password reset link...</p>",
inReplyTo: incomingMessage.messageId, // Maintains thread
references: incomingMessage.references
});
} else if (category === "complex_technical") {
// Escalate to human with context
await notifyHumanSupport(incomingMessage, category);
}
}
Key Benefits:
- 24/7 availability
- Sub-minute response times
- Consistent messaging
- Automatic ticket categorisation
- Thread context is maintained across exchanges.
Use Case 2: Account Signup and Verification Automation
The Problem: Testing signup flows across 50 different services means creating 50 email accounts, watching for verification emails, clicking links, and extracting OTP codes. Manual process takes hours.
The Openclaw Solution: Your agent creates temporary inboxes on demand, signs up for services programmatically, extracts verification codes automatically, and completes authentication flows without human intervention.
How It Works
- Openclaw agent creates a new inbox via API (takes 1 second)
- The agent uses that email to sign up for the target service.
- Verification email arrives, webhook notifies agent instantly.
- Agent extracts the OTP code or magic link from the email body.
- Agent completes verification automatically.
- Agent deletes temporary inbox after task completes
QA teams can use this to continuously test signup flows.
Implementation
Create a temporary inbox for each signup test:
// Create temporary test inbox
const testInbox = await client.inboxes.create({
username: `test-signup-${Date.now()}`,
displayName: "QA Test User"
});
console.log(`Test inbox: ${testInbox.inbox_id}`);
// Output: test-signup-1738234567890@agentmail.to
Your Openclaw agent uses this inbox to sign up for a service, then monitors for the verification email:
// Openclaw agent signs up using this email
await signUpForService({
email: testInbox.inbox_id,
username: "test_user",
password: "secure_password"
});
// Wait for verification email (webhook will trigger)
// When email arrives, extract OTP code
async function extractOTPCode(messageId: string) {
const message = await client.inboxes.messages.get(
testInbox.inbox_id,
messageId
);
// Extract 6-digit OTP code from email body
const otpMatch = message.text.match(/\b\d{6}\b/);
if (otpMatch) {
const otpCode = otpMatch[0];
console.log(`Extracted OTP: ${otpCode}`);
// Agent completes verification automatically
await verifyAccount(otpCode);
}
}
Clean up after the test completes:
// Delete temporary inbox after verification complete
await client.inboxes.delete(testInbox.inbox_id);
Key Benefits:
- Unlimited temporary inboxes
- Instant OTP extraction
- Parallel test execution
- No manual intervention
- Clean test environment per run
Use Case 3: Invoice and Receipt Processing
The Problem: Invoices arrive via email in various formats (PDF attachments, HTML emails, image scans). Finance teams spend 10+ hours per week manually extracting data, categorizing expenses, and entering information into accounting software.
The Openclaw Solution: Your agent monitors the accounting inbox, extracts structured data from invoice emails (vendor name, amount, date, invoice number), categorizes expenses automatically, and syncs to your accounting system in real-time.
How It Works
- The invoice email arrives at accounting@yourcompany.com
- Webhook triggers the Openclaw agent.
- Agent downloads PDF attachment or parses HTML.
- Agent extracts: vendor, amount, date, invoice number, line items.
- The agent categorises expenses (travel, software, office supplies)
- Agent creates entry in accounting software (QuickBooks, Xero, Google Sheets)
- Agent flags invoices over a certain threshold for human approval.
Implementation
Create an accounting inbox and configure a webhook:
const accountingInbox = await client.inboxes.create({
username: "accounting",
displayName: "Accounting Department"
});
await client.webhooks.create({
url: "https://your-openclaw-server.com/invoice-webhook",
events: ["message.received"],
inboxId: accountingInbox.inbox_id
});
Your Openclaw agent processes incoming invoices:
async function processInvoiceEmail(message) {
// Download PDF attachment if present
const invoice = message.attachments.find(a => a.filename.endsWith('.pdf'));
if (!invoice) {
console.log("No PDF invoice found");
return;
}
// Extract data from PDF (your OCR/parsing logic here)
const invoiceData = await extractInvoiceData(invoice.content);
// Example extracted data:
// {
// vendor: "Acme Software Inc",
// amount: 1299.00,
// invoiceNumber: "INV-2026-0042",
// date: "2026-01-29",
// category: "software"
// }
// Check if requires human approval
if (invoiceData.amount > 5000) {
await sendApprovalRequest(invoiceData);
} else {
// Auto-approve and sync to accounting software
await syncToQuickBooks(invoiceData);
// Send confirmation email
await client.inboxes.messages.send(accountingInbox.inbox_id, {
to: [message.from],
subject: `Re: ${message.subject}`,
text: `Invoice ${invoiceData.invoiceNumber} received and processed. Thank you!`,
html: `<p>Invoice <strong>${invoiceData.invoiceNumber}</strong> received and processed. Thank you!</p>`
});
}
}
Key Benefits:
- Automatic data extraction
- Real-time processing
- Categorization and routing
- Integration with accounting software
- Audit trail maintained
Use Case 4: Lead Nurturing and Follow-Up Sequences
The Problem: Sales leads arrive from website forms, events, and referrals. Each one needs a personalized follow-up at the right time. If you track leads manually, some will be missed. Fast responses are important because conversion rates drop eight times after the first five minutes.
The Openclaw Solution: Your agent watches the lead inbox, replies within seconds, sends personalized follow-ups based on engagement, sends promising leads to the sales team with details, and tracks every interaction automatically.
How It Works
- New lead fills out the contact form.
- Notification sent to leads@yourcompany.com
- Openclaw agent responds within 30 seconds with personalized message.
- Agent monitors for reply and engagement signals (opens, clicks)
- Based on behaviour, the agent sends appropriate follow-up (case study, demo invite, pricing)
- High-intent replies escalated to a sales rep with full context.
- The agent tracks the entire sequence in CRM automatically.
Implementation
Create leads inbox:
const leadsInbox = await client.inboxes.create({
username: "leads",
displayName: "Sales Team"
});
Your Openclaw agent responds to new leads instantly:
async function handleNewLead(leadData) {
// Send immediate response
await client.inboxes.messages.send(leadsInbox.inbox_id, {
to: [leadData.email],
subject: "Thanks for your interest in [Product]",
text: `Hi ${leadData.name},\n\nThanks for reaching out! I saw you're interested in [specific feature they mentioned].\n\nI'd love to show you how [Product] can help with that. Are you available for a quick 15-minute call this week?\n\nBest,\nSales Team`,
html: `<p>Hi ${leadData.name},</p><p>Thanks for reaching out! I saw you're interested in [specific feature they mentioned].</p><p>I'd love to show you how [Product] can help with that. Are you available for a quick 15-minute call this week?</p><p>Best,<br>Sales Team</p>`
});
// Schedule follow-up if no response in 48 hours
await scheduleFollowUp(leadData, 48);
}
async function sendFollowUp(leadData, sequenceStep) {
if (sequenceStep === 2) {
// Day 3: Send case study
await client.inboxes.messages.send(leadsInbox.inbox_id, {
to: [leadData.email],
subject: "How [Customer] achieved 10x ROI with [Product]",
text: "Hi again! I thought you might find this case study interesting...",
html: "<p>Hi again! I thought you might find this case study interesting...</p>"
});
} else if (sequenceStep === 3) {
// Day 7: Final follow-up
await client.inboxes.messages.send(leadsInbox.inbox_id, {
to: [leadData.email],
subject: "Still interested?",
text: "Just checking in one last time. Let me know if you'd like to chat!",
html: "<p>Just checking in one last time. Let me know if you'd like to chat!</p>"
});
}
}
Monitor for high-intent replies:
async function checkLeadEngagement(message) {
// If lead replies with questions or asks for demo
const highIntentKeywords = ["demo", "pricing", "when can we", "call", "meeting"];
const isHighIntent = highIntentKeywords.some(keyword =>
message.text.toLowerCase().includes(keyword)
);
if (isHighIntent) {
// Alert sales rep immediately
await notifySalesRep({
leadEmail: message.from,
message: message.text,
context: "High intent - mentioned demo/pricing"
});
}
}
Key Benefits:
- Sub-minute response times
- Behavioral targeting
- Automatic follow-up sequences
- Smart escalation to humans
- Complete engagement history
Use Case 5: Daily Briefings and Report Distribution
The Problem: Teams need daily summaries of metrics, alerts, and action items. Building these reports manually takes 30-60 minutes each morning. Information lives across multiple systems (analytics, CRM, support tickets, GitHub).
The Openclaw Solution: Your agent runs on a schedule (cron job), queries all relevant systems, compiles a comprehensive briefing, and emails it to your team every morning at the same time with zero manual effort.
How It Works
- Openclaw cron job triggers at 6:00 AM daily.
- Agent queries: Google Analytics (traffic), Stripe (revenue), GitHub (PR status), Zendesk (open tickets)
- The agent compiles data into a readable format.
- The agent sends a formatted email to the team distribution list.
- Urgent items are flagged prominently.
- Consistent format every day, never late
Teams can save 30-40 minutes per day on report compilation. Decision-making improves because everyone starts with the same information. Cross-team alignment increases because metrics are centralised.
Implementation
Create reporting inbox:
const reportsInbox = await client.inboxes.create({
username: "daily-reports",
displayName: "Daily Reports Bot"
});
Your Openclaw agent runs on schedule (configure in Openclaw cron):
// This function runs at 6:00 AM daily via Openclaw scheduler
async function sendDailyBrief() {
// Query all systems (your custom logic)
const analytics = await fetchGoogleAnalytics();
const revenue = await fetchStripeRevenue();
const openPRs = await fetchGitHubPRs();
const supportTickets = await fetchZendeskTickets();
// Compile briefing
const briefing = `
Daily Briefing - ${new Date().toLocaleDateString()}
๐ TRAFFIC
- Yesterday: ${analytics.visitors} visitors (+${analytics.change}%)
- Top page: ${analytics.topPage}
๐ฐ REVENUE
- MRR: $${revenue.mrr} (+${revenue.growth}%)
- New customers: ${revenue.newCustomers}
๐ง ENGINEERING
- Open PRs: ${openPRs.count}
- Needs review: ${openPRs.needsReview}
๐ซ SUPPORT
- Open tickets: ${supportTickets.open}
- Average response time: ${supportTickets.avgResponseTime}
โ ๏ธ URGENT: ${supportTickets.urgent.length > 0 ? supportTickets.urgent.join('\n') : 'None'}`;
// Send to team
await client.inboxes.messages.send(reportsInbox.inbox_id, {
to: [
"team@yourcompany.com",
"founders@yourcompany.com"
],
subject: `Daily Briefing - ${new Date().toLocaleDateString()}`,
text: briefing,
html: formatBriefingHTML(briefing)
});
}
Key Benefits:
- Automated daily execution
- Multi-system data aggregation
- Consistent timing and format
- Zero manual effort
- Immediate team alignment
Use Case 6: Email-Based Access Control and OTP Delivery
The Problem: Your application needs to send authentication codes, magic links, password resets, and security alerts. Using your personal email domain risks deliverability if volume spikes. Third-party email services are expensive at scale.
The Openclaw Solution: Your agent manages a dedicated transactional email inbox that sends time-sensitive codes and links with high deliverability, monitors bounce rates automatically, and handles reply notifications (like "I didn't request this code").
How It Works
- User requests a password reset in your app.
- Your backend triggers the Openclaw agent.
- The agent generates a secure token and sends an email via a dedicated inbox.
- User receives email with reset link/code.
- If the user replies ("I didn't request this"), the webhook notifies the security team.
- Agent tracks delivery metrics (opens, bounces, complaints)
Implementation
Create transactional inbox:
const authInbox = await client.inboxes.create({
username: "auth",
displayName: "Security Notifications",
domain: "yourdomain.com" // Custom domain improves deliverability
});
Your application triggers the agent to send OTP:
async function sendPasswordResetEmail(userEmail: string) {
// Generate secure token
const resetToken = generateSecureToken();
const resetLink = `https://yourapp.com/reset-password?token=${resetToken}`;
// Agent sends email
await client.inboxes.messages.send(authInbox.inbox_id, {
to: [userEmail],
subject: "Reset your password",
text: `Click this link to reset your password: ${resetLink}\n\nThis link expires in 1 hour.\n\nIf you didn't request this, please ignore this email.`,
html: `
<p>Click this link to reset your password:</p>
<p><a href="${resetLink}">${resetLink}</a></p>
<p>This link expires in 1 hour.</p>
<p><small>If you didn't request this, please ignore this email.</small></p>`
});
// Store token in database
await storeResetToken(userEmail, resetToken);
}
Monitor for suspicious replies:
// Webhook handler for replies to auth emails
async function handleAuthReply(message) {
// User replying "I didn't request this" indicates potential security issue
const suspiciousPatterns = ["didn't request", "unauthorized", "fraud", "hacked"];
const isSuspicious = suspiciousPatterns.some(pattern =>
message.text.toLowerCase().includes(pattern)
);
if (isSuspicious) {
// Alert security team
await notifySecurityTeam({
userEmail: message.from,
message: message.text,
timestamp: new Date()
});
}
}
Key Benefits:
- High deliverability rates
- Sub-2-second send times
- Custom domain branding
- Automatic bounce monitoring
- Security alert detection
Use Case 7: Newsletter and Content Distribution
The Problem: You send out weekly newsletters, product updates, and blog digests. Managing subscriber lists, personalizing content, tracking engagement, and handling unsubscribes all take a lot of time.
The Openclaw Solution: Your agent manages the subscriber database, personalizes content for each user, sends emails at the best times, tracks opens and clicks, handles unsubscribe requests automatically, and tests different subject lines.
How It Works
- Openclaw agent loads subscriber list from database.
- Agent personalizes email content for each recipient (name, preferences, past behaviour)
- The agent sends emails in batches to avoid rate limits.
- Agent tracks opens, clicks, and engagement.
- Unsubscribe requests are processed automatically.
- The agent compiles the performance report after the send completes
Implementation
Create newsletter inbox:
const newsletterInbox = await client.inboxes.create({
username: "newsletter",
displayName: "Your Company Newsletter",
domain: "yourdomain.com"
});
Your Openclaw agent sends personalized newsletters:
async function sendWeeklyNewsletter() {
// Load subscribers from database
const subscribers = await getNewsletterSubscribers();
// Newsletter content
const baseContent = {
subject: "Weekly Update - New Features Shipped",
headline: "This Week's Updates",
articles: [
{ title: "New Dashboard", link: "https://yoursite.com/blog/dashboard" },
{ title: "API Updates", link: "https://yoursite.com/blog/api-updates" }
]
};
// Send to each subscriber with personalization
for (const subscriber of subscribers) {
const personalizedContent = {
...baseContent,
greeting: `Hi ${subscriber.firstName}`,
// Add personalized recommendations based on their interests
recommendedArticles: getRecommendations(subscriber.interests)
};
await client.inboxes.messages.send(newsletterInbox.inbox_id, {
to: [subscriber.email],
subject: personalizedContent.subject,
text: formatNewsletterText(personalizedContent),
html: formatNewsletterHTML(personalizedContent),
headers: {
"List-Unsubscribe": `<mailto:newsletter@yourdomain.com?subject=unsubscribe>`,
"List-Unsubscribe-Post": "List-Unsubscribe=One-Click"
}
});
// Small delay to avoid rate limits
await sleep(100);
}
console.log(`Newsletter sent to ${subscribers.length} subscribers`);
}
Handle unsubscribe requests automatically:
async function handleNewsletterReply(message) {
// Check for unsubscribe request
if (message.subject.toLowerCase().includes("unsubscribe") ||
message.text.toLowerCase().includes("unsubscribe")) {
// Remove from subscriber list
await removeSubscriber(message.from);
// Send confirmation
await client.inboxes.messages.send(newsletterInbox.inbox_id, {
to: [message.from],
subject: "You've been unsubscribed",
text: "You've been removed from our newsletter. Sorry to see you go!",
html: "<p>You've been removed from our newsletter. Sorry to see you go!</p>"
});
}
}
Key Benefits:
- Automated personalization
- Batch sending capabilities
- Engagement tracking
- Auto-unsubscribe handling
- Performance analytics
Getting Started with Openclaw Email Automation
Ready to implement these use cases? Here's how to get started:
Step 1: Install Openclaw
Follow the official Openclaw installation guide for your operating system (macOS, Windows, Linux, or remote server).
Step 2: Set Up AgentMail
Sign up at agentmail.to and get your API key. AgentMail provides the email infrastructure your Openclaw agent needs.
Install the TypeScript SDK:
npm install agentmail
Step 3: Create Your First Inbox
import { AgentMailClient } from "agentmail";
const client = new AgentMailClient({
environment: "https://api.agentmail.to",
apiKey: process.env.AGENTMAIL_API_KEY
});
const inbox = await client.inboxes.create({
username: "my-first-agent",
displayName: "My First Openclaw Agent"
});
console.log(`Inbox created: ${inbox.inbox_id}`);
Step 4: Install the AgentMail Skill in Openclaw
openclaw skills install agentmail-to/agentmail-skills/agentmail
Or via ClawdHub:
clawdhub install agentmail
Step 5: Configure Webhooks
Set up webhooks so your Openclaw agent receives instant notifications when emails arrive:
await client.webhooks.create({
url: "https://your-openclaw-server.com/webhook",
events: ["message.received", "message.sent"],
inboxId: inbox.inbox_id
});
Step 6: Build Your First Automation
Begin with something simple, such as automated responses or daily briefings. After that is working, you can move on to more complex workflows.
Best Practices for Openclaw Email Automation
1. Use Dedicated Inboxes Per Workflow
Do not use the same inbox for different automation workflows. Keep customer support emails separate from newsletter unsubscribes. Keeping them isolated prevents mix-ups and makes troubleshooting easier.
// Good: Separate inboxes
const supportInbox = await client.inboxes.create({ username: "support" });
const leadsInbox = await client.inboxes.create({ username: "leads" });
const reportsInbox = await client.inboxes.create({ username: "reports" });
// Bad: One inbox for everything
const sharedInbox = await client.inboxes.create({ username: "everything" });
2. Always Include HTML and Text Versions
Email clients show HTML if it is available, but including a text version helps avoid spam filters and ensures everyone can read your message.
await client.inboxes.messages.send(inbox.inbox_id, {
to: [recipient],
subject: "Your subject",
text: "Plain text version", // Always include
html: "<p>HTML version</p>" // Always include
});
3. Maintain Thread Context
Use the inReplyTo and references headers to keep conversations organized in threads:
await client.inboxes.messages.send(inbox.inbox_id, {
to: [originalSender],
subject: `Re: ${originalSubject}`,
text: "Your reply",
html: "<p>Your reply</p>",
inReplyTo: originalMessage.messageId,
references: originalMessage.references
});
4. Monitor and Alert on Failures
Set up monitoring so you are notified if automation fails:
try {
await client.inboxes.messages.send(inbox.inbox_id, messageData);
} catch (error) {
// Alert your team when sends fail
await notifyTeam({
alert: "Email send failed",
error: error.message,
timestamp: new Date()
});
}
5. Test with Temporary Inboxes
Before deploying to production, test with temporary inboxes:
const testInbox = await client.inboxes.create({
username: `test-${Date.now()}`
});
// Run your tests
await runAutomationTests(testInbox);
// Clean up
await client.inboxes.delete(testInbox.inbox_id);
6. Use Custom Domains for Professional Appearance
For customer-facing automation, use your own domain:
const professionalInbox = await client.inboxes.create({
username: "support",
domain: "yourcompany.com", // Instead of @agentmail.to
displayName: "YourCompany Support"
});
7. Rate Limit Your Own Sends
Even though AgentMail handles high volume, it adds delays when sending bulk emails:
for (const recipient of largeList) {
await client.inboxes.messages.send(inbox.inbox_id, {
to: [recipient],
subject: "Your message",
text: "Content"
});
await sleep(100); // 100ms delay between sends
}
Common Challenges and Solutions
Challenge 1: "My agent isn't receiving webhook notifications"
Solution: Verify your webhook URL is publicly accessible and returns HTTP 200. Test with a service like webhook.site first.
// Test webhook setup
const webhook = await client.webhooks.create({
url: "https://webhook.site/your-unique-url", // Test first
events: ["message.received"],
inboxId: inbox.inbox_id
});
Challenge 2: "Emails are landing in spam"
Solution: Use custom domains with the right DNS records (SPF, DKIM, DMARC). Always include both HTML and text versions, and avoid words that trigger spam filters.
// Set up custom domain with verification
const domain = await client.domains.create({
domain: "yourcompany.com",
feedbackEnabled: true
});
// Follow DNS setup instructions provided
console.log(domain.records);
Challenge 3: "I need to handle attachments"
Solution: AgentMail supports attachments. Access them via the messages API:
const message = await client.inboxes.messages.get(inbox.inbox_id, messageId);
for (const attachment of message.attachments) {
console.log(`Attachment: ${attachment.filename}`);
console.log(`Size: ${attachment.size} bytes`);
// Download and process attachment content
await processAttachment(attachment);
}
Challenge 4: "How do I search old messages?"
Solution: Use AgentMail's semantic search to find messages based on their content, not just keywords:
// Search messages semantically
const results = await client.inboxes.messages.search(inbox.inbox_id, {
query: "invoice from January",
limit: 20
});
Challenge 5: "My automation is too slow"
Solution: Use webhooks instead of checking for new messages on a schedule. Process tasks in the background and group operations together when you can.
// Bad: Polling every minute
setInterval(async () => {
const messages = await client.inboxes.messages.list(inbox.inbox_id);
// Process messages
}, 60000);
// Good: Webhooks notify instantly
// Your webhook endpoint receives notification immediately when email arrives
Security Considerations
Inbox Isolation
Each automation workflow should have its own inbox. Never share inboxes between different agents or use cases.
// Good: Isolated inboxes
const productionSupport = await client.inboxes.create({ username: "prod-support" });
const stagingSupport = await client.inboxes.create({ username: "staging-support" });
// Bad: Shared inbox
const sharedSupport = await client.inboxes.create({ username: "support" });
// Both production and staging using same inbox
API Key Management
Store API keys in environment variables, never in code:
// Good
const client = new AgentMailClient({
environment: "https://api.agentmail.to",
apiKey: process.env.AGENTMAIL_API_KEY // From environment
});
// Bad
const client = new AgentMailClient({
environment: "https://api.agentmail.to",
apiKey: "sk-abc123" // Hardcoded, dangerous
});
Webhook Signature Verification
Verify webhook signatures to ensure requests actually come from AgentMail:
// Verify webhook signature
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
Monitor for Suspicious Activity
Set up alerts for unusual patterns:
// Alert on high volume spikes
if (emailsSentLastHour > normalThreshold * 3) {
await notifySecurityTeam({
alert: "Unusual email volume detected",
count: emailsSentLastHour,
threshold: normalThreshold
});
}
Conclusion
Email automation turns Openclaw from a smart assistant into a true team member. It manages customer support while you sleep, follows up with leads automatically, processes invoices in real time, and always sends scheduled reports.
The seven use cases covered here are running in production today:
- Customer Support - 24/7 response, sub-minute times, automatic escalation
- Account Verification - Unlimited temporary inboxes, instant OTP extraction
- Invoice Processing - Automatic data extraction, real-time accounting sync
- Lead Nurturing - Instant engagement, behavioural follow-ups, smart routing.
- Daily Briefings - Multi-system aggregation, consistent delivery
- Access Control - High-deliverability transactional emails, security monitoring
- Newsletter Distribution - Personalization at scale, engagement tracking
Start with something simple. Choose one use case, build it, test it, and launch it. Then you can add more.
Your Openclaw agent is ready to take on your email workload. Set up the right infrastructure so it can get started.
FAQ
Can I use my own domain with AgentMail?
Yes! AgentMail supports custom domains on paid plans. Instead of agent@agentmail.to, you can use agent@yourdomain.com.
Can I access AgentMail inboxes from my phone?
AgentMail is API-only, so there's no official mobile app. However, you could build a simple mobile interface using the API, or access via webhooks that forward to your personal email.
What if I need more than 2,000 emails/day with Gmail?
You'd need to: (1) Request quota increases from Google (not guaranteed), (2) Use multiple Gmail accounts and distribute the load, or (3) Switch to a dedicated email service like AgentMail.
Is AgentMail secure?
Yes. AgentMail uses TLS and data encryption, API key authentication, and webhook signature verification.
Can I try AgentMail before committing?
Yes! AgentMail offers a free tier with 3 inboxes and limited volume, perfect for testing.
AgentMail gives your agents real inboxes. Create inboxes via API. Send and receive Emails with 0 complexity. Free to start.

