Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
Zoho Calendar API integration with managed OAuth. Manage calendars and events with full scheduling capabilities. Use this skill when users want to read, create, update, or delete calendar events, manage calendars, or schedule meetings. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). Requires network access and valid Maton API key.
Zoho Calendar API integration with managed OAuth. Manage calendars and events with full scheduling capabilities. Use this skill when users want to read, create, update, or delete calendar events, manage calendars, or schedule meetings. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). Requires network access and valid Maton API key.
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete.
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run.
Access the Zoho Calendar API with managed OAuth authentication. Manage calendars and events with full CRUD operations, including recurring events and attendee management.
# List calendars python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/zoho-calendar/api/v1/calendars') 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-calendar/api/v1/{endpoint} The gateway proxies requests to calendar.zoho.com/api/v1 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"
Sign in or create an account at maton.ai Go to maton.ai/settings Copy your API key
Manage your Zoho Calendar 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-calendar&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-calendar'}).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-calendar", "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 Calendar 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-calendar/api/v1/calendars') 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.
List Calendars GET /zoho-calendar/api/v1/calendars Example: python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/zoho-calendar/api/v1/calendars') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF Response: { "calendars": [ { "uid": "fda9b0b4ad834257b622cb3dc3555727", "name": "My Calendar", "color": "#8cbf40", "textcolor": "#FFFFFF", "timezone": "PST", "isdefault": true, "category": "own", "privilege": "owner" } ] } Get Calendar Details GET /zoho-calendar/api/v1/calendars/{calendar_uid} Example: python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/zoho-calendar/api/v1/calendars/fda9b0b4ad834257b622cb3dc3555727') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF Create Calendar POST /zoho-calendar/api/v1/calendars?calendarData={json} Required Fields: name - Calendar name (max 50 characters) color - Hex color code (e.g., #FF5733) Optional Fields: textcolor - Text color hex code description - Calendar description (max 1000 characters) timezone - Calendar timezone include_infreebusy - Show as Busy/Free (boolean) public - Visibility level (disable, freebusy, or view) Example: python <<'EOF' import urllib.request, os, json, urllib.parse calendarData = { "name": "Work Calendar", "color": "#FF5733", "textcolor": "#FFFFFF", "description": "My work calendar" } url = f'https://gateway.maton.ai/zoho-calendar/api/v1/calendars?calendarData={urllib.parse.quote(json.dumps(calendarData))}' req = urllib.request.Request(url, method='POST') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF Response: { "calendars": [ { "uid": "86fb9745076e4672ae4324f05e1f5393", "name": "Work Calendar", "color": "#FF5733", "textcolor": "#FFFFFF" } ] } Delete Calendar DELETE /zoho-calendar/api/v1/calendars/{calendar_uid} Example: python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/zoho-calendar/api/v1/calendars/86fb9745076e4672ae4324f05e1f5393', 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 Response: { "calendars": [ { "uid": "86fb9745076e4672ae4324f05e1f5393", "calstatus": "deleted" } ] }
List Events GET /zoho-calendar/api/v1/calendars/{calendar_uid}/events?range={json} Query Parameters: ParameterTypeDescriptionrangeJSON objectRequired. Start and end dates in format {"start":"yyyyMMdd","end":"yyyyMMdd"}. Max 31-day span.byinstancebooleanIf true, recurring event instances are returned separatelytimezonestringTimezone for datetime values Example: python <<'EOF' import urllib.request, os, json, urllib.parse from datetime import datetime, timedelta today = datetime.now() end_date = today + timedelta(days=7) range_param = json.dumps({ "start": today.strftime("%Y%m%d"), "end": end_date.strftime("%Y%m%d") }) url = f'https://gateway.maton.ai/zoho-calendar/api/v1/calendars/fda9b0b4ad834257b622cb3dc3555727/events?range={urllib.parse.quote(range_param)}' req = urllib.request.Request(url) req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF Response: { "events": [ { "uid": "c63e8b9fcb3e48c2a00b16729932d636@zoho.com", "title": "Team Meeting", "dateandtime": { "timezone": "America/Los_Angeles", "start": "20260206T100000-0800", "end": "20260206T110000-0800" }, "isallday": false, "etag": "1770368451507", "organizer": "user@example.com" } ] } Get Event Details GET /zoho-calendar/api/v1/calendars/{calendar_uid}/events/{event_uid} Example: python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/zoho-calendar/api/v1/calendars/fda9b0b4ad834257b622cb3dc3555727/events/c63e8b9fcb3e48c2a00b16729932d636@zoho.com') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF Create Event POST /zoho-calendar/api/v1/calendars/{calendar_uid}/events?eventdata={json} Required Fields (in eventdata): dateandtime - Object with start, end, and optionally timezone Format: yyyyMMdd'T'HHmmss'Z' (GMT) for timed events Format: yyyyMMdd for all-day events Optional Fields: title - Event name description - Event details (max 10,000 characters) location - Event location (max 255 characters) isallday - Boolean for all-day events isprivate - Boolean to hide details from non-delegates color - Hex color code attendees - Array of attendee objects reminders - Array of reminder objects rrule - Recurrence rule string (e.g., FREQ=DAILY;COUNT=5) Example: python <<'EOF' import urllib.request, os, json, urllib.parse from datetime import datetime, timedelta start_time = datetime.utcnow() + timedelta(hours=1) end_time = start_time + timedelta(hours=1) eventdata = { "title": "Team Meeting", "dateandtime": { "timezone": "America/Los_Angeles", "start": start_time.strftime("%Y%m%dT%H%M%SZ"), "end": end_time.strftime("%Y%m%dT%H%M%SZ") }, "description": "Weekly team sync", "location": "Conference Room A" } url = f'https://gateway.maton.ai/zoho-calendar/api/v1/calendars/fda9b0b4ad834257b622cb3dc3555727/events?eventdata={urllib.parse.quote(json.dumps(eventdata))}' req = urllib.request.Request(url, method='POST') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF Response: { "events": [ { "uid": "c63e8b9fcb3e48c2a00b16729932d636@zoho.com", "title": "Team Meeting", "dateandtime": { "timezone": "America/Los_Angeles", "start": "20260206T100000-0800", "end": "20260206T110000-0800" }, "etag": "1770368451507", "estatus": "added" } ] } Update Event PUT /zoho-calendar/api/v1/calendars/{calendar_uid}/events/{event_uid}?eventdata={json} Required Fields: dateandtime - Start and end times etag - Current etag value (from Get Event Details) Optional Fields: Same as Create Event Example: python <<'EOF' import urllib.request, os, json, urllib.parse from datetime import datetime, timedelta start_time = datetime.utcnow() + timedelta(hours=2) end_time = start_time + timedelta(hours=1) eventdata = { "title": "Updated Team Meeting", "dateandtime": { "timezone": "America/Los_Angeles", "start": start_time.strftime("%Y%m%dT%H%M%SZ"), "end": end_time.strftime("%Y%m%dT%H%M%SZ") }, "etag": 1770368451507 } url = f'https://gateway.maton.ai/zoho-calendar/api/v1/calendars/fda9b0b4ad834257b622cb3dc3555727/events/c63e8b9fcb3e48c2a00b16729932d636@zoho.com?eventdata={urllib.parse.quote(json.dumps(eventdata))}' req = urllib.request.Request(url, method='PUT') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF Delete Event DELETE /zoho-calendar/api/v1/calendars/{calendar_uid}/events/{event_uid} Required Header: etag - Current etag value of the event Example: python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/zoho-calendar/api/v1/calendars/fda9b0b4ad834257b622cb3dc3555727/events/c63e8b9fcb3e48c2a00b16729932d636@zoho.com', method='DELETE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('etag', '1770368451507') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF Response: { "events": [ { "uid": "c63e8b9fcb3e48c2a00b16729932d636@zoho.com", "estatus": "deleted", "caluid": "fda9b0b4ad834257b622cb3dc3555727" } ] }
When creating or updating events, include attendees: { "attendees": [ { "email": "user@example.com", "permission": 1, "attendance": 1 } ] } Permission levels: 0 (Guest), 1 (View), 2 (Invite), 3 (Edit) Attendance: 0 (Non-participant), 1 (Required), 2 (Optional)
{ "reminders": [ { "action": "popup", "minutes": 30 }, { "action": "email", "minutes": 60 } ] } Actions: email, popup, notification
Use the rrule field with iCalendar RRULE format: { "rrule": "FREQ=DAILY;COUNT=5;INTERVAL=1" } Examples: Daily for 5 days: FREQ=DAILY;COUNT=5;INTERVAL=1 Weekly on Mon/Tue: FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,TU;UNTIL=20250817T064600Z Monthly last Tuesday: FREQ=MONTHLY;INTERVAL=1;BYDAY=TU;BYSETPOS=-1;COUNT=2
const response = await fetch( 'https://gateway.maton.ai/zoho-calendar/api/v1/calendars', { 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-calendar/api/v1/calendars', headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'} ) data = response.json()
Event and calendar data is passed as JSON in the eventdata or calendarData query parameter Date/time format for events: yyyyMMdd'T'HHmmss'Z' (GMT) or yyyyMMdd for all-day events The range parameter for listing events cannot exceed 31 days The etag is required for update and delete operations - always get the latest etag before modifying For delete operations, the etag must be passed as a header, not a query parameter IMPORTANT: When using curl commands, use curl -g when URLs contain brackets to disable glob parsing IMPORTANT: When piping curl output to jq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments
StatusMeaning400Missing Zoho Calendar connection, missing required parameter, or invalid request401Invalid or missing Maton API key, or OAuth scope mismatch404Resource not found429Rate limited4xx/5xxPassthrough error from Zoho Calendar API
ErrorDescriptionETAG_MISSINGetag header required for delete operationsEXTRA_PARAM_FOUNDInvalid parameter in requestINVALID_DATAMalformed request data
Check that the MATON_API_KEY environment 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://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
Ensure your URL path starts with zoho-calendar. For example: Correct: https://gateway.maton.ai/zoho-calendar/api/v1/calendars Incorrect: https://gateway.maton.ai/api/v1/calendars
Zoho Calendar API Introduction Zoho Calendar Events API Zoho Calendar Calendars API Create Event Get Events List Maton Community Maton Support
Workflow acceleration for inboxes, docs, calendars, planning, and execution loops.
Largest current source with strong distribution and engagement signals.