Guide
Email Forwarding Rules: API Guide
Three APIs let you create email routing rules programmatically: Gmail's users.settings.filters, Microsoft Graph's mailFolders/inbox/messageRules, and the Nylas CLI's nylas agent rule create. Each takes a different approach to conditions, actions, and provider scope. This guide compares all three with working code.
Written by Hazik Director of Product Management
Command references used in this guide: nylas agent rule create, nylas agent rule list, and nylas agent policy create.
What are email forwarding rules and how do APIs expose them?
Email forwarding rules are server-side instructions that automatically route, label, archive, or delete incoming messages based on conditions like sender, subject, or header values. Gmail calls them “filters.” Microsoft calls them “inbox rules” or “message rules.” Both providers expose them through REST APIs that let you create, list, update, and delete rules programmatically. Gmail supports up to 1,000 filters per account. Exchange Online limits inbox rules by mailbox storage quota, not a fixed count.
The use cases are straightforward: auto-forward invoices to your finance team, archive newsletters, apply labels to messages from specific domains, or block unwanted senders. AI agents use rules to pre-filter noise before triage, route high-priority messages to a human queue, and enforce outbound send policies. Each API handles this differently, and none of them works across providers without custom code.
How do you create Gmail filters with the API?
Gmail's filters API lives at users.settings.filters in the Gmail API. Each filter has a criteria object (matching conditions) and an action object (what to do). The criteria use a subset of Gmail search syntax: from, to, subject, query, hasAttachment, and size fields. Actions include addLabelIds, removeLabelIds, forward, and shouldArchive. The API requires the https://www.googleapis.com/auth/gmail.settings.basic OAuth scope.
The example below creates a filter that forwards all emails from billing@stripe.com to your finance team and skips the inbox. This requires a verified forwarding address (Gmail forces a confirmation email before it allows forwarding). According to Google's filters API reference, each filters.create call consumes quota units from your daily budget.
# Gmail API — create a filter (Python)
from googleapiclient.discovery import build
from google.oauth2.credentials import Credentials
creds = Credentials.from_authorized_user_file("token.json")
service = build("gmail", "v1", credentials=creds)
filter_body = {
"criteria": {
"from": "billing@stripe.com"
},
"action": {
"forward": "finance@yourcompany.com",
"removeLabelIds": ["INBOX"]
}
}
result = service.users().settings().filters().create(
userId="me", body=filter_body
).execute()
print(f"Filter created: {result['id']}")
# List all existing filters
filters = service.users().settings().filters().list(
userId="me"
).execute()
print(f"Total filters: {len(filters.get('filter', []))}")The main limitation: Gmail filters only work on Gmail accounts. You can't use this API to create rules on Outlook, Yahoo, or Exchange mailboxes. The filter also can't match on custom headers, message size in bytes (only approximate ranges), or thread membership. For more complex routing, you need to poll with messages.list and apply logic in your application code.
How do you create Outlook inbox rules with Graph API?
Microsoft Graph exposes inbox rules at /me/mailFolders/inbox/messageRules. Each rule has a conditions object, an actions object, and optional exceptions for override conditions. Graph rules support 30+ condition types, including senderContains, subjectContains, importance, hasAttachments, headerContains, and bodyContains. Actions include forwardTo, moveToFolder, delete, markAsRead, and stopProcessingRules.
The example below creates an Outlook inbox rule that moves emails containing “invoice” in the subject to a folder called “Finance” and marks them as read. This requires the MailboxSettings.ReadWrite delegated permission. The Graph API applies standard throttling to messageRules calls: 10,000 requests per 10 minutes per app per mailbox, according to the Graph throttling documentation.
# Microsoft Graph — create an inbox rule (Python)
import requests
access_token = "your-access-token" # From MSAL auth flow
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
# First, get the folder ID for "Finance"
folders = requests.get(
"https://graph.microsoft.com/v1.0/me/mailFolders",
headers=headers
).json()
finance_id = next(
f["id"] for f in folders["value"]
if f["displayName"] == "Finance"
)
# Create the inbox rule
rule = {
"displayName": "Move invoices to Finance",
"sequence": 1,
"isEnabled": True,
"conditions": {
"subjectContains": ["invoice"]
},
"actions": {
"moveToFolder": finance_id,
"markAsRead": True,
"stopProcessingRules": True
}
}
result = requests.post(
"https://graph.microsoft.com/v1.0/me/mailFolders/inbox/messageRules",
headers=headers,
json=rule
)
print(f"Rule created: {result.json()['id']}")Graph inbox rules are more expressive than Gmail filters. The headerContains condition matches arbitrary email headers, and bodyContains searches message content. The Graph messageRule resource documentation lists the full set of conditions and actions available. But like Gmail, these rules only work on Microsoft 365 and Exchange mailboxes. Creating the same routing logic across both providers requires maintaining two separate API integrations.
How do you create email rules with the CLI?
The nylas agent rule create command creates server-side email rules that work across all 6 supported providers. Rules attach to a policy (created with nylas agent policy create). You can specify conditions and actions inline with --name, --condition, and --action flags, or pass a full JSON definition with --data-file rule.json. The command creates the rule via the Nylas API, so it persists server-side.
The example below creates a policy, then adds two rules: one that blocks emails from a specific domain, and one that auto-archives messages matching a subject pattern. The CLI handles the API calls, OAuth token refresh, and JSON serialization. Setup takes under 2 minutes if you've already run nylas init.
# Create a policy for your email rules
POLICY_ID=$(nylas agent policy create --name "Inbox Routing" --json | jq -r .id)
# Rule 1: Block emails from a spam domain (using a JSON rule file)
cat > block-spam.json <<'EOF'
{
"name": "Block spam domain",
"condition": { "field": "from.domain", "operator": "is", "value": "spammer.example.com" },
"action": { "type": "block" }
}
EOF
nylas agent rule create --data-file block-spam.json
# Rule 2: Archive and mark-read all newsletter emails
cat > archive-newsletters.json <<'EOF'
{
"name": "Archive newsletters",
"condition": { "field": "subject", "operator": "contains", "value": "newsletter" },
"actions": [{ "type": "archive" }, { "type": "mark_as_read" }]
}
EOF
nylas agent rule create --data-file archive-newsletters.json
# List all rules
nylas agent rule list --jsonThe key difference from Gmail and Graph APIs: one command creates rules that apply regardless of the user's email provider. The same rule definition works for Gmail, Outlook, Yahoo, iCloud, Exchange, and IMAP accounts. You don't write provider-specific code or handle different authentication flows.
How do the three approaches compare?
The table below compares all three rule systems across 8 dimensions that affect how you build automated email routing. Gmail filters are the simplest but least expressive. Graph rules offer the most condition types. CLI rules trade condition depth for provider portability.
| Feature | Gmail Filters API | Graph Inbox Rules | Nylas CLI Rules |
|---|---|---|---|
| Provider support | Gmail only | Outlook / Exchange only | Gmail, Outlook, Exchange, Yahoo, iCloud, IMAP |
| Max rules | 1,000 per account | Limited by mailbox quota | Per policy (no documented limit) |
| Condition types | ~8 (from, to, subject, query, size, attachment) | 30+ (headers, body, importance, categories) | Domain, sender, subject, trigger direction |
| Actions | Label, archive, forward, delete, star | Move, forward, delete, mark read, flag, redirect, copy | Block, archive, mark read |
| Auth required | OAuth 2.0 + gmail.settings.basic scope | OAuth 2.0 + MailboxSettings.ReadWrite | Nylas API key + grant |
| Setup time | 30+ min (GCP project, consent screen) | 30+ min (Azure AD app, MSAL) | ~2 min (nylas init) |
| Custom headers | No | Yes (headerContains) | No |
| Exception handling | No (separate negated filter) | Yes (exceptions object) | Via separate priority rules |
Which approach should you choose?
The decision depends on provider scope and condition complexity. If your users are all on Gmail and you need filter rules with the full Gmail search syntax, the Gmail Filters API gives you the most direct integration. If your users are on Microsoft 365 and you need body content matching or custom header conditions, Graph inbox rules are the most expressive option. If your users span multiple providers, the CLI creates rules without provider-specific code.
- Gmail-only, complex conditions: Gmail Filters API. Supports up to 1,000 filters and uses Gmail's own search syntax in the
queryfield for advanced matching. - Outlook-only, header or body matching: Graph messageRules. The 30+ condition types and exceptions object handle scenarios no other API supports.
- Multi-provider, AI agent guardrails: CLI rules. One
nylas agent rule createcommand creates blocking, archiving, or routing rules that work across all 6 providers. Pair withnylas agent policy createfor agent containment. - Forwarding to a webhook: None of these create webhook-based forwarding directly. Use inbound email webhooks instead, where the provider pushes new messages to your HTTP endpoint.
For AI agent safety, rules and policies prevent an agent from sending to unauthorized domains or responding to prompt injection attempts. The agent containment guide covers the full pattern for blocking exfiltration and auto-reply loops.
Next steps
- Stop your AI agent from going rogue — block outbound threats with policy rules and containment patterns
- Search email from terminal — compare Gmail search operators, Graph $filter, IMAP SEARCH, and CLI search
- Gmail API search query examples — full Gmail search syntax reference with code
- Full command reference — every flag and subcommand documented