zoho-mailZoho Mail API integration with managed OAuth. Send, receive, and manage emails, folders, and labels. Use this skill when users want to send emails, read messages, manage folders, or work with email labels in Zoho Mail. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). Requires network access and valid Maton API key.
Install via ClawdBot CLI:
clawdbot install byungkyu/zoho-mailAccess the Zoho Mail API with managed OAuth authentication. Send, receive, search, and manage emails with full folder and label management.
# List all accounts
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/zoho-mail/api/accounts')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
https://gateway.maton.ai/zoho-mail/{native-api-path}
Replace {native-api-path} with the actual Zoho Mail API endpoint path. The gateway proxies requests to mail.zoho.com and automatically injects your OAuth token.
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Manage your Zoho Mail OAuth connections at https://ctrl.maton.ai.
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=zoho-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
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'zoho-mail'}).encode()
req = urllib.request.Request('https://ctrl.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
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.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": "21fd90f9-5935-43cd-b6c8-bde9d915ca80",
"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": "zoho-mail",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.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
If you have multiple Zoho Mail connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/zoho-mail/api/accounts')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '21fd90f9-5935-43cd-b6c8-bde9d915ca80')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If omitted, the gateway uses the default (oldest) active connection.
Retrieve all mail accounts for the authenticated user.
GET /zoho-mail/api/accounts
Example:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/zoho-mail/api/accounts')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
GET /zoho-mail/api/accounts/{accountId}
GET /zoho-mail/api/accounts/{accountId}/folders
Example:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/zoho-mail/api/accounts/{accountId}/folders')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"status": {
"code": 200,
"description": "success"
},
"data": [
{
"folderId": "1367000000000008014",
"folderName": "Inbox",
"folderType": "Inbox",
"path": "/Inbox",
"imapAccess": true,
"isArchived": 0,
"URI": "https://mail.zoho.com/api/accounts/1367000000000008002/folders/1367000000000008014"
},
{
"folderId": "1367000000000008016",
"folderName": "Drafts",
"folderType": "Drafts",
"path": "/Drafts",
"imapAccess": true,
"isArchived": 0
}
]
}
POST /zoho-mail/api/accounts/{accountId}/folders
Content-Type: application/json
{
"folderName": "My Custom Folder"
}
PUT /zoho-mail/api/accounts/{accountId}/folders/{folderId}
Content-Type: application/json
{
"folderName": "Renamed Folder"
}
DELETE /zoho-mail/api/accounts/{accountId}/folders/{folderId}
GET /zoho-mail/api/accounts/{accountId}/labels
Example:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/zoho-mail/api/accounts/{accountId}/labels')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
POST /zoho-mail/api/accounts/{accountId}/labels
Content-Type: application/json
{
"labelName": "Important"
}
PUT /zoho-mail/api/accounts/{accountId}/labels/{labelId}
Content-Type: application/json
{
"labelName": "Updated Label"
}
DELETE /zoho-mail/api/accounts/{accountId}/labels/{labelId}
GET /zoho-mail/api/accounts/{accountId}/messages/view?folderId={folderId}
Query Parameters:
| Parameter | Type | Description |
|-----------|------|-------------|
| folderId | long | Folder ID to list messages from |
| limit | integer | Number of messages to return (default: 50) |
| start | integer | Offset for pagination |
| sortBy | string | Sort field (e.g., date) |
| sortOrder | boolean | true for ascending, false for descending |
Example:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/zoho-mail/api/accounts/{accountId}/messages/view?folderId={folderId}&limit=10')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
GET /zoho-mail/api/accounts/{accountId}/messages/search?searchKey={query}
Query Parameters:
| Parameter | Type | Description |
|-----------|------|-------------|
| searchKey | string | Search query |
| limit | integer | Number of results to return |
| start | integer | Offset for pagination |
Example:
python <<'EOF'
import urllib.request, os, json
import urllib.parse
query = urllib.parse.quote('from:sender@example.com')
req = urllib.request.Request(f'https://gateway.maton.ai/zoho-mail/api/accounts/{{accountId}}/messages/search?searchKey={query}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
GET /zoho-mail/api/accounts/{accountId}/folders/{folderId}/messages/{messageId}/content
Example:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/zoho-mail/api/accounts/{accountId}/folders/{folderId}/messages/{messageId}/content')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
GET /zoho-mail/api/accounts/{accountId}/folders/{folderId}/messages/{messageId}/header
GET /zoho-mail/api/accounts/{accountId}/folders/{folderId}/messages/{messageId}/details
GET /zoho-mail/api/accounts/{accountId}/messages/{messageId}/originalmessage
POST /zoho-mail/api/accounts/{accountId}/messages
Content-Type: application/json
{
"fromAddress": "sender@yourdomain.com",
"toAddress": "recipient@example.com",
"subject": "Email Subject",
"content": "Email body content",
"mailFormat": "html"
}
Request Body Fields:
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| fromAddress | string | Yes | Sender's email address |
| toAddress | string | Yes | Recipient's email address |
| subject | string | Yes | Email subject |
| content | string | Yes | Email body content |
| ccAddress | string | No | CC recipient |
| bccAddress | string | No | BCC recipient |
| mailFormat | string | No | html or plaintext (default: html) |
| askReceipt | string | No | yes or no for read receipt |
| encoding | string | No | Character encoding (default: UTF-8) |
Example - Send Email:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({
"fromAddress": "sender@yourdomain.com",
"toAddress": "recipient@example.com",
"subject": "Hello from Zoho Mail API",
"content": "<h1>Hello!</h1><p>This is a test email.</p>",
"mailFormat": "html"
}).encode()
req = urllib.request.Request('https://gateway.maton.ai/zoho-mail/api/accounts/{accountId}/messages', 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
Scheduling Parameters (Optional):
| Field | Type | Description |
|-------|------|-------------|
| isSchedule | boolean | Enable scheduling |
| scheduleType | integer | 1-5 for preset times; 6 for custom |
| timeZone | string | Required if scheduleType=6 (e.g., GMT 5:30) |
| scheduleTime | string | Required if scheduleType=6 (format: MM/DD/YYYY HH:MM:SS) |
POST /zoho-mail/api/accounts/{accountId}/messages/{messageId}
Content-Type: application/json
{
"fromAddress": "sender@yourdomain.com",
"toAddress": "recipient@example.com",
"subject": "Re: Original Subject",
"content": "Reply content"
}
POST /zoho-mail/api/accounts/{accountId}/messages
Content-Type: application/json
{
"fromAddress": "sender@yourdomain.com",
"toAddress": "recipient@example.com",
"subject": "Draft Subject",
"content": "Draft content",
"mode": "draft"
}
PUT /zoho-mail/api/accounts/{accountId}/updatemessage
Content-Type: application/json
{
"messageId": ["messageId1", "messageId2"],
"folderId": "folderId",
"mode": "markAsRead"
}
Mode Options:
markAsRead - Mark messages as readmarkAsUnread - Mark messages as unreadmoveMessage - Move messages (requires destfolderId)flag - Set flag (requires flagid: 1-4)archive - Archive messagesunArchive - Unarchive messagesspam - Mark as spamnotSpam - Mark as not spamExample - Mark as Read:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({
"messageId": ["1234567890123456789"],
"folderId": "9876543210987654321",
"mode": "markAsRead"
}).encode()
req = urllib.request.Request('https://gateway.maton.ai/zoho-mail/api/accounts/{accountId}/updatemessage', data=data, method='PUT')
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
DELETE /zoho-mail/api/accounts/{accountId}/folders/{folderId}/messages/{messageId}
POST /zoho-mail/api/accounts/{accountId}/messages/attachments
Content-Type: multipart/form-data
GET /zoho-mail/api/accounts/{accountId}/folders/{folderId}/messages/{messageId}/attachmentinfo
GET /zoho-mail/api/accounts/{accountId}/folders/{folderId}/messages/{messageId}/attachments/{attachmentId}
Zoho Mail uses offset-based pagination:
GET /zoho-mail/api/accounts/{accountId}/messages/view?folderId={folderId}&start=0&limit=50
start: Offset index (default: 0)limit: Number of records to return (default: 50)For subsequent pages, increment start by limit:
start=0&limit=50start=50&limit=50start=100&limit=50const response = await fetch(
'https://gateway.maton.ai/zoho-mail/api/accounts',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const data = await response.json();
import os
import requests
response = requests.get(
'https://gateway.maton.ai/zoho-mail/api/accounts',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
)
data = response.json()
/api/accounts to get your account IDfromAddress must be associated with the authenticated accountINVALID_OAUTHSCOPE error, contact Maton support at support@maton.ai with the specific operations/APIs you need and your use-casecurl -g when URLs contain brackets to disable glob parsingjq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments| Status | Meaning |
|--------|---------|
| 400 | Missing Zoho Mail connection or invalid request |
| 401 | Invalid or missing Maton API key |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Zoho Mail API |
MATON_API_KEY environment variable is set:echo $MATON_API_KEY
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.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
zoho-mail. For example:https://gateway.maton.ai/zoho-mail/api/accountshttps://gateway.maton.ai/api/accountsGenerated Feb 23, 2026
Businesses can use this skill to automatically send personalized email replies to customer inquiries. It integrates with CRM systems to fetch customer details and draft responses, ensuring timely and consistent communication. This reduces manual effort and improves response times in support workflows.
Small businesses can manage email marketing campaigns by sending bulk emails, tracking opens, and organizing contacts into folders. It allows segmentation of email lists and scheduling of follow-ups, helping to nurture leads and drive sales without complex tools.
Teams can use this skill to share project updates, documents, and feedback through email threads. It enables automated folder creation for different projects, keeping communications organized and accessible, which streamlines collaboration in remote or hybrid work environments.
Companies can automate the sending of invoices and payment reminders to clients. The skill can draft emails with attachments, schedule them based on due dates, and categorize responses in folders for accounting purposes, improving cash flow management.
Organizations can handle event registrations by sending automated confirmation emails, updates, and post-event surveys. It manages attendee lists in folders and sends personalized messages, enhancing engagement and reducing administrative overhead for events.
Offer a subscription-based service that uses this skill to provide automated email workflows for businesses. Charge monthly fees based on usage tiers, such as number of emails sent or advanced features like analytics. This model generates recurring revenue from SMEs seeking efficiency.
Develop a freemium app that allows individual users to manage emails for free with basic features, while charging for premium capabilities like bulk sending or API access. Monetize through upgrades and in-app purchases, targeting professionals and small teams.
Provide consulting services to integrate this skill into existing enterprise systems, such as ERP or CRM platforms. Charge for setup, customization, and ongoing support, leveraging the skill's API for tailored email solutions in large organizations.
💬 Integration Tip
Ensure the MATON_API_KEY is securely stored in environment variables and test connection management via the control panel before deploying in production workflows.
Captures learnings, errors, and corrections to enable continuous improvement. Use when: (1) A command or operation fails unexpectedly, (2) User corrects Clau...
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
Search and analyze your own session logs (older/parent conversations) using jq.
Typed knowledge graph for structured agent memory and composable skills. Use when creating/querying entities (Person, Project, Task, Event, Document), linking related objects, enforcing constraints, planning multi-step actions as graph transformations, or when skills need to share state. Trigger on "remember", "what do I know about", "link X to Y", "show dependencies", entity CRUD, or cross-skill data access.
Ultimate AI agent memory system for Cursor, Claude, ChatGPT & Copilot. WAL protocol + vector search + git-notes + cloud backup. Never lose context again. Vibe-coding ready.
Headless browser automation CLI optimized for AI agents with accessibility tree snapshots and ref-based element selection