Gmail
Access the Gmail API with managed OAuth authentication. Read, send, and manage emails, threads, labels, and drafts.
Quick Start
CLI:
maton google-mail message list -L 10
maton api '/google-mail/gmail/v1/users/me/messages?maxResults=10'
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/google-mail/gmail/v1/users/me/messages?maxResults=10')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Base URL
https://api.maton.ai/google-mail/{native-api-path}
Maton proxies requests to gmail.googleapis.com and automatically injects your OAuth token.
Installation
NPM:
npm install -g @maton/cli
Homebrew:
brew install maton-ai/cli/maton
Authentication
CLI:
maton login # Opens browser for API key
maton login --interactive # Skip browser, paste API key directly
maton whoami # Show current auth state
Manual:
- Sign in or create an account at maton.ai
- Go to maton.ai/settings
- Copy your API key
- Set your API key as
MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Connection Management
Manage your Google OAuth connections at https://api.maton.ai.
List Connections
CLI:
maton connection list google-mail --status ACTIVE
maton api -X GET /connections -f app=google-mail -f status=ACTIVE
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=google-mail&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Create Connection
CLI:
maton connection create google-mail
maton api /connections -f app=google-mail
Python:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'google-mail'}).encode()
req = urllib.request.Request('https://api.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Get Connection
CLI:
maton connection view {connection_id}
maton api /connections/{connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"connection": {
"connection_id": "{connection_id}",
"status": "ACTIVE",
"creation_time": "2025-12-08T07:20:53.488460Z",
"last_updated_time": "2026-01-31T20:03:32.593153Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "google-mail",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
Delete Connection
CLI:
maton connection delete {connection_id}
maton api -X DELETE /connections/{connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Specifying Connection
If you have multiple Gmail connections, specify which one to use:
CLI:
maton google-mail message list -L 10 --connection {connection_id}
maton api /google-mail/gmail/v1/users/me/messages --connection {connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/google-mail/gmail/v1/users/me/messages')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple connections, always specify the connection to ensure requests go to the intended account.
Security & Permissions
- Access is scoped to messages, threads, labels, drafts, and email sending within the connected Gmail account.
- All write operations require explicit user approval. Before executing any create, update, or delete call, confirm the target resource and intended effect with the user.
API Reference
List Messages
GET /google-mail/gmail/v1/users/me/messages?maxResults=10
Example:
maton google-mail message list -L 10
With query filter:
GET /google-mail/gmail/v1/users/me/messages?q=is:unread&maxResults=10
Example:
maton google-mail message list --query 'is:unread' -L 10
Get Message
GET /google-mail/gmail/v1/users/me/messages/{messageId}
Example:
maton google-mail message view {messageId} --headers
With metadata only:
GET /google-mail/gmail/v1/users/me/messages/{messageId}?format=metadata&metadataHeaders=From&metadataHeaders=Subject&metadataHeaders=Date
Example:
maton google-mail message view {messageId} --fetch-format metadata --metadata-header From,Subject,Date
Send Message
POST /google-mail/gmail/v1/users/me/messages/send
Content-Type: application/json
{
"raw": "BASE64_ENCODED_EMAIL"
}
Example:
maton google-mail message send --to [email protected] --subject 'Hello' --body 'Hi there!'
Reply to Message
maton google-mail message reply {messageId} --body 'Thanks!'
Forward Message
maton google-mail message forward {messageId} --to [email protected] --body 'FYI'
List Labels
GET /google-mail/gmail/v1/users/me/labels
Example:
maton google-mail label list
List Threads
GET /google-mail/gmail/v1/users/me/threads?maxResults=10
Example:
maton google-mail thread list -L 10
Get Thread
GET /google-mail/gmail/v1/users/me/threads/{threadId}
Example:
maton google-mail thread view {threadId}
Modify Message Labels
POST /google-mail/gmail/v1/users/me/messages/{messageId}/modify
Content-Type: application/json
{
"addLabelIds": ["STARRED"],
"removeLabelIds": ["UNREAD"]
}
Example:
maton google-mail message modify {messageId} --add-label STARRED --remove-label UNREAD
Trash Message
POST /google-mail/gmail/v1/users/me/messages/{messageId}/trash
Example:
maton google-mail message trash {messageId}
Create Draft
POST /google-mail/gmail/v1/users/me/drafts
Content-Type: application/json
{
"message": {
"raw": "BASE64URL_ENCODED_EMAIL"
}
}
Example:
maton google-mail draft create --to [email protected] --subject 'Hello' --body 'Draft content here'
Send Draft
POST /google-mail/gmail/v1/users/me/drafts/send
Content-Type: application/json
{
"id": "{draftId}"
}
Example:
maton google-mail draft send {draftId}
Get Profile
GET /google-mail/gmail/v1/users/me/profile
Query Operators
Use in the q parameter:
is:unread- Unread messagesis:starred- Starred messagesfrom:[email protected]- From specific senderto:[email protected]- To specific recipientsubject:keyword- Subject contains keywordafter:2024/01/01- After datebefore:2024/12/31- Before datehas:attachment- Has attachments
Code Examples
CLI
# List unread messages with headers
maton google-mail message list --hydrate
# Filter with jq — e.g., only messages from a specific sender
maton google-mail message list -L 20 --query 'from:[email protected]' --json --jq '.messages[].id'
# List all threads with pagination
maton google-mail thread list --paginate --query 'newer_than:7d'
JavaScript
const response = await fetch(
'https://api.maton.ai/google-mail/gmail/v1/users/me/messages?maxResults=10',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
Python
import os
import requests
response = requests.get(
'https://api.maton.ai/google-mail/gmail/v1/users/me/messages',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'},
params={'maxResults': 10, 'q': 'is:unread'}
)
Notes
- Use
meas userId for the authenticated user - Message body is base64url encoded in the
rawfield - Common labels:
INBOX,SENT,DRAFT,STARRED,UNREAD,TRASH - IMPORTANT: When using curl commands, use
curl -gwhen URLs contain brackets (fields[],sort[],records[]) to disable glob parsing - IMPORTANT: When piping curl output to
jqor other commands, environment variables like$MATON_API_KEYmay not expand correctly in some shell environments. You may get "Invalid API key" errors when piping.
Error Handling
| Status | Meaning |
|--------|---------|
| 400 | Missing Gmail connection |
| 401 | Invalid or missing Maton API key |
| 429 | Rate limited (10 req/sec per account) |
| 4xx/5xx | Passthrough error from Gmail API |
Troubleshooting: API Key Issues
CLI:
- Check your auth state:
maton whoami
- Verify the API key is valid by listing connections:
maton connection list
Manual:
- Check that the
MATON_API_KEYenvironment variable is set:
echo $MATON_API_KEY
- Verify the API key is valid by listing connections:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Troubleshooting: Invalid App Name
- Ensure your URL path starts with
google-mail. For example:
- Correct:
https://api.maton.ai/google-mail/gmail/v1/users/me/messages - Incorrect:
https://api.maton.ai/gmail/v1/users/me/messages