Skill v1.0.0
currentAutomated scan100/100version: "1.0.0" name: agentmail description: Give AI agents their own email inboxes using the AgentMail API. Use when building email agents, sending/receiving emails programmatically, managing inboxes, handling attachments, organizing with labels, creating drafts for human approval, or setting up real-time notifications via webhooks/websockets. Supports multi-tenant isolation with pods.
AgentMail SDK
AgentMail is an API-first email platform for AI agents. Install the SDK and initialize the client.
Installation
# TypeScript/Nodenpm install agentmail# Pythonpip install agentmail
Setup
import { AgentMailClient } from "agentmail";const client = new AgentMailClient({ apiKey: "YOUR_API_KEY" });
from agentmail import AgentMailclient = AgentMail(api_key="YOUR_API_KEY")
Inboxes
Create scalable inboxes on-demand. Each inbox has a unique email address.
// Create inbox (auto-generated address)const autoInbox = await client.inboxes.create();// Create with custom username and domainconst customInbox = await client.inboxes.create({username: "support",domain: "yourdomain.com",});// List, get, deleteconst inboxes = await client.inboxes.list();const fetchedInbox = await client.inboxes.get("inbox@agentmail.to");await client.inboxes.delete("inbox@agentmail.to");
# Create inbox (auto-generated address)inbox = client.inboxes.create()# Create with custom username and domainfrom agentmail.inboxes.types import CreateInboxRequestinbox = client.inboxes.create(request=CreateInboxRequest(username="support", domain="yourdomain.com"),)# List, get, deleteinboxes = client.inboxes.list()inbox = client.inboxes.get(inbox_id="inbox@agentmail.to")client.inboxes.delete(inbox_id="inbox@agentmail.to")
Messages
Always send both text and html for best deliverability.
// Send messageawait client.inboxes.messages.send("agent@agentmail.to", {to: "recipient@example.com",subject: "Hello",text: "Plain text version",html: "<p>HTML version</p>",labels: ["outreach"],});// Reply to messageawait client.inboxes.messages.reply("agent@agentmail.to", "msg_123", {text: "Thanks for your email!",});// List and get messagesconst messages = await client.inboxes.messages.list("agent@agentmail.to");const message = await client.inboxes.messages.get("agent@agentmail.to", "msg_123");// Update labelsawait client.inboxes.messages.update("agent@agentmail.to", "msg_123", {addLabels: ["replied"],removeLabels: ["unreplied"],});
# Send messageclient.inboxes.messages.send(inbox_id="agent@agentmail.to",to="recipient@example.com",subject="Hello",text="Plain text version",html="<p>HTML version</p>",labels=["outreach"])# Reply to messageclient.inboxes.messages.reply(inbox_id="agent@agentmail.to",message_id="msg_123",text="Thanks for your email!")# List and get messagesmessages = client.inboxes.messages.list(inbox_id="agent@agentmail.to")message = client.inboxes.messages.get(inbox_id="agent@agentmail.to", message_id="msg_123")# Update labelsclient.inboxes.messages.update(inbox_id="agent@agentmail.to",message_id="msg_123",add_labels=["replied"],remove_labels=["unreplied"])
Threads
Threads group related messages in a conversation.
// List threads (with optional label filter)const threads = await client.inboxes.threads.list("agent@agentmail.to", {labels: ["unreplied"],});// Get thread detailsconst thread = await client.inboxes.threads.get("agent@agentmail.to", "thd_123");// Org-wide thread listingconst allThreads = await client.threads.list();
# List threads (with optional label filter)threads = client.inboxes.threads.list(inbox_id="agent@agentmail.to", labels=["unreplied"])# Get thread detailsthread = client.inboxes.threads.get(inbox_id="agent@agentmail.to", thread_id="thd_123")# Org-wide thread listingall_threads = client.threads.list()
Attachments
Send attachments with Base64 encoding. Retrieve from messages or threads.
// Send with attachmentconst content = Buffer.from(fileBytes).toString("base64");await client.inboxes.messages.send("agent@agentmail.to", {to: "recipient@example.com",subject: "Report",text: "See attached.",attachments: [{ content, filename: "report.pdf", contentType: "application/pdf" },],});// Get attachmentconst fileData = await client.inboxes.messages.getAttachment("agent@agentmail.to","msg_123","att_456",);
import base64# Send with attachmentcontent = base64.b64encode(file_bytes).decode()client.inboxes.messages.send(inbox_id="agent@agentmail.to",to="recipient@example.com",subject="Report",text="See attached.",attachments=[{"content": content, "filename": "report.pdf", "content_type": "application/pdf"}])# Get attachmentfile_data = client.inboxes.messages.get_attachment(inbox_id="agent@agentmail.to",message_id="msg_123",attachment_id="att_456")
Drafts
Create drafts for human-in-the-loop approval before sending.
// Create draftconst draft = await client.inboxes.drafts.create("agent@agentmail.to", {to: "recipient@example.com",subject: "Pending approval",text: "Draft content",});// Send draft (converts to message)await client.inboxes.drafts.send("agent@agentmail.to", draft.draftId, {});
# Create draftdraft = client.inboxes.drafts.create(inbox_id="agent@agentmail.to",to="recipient@example.com",subject="Pending approval",text="Draft content")# Send draft (converts to message)client.inboxes.drafts.send(inbox_id="agent@agentmail.to", draft_id=draft.draft_id)
Pods
Multi-tenant isolation for SaaS platforms. Each customer gets isolated inboxes.
// Create pod for a customerconst pod = await client.pods.create({ clientId: "customer_123" });// Create inbox within podconst inbox = await client.pods.inboxes.create(pod.podId, {});// List inboxes scoped to podconst inboxes = await client.pods.inboxes.list(pod.podId);
# Create pod for a customerpod = client.pods.create(client_id="customer_123")# Create inbox within pod (pods.inboxes.create accepts flat kwargs)inbox = client.pods.inboxes.create(pod_id=pod.pod_id)# List inboxes scoped to podinboxes = client.pods.inboxes.list(pod_id=pod.pod_id)
Idempotency
Use clientId for safe retries on create operations.
const inbox = await client.inboxes.create({clientId: "unique-idempotency-key",});// Retrying with same clientId returns the original inbox, not a duplicate
from agentmail.inboxes.types import CreateInboxRequestinbox = client.inboxes.create(request=CreateInboxRequest(client_id="unique-idempotency-key"),)# Retrying with same client_id returns the original inbox, not a duplicate
Real-Time Events
For real-time notifications, see the reference files:
- webhooks.md - HTTP-based notifications (requires public URL)
- websockets.md - Persistent connection (no public URL needed)