Guide
Email APIs for AI Agents Compared
Your AI agent needs to read, send, and search email. There are six common ways to do it: Gmail API, Microsoft Graph API, SendGrid/Mailgun/Postmark, direct IMAP, Nylas API, and Nylas CLI. Each has different auth complexity, provider coverage, and agent-friendliness. This guide compares all six across 14 criteria, with code examples showing how agents actually call each one. Covers Gmail, Outlook, Exchange, Yahoo, iCloud, and IMAP providers.
Written by Nick Barraclough Product Manager
Reviewed by Caleb Geene
Disclosure: Nylas CLI is built by Nylas, the publisher of this guide. We present factual comparisons, but readers should be aware of this relationship.
The problem: 6 options, wildly different trade-offs
AI agents that need email access face six options split across three categories: provider-specific APIs (Gmail API, Microsoft Graph), send-only services (SendGrid, Mailgun, Postmark), and multi-provider solutions (IMAP, Nylas). Setup time ranges from 2 minutes to 4+ hours, provider coverage spans 1 to 6 providers, and agent compatibility varies from raw MIME parsing to native MCP integration.
The right choice depends on what your agent actually does. An agent that triages support tickets needs read access. An agent that extracts OTP codes needs search. An agent that schedules meetings needs calendar integration. Each of the six options covers a different slice of these requirements, and none of them covers everything equally well.
Gmail API
The Gmail API is Google's official REST interface for programmatic access to Gmail and Google Workspace accounts. It supports full read, write, search, and label operations across 1.8 billion Gmail accounts worldwide. For agents that only target Gmail users, the Gmail API provides the deepest provider-specific integration, including Pub/Sub push notifications and Workspace admin controls.
The catch: setup takes 30+ minutes. You need a GCP project, an OAuth consent screen (1-6 weeks for external app review), scope selection, credential creation, and custom token refresh logic. Messages come back as base64url-encoded MIME, which you'll need to parse. Watch-based push notifications expire every 48 hours and must be renewed.
According to Google's Gmail API quota docs, the messages.send endpoint costs 100 quota units per call, and new projects get 6,000 quota units per minute per user per project. An agent sending more than 60 messages in one minute needs backoff or batching.
# Gmail API: what your agent code looks like
# 1. Authenticate (custom OAuth2 flow)
# 2. Build base64url MIME message
# 3. Handle token refresh on 401
# 4. Parse base64url MIME response
# 5. Implement exponential backoff for 429s
import base64
from email.mime.text import MIMEText
from googleapiclient.discovery import build
message = MIMEText("Hello from my agent")
message["to"] = "[email protected]"
message["subject"] = "Agent update"
raw = base64.urlsafe_b64encode(message.as_bytes()).decode()
service = build("gmail", "v1", credentials=creds)
service.users().messages().send(
userId="me", body={"raw": raw}
).execute()Best for: Google Workspace-only deployments where you already have GCP infrastructure. Agents that need Gmail-specific features like labels and Pub/Sub push.
Microsoft Graph API
Microsoft Graph is the unified API for Outlook and Microsoft 365 email, calendar, and contacts. It covers over 400 million commercial Microsoft 365 users and replaces Exchange Web Services (EWS), which Microsoft is deprecating in October 2026. For agents that exclusively target Microsoft accounts, Graph provides the deepest integration, including shared mailboxes, room calendars, and Teams interop.
The catch: requires an Azure AD app registration, MSAL token handling, and Microsoft-specific message formats. The permission model has two modes (delegated and application), each with different scopes. Throttling returns 429 with a Retry-After header your agent must respect. According to Microsoft's throttling docs, the default limit for mail endpoints is 10,000 requests per 10 minutes per app per tenant. An agent that exceeds this threshold gets 429 responses with a Retry-After header, and your code must implement backoff logic manually.
# Microsoft Graph: what your agent code looks like
import msal
import requests
app = msal.ConfidentialClientApplication(
client_id, authority=authority,
client_credential=client_secret
)
# Acquire token (handle refresh, cache, retry)
result = app.acquire_token_for_client(
scopes=["https://graph.microsoft.com/.default"]
)
# Send email (Microsoft-specific JSON format)
requests.post(
"https://graph.microsoft.com/v1.0/me/sendMail",
headers={"Authorization": f"Bearer {result['access_token']}"},
json={
"message": {
"subject": "Agent update",
"body": {"contentType": "Text", "content": "Hello"},
"toRecipients": [
{"emailAddress": {"address": "[email protected]"}}
]
}
}
)Best for: Microsoft 365-only organizations. Agents that need Exchange Online features like shared mailboxes and room calendars.
SendGrid / Mailgun / Postmark
SendGrid, Mailgun, and Postmark are transactional email services designed for outbound delivery at scale. They handle deliverability tracking, bounce management, and template rendering, but none of them can read an inbox or access calendar data. For AI agents that only send notifications, alerts, or reports without needing to read replies, these services offer the simplest send-side integration with free tiers starting at 100 emails per day.
The catch: SendGrid, Mailgun, and Postmark are send-only. An agent that needs to both read and send email can't use these alone. Mailgun offers an Inbound Routes feature for receiving, but it requires DNS MX record changes and webhook handling.
SendGrid's free tier allows 100 emails per day. Mailgun offers 1,000 emails in the first month, then requires a paid plan. Postmark charges $1.25 per 1,000 emails.
# SendGrid: send-only example
import sendgrid
sg = sendgrid.SendGridAPIClient(api_key="SG.xxx")
sg.send({
"personalizations": [{"to": [{"email": "[email protected]"}]}],
"from": {"email": "[email protected]"},
"subject": "Agent notification",
"content": [{"type": "text/plain", "value": "Task complete."}]
})
# But where's the "read inbox" call?
# It doesn't exist. SendGrid can't read email.Best for: Agents that only send outbound notifications, alerts, or reports. Not suitable for agents that need to read and respond to email.
Direct IMAP
IMAP (Internet Message Access Protocol), defined in RFC 9051, is the underlying protocol that most email providers support. It gives agents raw access to mailboxes, folders, and messages across virtually any provider. IMAP has been the standard mail access protocol since 1996, and roughly 95% of email providers still support it. For agents that need protocol-level control or work with niche mail servers, direct IMAP provides the most flexible option.
The catch: IMAP wasn't designed for agents. The IDLE extension for push notifications only monitors one folder at a time. Messages come as raw MIME, which requires parsing multi-part content, decoding base64 attachments, and handling character encoding edge cases. Each provider has its own credential requirements: Gmail needs OAuth2 tokens, Yahoo uses app passwords, iCloud requires app-specific passwords.
Python's built-in imaplib module handles the protocol layer, but agents still need to parse RFC 2822 headers and MIME multipart bodies manually. The search syntax is IMAP-native (not full-text), and sending email requires a separate SMTP connection on port 587.
# Direct IMAP: raw protocol access
import imaplib
import email
# Connect (credentials differ by provider)
imap = imaplib.IMAP4_SSL("imap.gmail.com")
imap.login("[email protected]", "oauth2_token") # or app password
# Select inbox
imap.select("INBOX")
# Search (IMAP search syntax, not full-text)
_, message_ids = imap.search(None, "FROM", '"[email protected]"')
# Fetch and parse MIME (the hard part)
for mid in message_ids[0].split():
_, data = imap.fetch(mid, "(RFC822)")
msg = email.message_from_bytes(data[0][1])
subject = msg["subject"]
# Now decode the body (might be multipart, might be base64,
# might be quoted-printable, might be nested...)
# No JSON output. No calendar. No contacts.
# Can't send without SMTP (separate connection).Best for: Agents that need raw protocol access, work with niche providers, or operate in environments where third-party APIs aren't allowed.
Nylas API and Nylas CLI
Nylas provides a unified API that normalizes email, calendar, and contacts across 6 providers (Gmail, Outlook, Exchange, Yahoo, iCloud, IMAP) into a single interface. The Nylas CLI wraps this API in a command-line tool with structured JSON output, a built-in MCP server exposing 16 tools for AI agents, and a non-interactive mode for scripting. Setup takes about 2 minutes compared to 1-4 hours for Gmail API or Microsoft Graph.
Install the CLI, run nylas auth login, and start running commands. OAuth is handled automatically. Token refresh is internal. Rate limit retries are built in.
# Nylas CLI: complete setup + first email
brew install nylas/nylas-cli/nylas
nylas auth login # browser-based OAuth, any provider
nylas email list --json --limit 5
# Send email
nylas email send --to [email protected] \
--subject "Agent update" --body "Task complete." --yes
# Search inbox
nylas email search "invoice Q4" --json
# Calendar access (same tool, same auth)
nylas calendar events list --json
# AI agent integration via MCP
nylas mcp install --assistant claude-codeThe Nylas CLI is free, open-source, and MIT licensed. The MCP server exposes 16 tools that Claude Code, Cursor, VS Code, and Windsurf can call natively. For production applications, the Nylas API offers the same multi-provider coverage with SDKs in Python, Node.js, Ruby, and Java.
Best for: Agents that need multi-provider email access, agents that also need calendar and contacts, and any project where setup speed matters.
The comparison table
All six email API options compared across 14 criteria that matter most for AI agent development: inbox read access, send capability, search, calendar and contacts integration, provider count, auth complexity, JSON output format, MCP server availability, webhook support, rate limit handling, open-source status, CLI availability, and agent-friendliness. Only 2 of the 6 options support both read and send across multiple providers.
| Capability | Gmail API | Graph API | SendGrid | IMAP | Nylas CLI |
|---|---|---|---|---|---|
| Read inbox | Yes | Yes | No | Yes | Yes |
| Send email | Yes | Yes | Yes | Via SMTP | Yes |
| Search messages | Yes | Yes | No | Limited | Yes |
| Calendar access | Separate API | Yes | No | No | Yes |
| Contacts access | Separate API | Yes | No | No | Yes |
| Provider count | 1 (Gmail) | 1 (Microsoft) | N/A | Any | 6 |
| Auth complexity | High (GCP + OAuth) | High (Azure AD + MSAL) | Low (API key) | Medium (per-provider) | Low (one command) |
| JSON output | Yes (after MIME decode) | Yes | N/A | No (raw MIME) | Yes (--json) |
| MCP server | No | No | No | No | Yes (16 tools) |
| Webhook support | Pub/Sub (48h expiry) | Subscriptions | Yes (send events) | No (must poll) | Yes |
| Rate limit handling | Manual backoff | Manual backoff | Built-in | Provider-dependent | Built-in |
| Open source | Client libs only | Client libs only | Client libs only | Protocol | Yes (MIT) |
| CLI available | No | No | No | Via mutt/mailx | Yes |
| Agent-friendly | API client | API client | API client | Library | Subprocess + MCP |
Which to use when
The right email API for an AI agent depends on three factors: which email providers your users are on, whether the agent needs read access or send-only, and how much setup time you can afford. Single-provider agents should use the native API (Gmail API or Microsoft Graph). Send-only agents should use SendGrid or Postmark. Multi-provider agents that need read, send, search, and calendar access should use Nylas CLI or Nylas API.
- All your users are on Gmail / Google Workspace? Gmail API. You'll write more code, but you get Google-specific features like labels, Pub/Sub push, and Workspace admin APIs.
- All your users are on Microsoft 365? Graph API. Same trade-off: more code, but you get shared mailboxes, room calendars, and Teams integration.
- Your agent only sends notifications? SendGrid or Postmark. Fast setup, high deliverability, good analytics. Don't try to make them read inboxes.
- You need raw protocol access or work with niche providers? Direct IMAP. Most flexible, most work.
- You need multi-provider read+send+search+calendar? Nylas CLI or Nylas API. One integration, 6 providers, JSON output, MCP server for agents.
Agent integration patterns
AI agents consume email APIs in three distinct patterns: as an API client through a language SDK, as a subprocess call that shells out to a CLI tool, or through an MCP server that provides pre-defined tools to the agent host. The API client pattern requires the most custom code (typically 40-80 lines per tool definition). The subprocess pattern cuts that to 10-15 lines. The MCP pattern eliminates tool definition code entirely.
Pattern 1: API client (Gmail API, Graph API, SendGrid)
In the API client pattern, your agent calls the email API through a language SDK like Google's google-api-python-client or Microsoft's msal. This means writing custom tool definitions for each operation (list, send, search), handling OAuth2 token acquisition and refresh, and parsing provider-specific response formats. A typical Gmail API tool definition runs 30-50 lines of Python just for listing messages, because you need to decode base64url MIME bodies and extract headers from nested payload structures.
# Agent tool definition for Gmail API
def gmail_list_messages(query: str, max_results: int = 10) -> list:
"""List Gmail messages matching a search query."""
service = build("gmail", "v1", credentials=get_credentials())
results = service.users().messages().list(
userId="me", q=query, maxResults=max_results
).execute()
messages = []
for msg_ref in results.get("messages", []):
msg = service.users().messages().get(
userId="me", id=msg_ref["id"], format="full"
).execute()
# Decode base64url MIME body
# Handle multipart content
# Extract headers
messages.append(parse_gmail_message(msg))
return messagesPattern 2: Subprocess (Nylas CLI, IMAP tools)
In the subprocess pattern, your agent shells out to a CLI command and parses the JSON output. The Nylas CLI returns structured JSON by default with the --json flag, so each tool definition is roughly 10 lines of Python: build the command, run it with subprocess.run(), and parse the result with json.loads(). No SDK installation, no OAuth code, no token refresh logic.
# Agent tool definition for Nylas CLI
import subprocess
import json
def email_list(query: str = "", limit: int = 10) -> list:
"""List recent emails, optionally filtered by search query."""
cmd = ["nylas", "email", "list", "--json", "--limit", str(limit)]
if query:
cmd = ["nylas", "email", "search", query, "--json", "--limit", str(limit)]
result = subprocess.run(cmd, capture_output=True, text=True)
return json.loads(result.stdout)
def email_send(to: str, subject: str, body: str) -> dict:
"""Send an email."""
result = subprocess.run([
"nylas", "email", "send",
"--to", to, "--subject", subject, "--body", body,
"--json", "--yes"
], capture_output=True, text=True)
return json.loads(result.stdout)Pattern 3: MCP server (Nylas CLI only)
The MCP (Model Context Protocol) pattern connects agents to a server that provides pre-defined tools over a standardized wire format. The Nylas CLI's MCP server exposes 16 tools covering email, calendar, and contacts operations. Claude Code, Cursor, and VS Code connect to MCP servers natively, so agents gain email access with zero custom tool definitions.
# Install MCP for your AI assistant -- one command
nylas mcp install --assistant claude-code
# That's it. Your agent now has 16 tools:
# - list_messages, send_message, search_messages
# - create_draft, update_draft, send_draft
# - list_events, create_event, update_event
# - list_contacts, search_contacts
# - and more
# Test it by asking your agent:
# "What emails did I get from Sarah today?"
# "Send a reply saying I'll review the contract by Friday"
# "Create a meeting for tomorrow at 2pm with the team"The MCP pattern eliminates tool definition boilerplate entirely. For agents running in Claude Code, Cursor, or VS Code, it's the fastest path from zero to working email access.
JSON output comparison
Agents need structured data they can parse without custom deserialization logic. The Gmail API returns messages with base64url-encoded bodies nested inside a payload object, requiring 2 decoding steps before the agent can read the content. The Nylas CLI returns flat JSON with top-level subject, from, and snippet fields that are ready for jq, Python json.loads(), or direct LLM consumption.
# Gmail API response (simplified)
{
"messages": [
{
"id": "18e4b2c3d4e5f6a7",
"payload": {
"headers": [
{"name": "From", "value": "Sarah <[email protected]>"},
{"name": "Subject", "value": "Q4 Report"}
],
"body": {"data": "SGVsbG8gZnJvbSBTYXJhaA=="}
}
}
]
}
# Nylas CLI response (nylas email list --json --limit 1)
[
{
"id": "a1b2c3d4e5f6g7h8",
"subject": "Q4 Report",
"from": [{"name": "Sarah", "email": "[email protected]"}],
"date": "2026-03-28T10:30:00-04:00",
"unread": true,
"snippet": "Hello from Sarah..."
}
]The difference matters for agent reliability. An agent parsing Gmail API responses needs custom error handling for malformed MIME, missing headers, and nested multipart boundaries. An agent parsing Nylas CLI output just calls json.loads() on the stdout string.
Setup time comparison
Setup time varies by a factor of 120x across the six options. The Gmail API takes 1-4 hours for initial configuration (and up to 6 weeks if your OAuth consent screen requires Google's external app review). Microsoft Graph takes 1-3 hours for Azure AD registration and MSAL configuration. SendGrid can be running in 15 minutes. Direct IMAP needs 30-60 minutes of per-provider credential setup and MIME parser work. The Nylas CLI takes roughly 2 minutes from install to first API call.
| Option | Estimated setup time | What's involved |
|---|---|---|
| Gmail API | 1-4 hours (days if external review) | GCP project, OAuth consent, credentials, token storage |
| Graph API | 1-3 hours | Azure AD app, MSAL config, permission grants |
| SendGrid | 15 minutes | Account creation, API key, domain verification |
| IMAP | 30-60 minutes | Per-provider credentials, MIME parser, connection handling |
| Nylas CLI | 2 minutes | brew install + nylas auth login |
Frequently asked questions
These are the most common questions developers ask when choosing an email API for AI agents. The answers cover combining multiple APIs, pricing across all 6 options, data storage behavior, and migration paths between providers.
Can I use multiple options together?
Yes. Many teams use SendGrid for outbound transactional email and Nylas CLI for agent inbox access. The tools don't conflict. Use whatever fits each use case.
What about the cost of each option?
Gmail API and Graph API are free (you're paying for Workspace or M365 already). SendGrid's free tier covers 100 emails/day. Mailgun is free for the first month, then starts at $0.80/1,000 emails. IMAP is free (it's a protocol). Nylas CLI is free and open-source (MIT license).
Does Nylas CLI store my email data?
The CLI authenticates via OAuth and accesses email through the Nylas API. Messages aren't stored locally beyond the JSON output of individual commands. Token credentials are stored in your system keychain.
Can I switch from Gmail API to Nylas CLI without changing my agent's code?
If your agent calls the Gmail API directly, you'll need to swap the tool definitions. If your agent uses subprocess calls, replace the Gmail SDK code with nylas email list --json and nylas email send commands. The MCP pattern requires the least agent-side code changes since it's tool-definition-free.
Next steps
- Give AI agents email access via MCP -- set up the MCP server for Claude, Cursor, or VS Code
- Best email infrastructure for AI agents -- choose the stack for reads, sends, audits, calendar, and scale
- Google Workspace MCP for AI agents -- compare Google's MCP preview with a multi-provider CLI workflow
- Give your AI coding agent an email address -- connect Claude Code, Cursor, Codex CLI, and OpenClaw
- Build an AI email triage agent -- put your chosen API to work classifying and responding to email
- Nylas CLI vs Recall.ai -- email/calendar vs meeting recordings for agents
- Build an LLM agent with email tools -- subprocess patterns for custom agents
- Why Gmail API breaks AI agents -- deep dive into Gmail API friction points
- Full command reference -- every flag, subcommand, and example
- Model Context Protocol specification — the wire format any of these APIs has to translate into for an agent host