Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
Interact with Zoho CRM, Projects, and Meeting APIs. Use when managing deals, contacts, leads, tasks, projects, milestones, meeting recordings, or any Zoho wo...
Interact with Zoho CRM, Projects, and Meeting APIs. Use when managing deals, contacts, leads, tasks, projects, milestones, meeting recordings, or any Zoho wo...
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. Then review README.md for any prerequisites, environment setup, or post-install checks. 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. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run.
Made by Zone 99 ยท GitHub ยท Contribute
Use the zoho CLI wrapper โ it handles OAuth token refresh and caching automatically. zoho help # Show all commands zoho token # Print current access token (auto-refreshes)
Go to Zoho API Console Click Add Client โ choose Server-based Applications Fill in: Client Name: your app name (e.g. "Clawdbot Zoho Integration") Homepage URL: your domain or https://localhost Redirect URI: https://localhost/callback (or any URL you control โ you only need it once to grab the code) Click Create Note down the Client ID and Client Secret
Build this URL and open it in your browser (replace the placeholders): https://accounts.zoho.com/oauth/v2/auth ?response_type=code &client_id=YOUR_CLIENT_ID &scope=ZohoCRM.modules.ALL,ZohoCRM.settings.ALL,ZohoProjects.projects.ALL,ZohoProjects.tasks.ALL,ZohoMeeting.recording.READ,ZohoMeeting.meeting.READ,ZohoMeeting.meetinguds.READ,ZohoFiles.files.READ &redirect_uri=https://localhost/callback &access_type=offline &prompt=consent Important: Use the accounts URL matching your datacenter: RegionAccounts URLUShttps://accounts.zoho.comEUhttps://accounts.zoho.euINhttps://accounts.zoho.inAUhttps://accounts.zoho.com.auJPhttps://accounts.zoho.jpUKhttps://accounts.zoho.ukCAhttps://accounts.zohocloud.caSAhttps://accounts.zoho.sa After granting access, you'll be redirected to something like: https://localhost/callback?code=1000.abc123...&location=us&accounts-server=https://accounts.zoho.com Copy the code parameter value. This code expires in 2 minutes โ move to Step 3 immediately.
Run this curl command (replace placeholders): curl -X POST "https://accounts.zoho.com/oauth/v2/token" \ -d "client_id=YOUR_CLIENT_ID" \ -d "client_secret=YOUR_CLIENT_SECRET" \ -d "grant_type=authorization_code" \ -d "redirect_uri=https://localhost/callback" \ -d "code=PASTE_CODE_FROM_STEP_2" Response: { "access_token": "1000.xxxx.yyyy", "refresh_token": "1000.xxxx.zzzz", "api_domain": "https://www.zohoapis.com", "token_type": "Bearer", "expires_in": 3600 } Save the refresh_token โ this is your long-lived credential. The access token expires in 1 hour, but the CLI auto-refreshes it using the refresh token.
CRM/Projects Org ID: # After setting up .env with client_id, client_secret, refresh_token: zoho raw GET /crm/v7/org | jq '.org[0].id' Meeting Org ID: Log into Zoho Meeting โ Admin Settings โ look for the Organization ID in the URL or settings page. It's different from the CRM org ID.
Create .env in the skill directory: ZOHO_CLIENT_ID=1000.XXXXXXXXXXXXXXXXXXXXXXXXX ZOHO_CLIENT_SECRET=your_client_secret_here ZOHO_REFRESH_TOKEN=1000.your_refresh_token_here ZOHO_ORG_ID=123456789 # CRM/Projects org ID ZOHO_MEETING_ORG_ID=987654321 # Meeting org ID (different from CRM) ZOHO_CRM_DOMAIN=https://www.zohoapis.com ZOHO_PROJECTS_DOMAIN=https://projectsapi.zoho.com/restapi ZOHO_MEETING_DOMAIN=https://meeting.zoho.com ZOHO_ACCOUNTS_URL=https://accounts.zoho.com Adjust the domain URLs if you're on a non-US datacenter (e.g. .eu, .in, .com.au).
ScopeUsed ForZohoCRM.modules.ALLRead/write CRM records (Deals, Contacts, Leads, etc.)ZohoCRM.settings.ALLRead CRM field definitions and org settingsZohoProjects.projects.ALLRead/write projectsZohoProjects.tasks.ALLRead/write tasks, milestones, bugs, timelogsZohoMeeting.recording.READList and access meeting recordingsZohoMeeting.meeting.READList meetings and session detailsZohoMeeting.meetinguds.READDownload recording filesZohoFiles.files.READDownload files (recordings, transcripts) You can request fewer scopes if you only need CRM or only need Meeting. The authorization URL scope parameter is comma-separated.
"invalid_code" โ The authorization code expired (2 min lifetime). Redo Step 2. "invalid_client" โ Wrong Client ID, or wrong accounts-server URL for your datacenter. "invalid_redirect_uri" โ The redirect_uri in the curl must exactly match what you registered in API Console. Token refresh fails โ Refresh tokens can be revoked. Redo Steps 2โ3 to get a new one. "Given URL is wrong" โ You're hitting the wrong API domain for your datacenter.
# List records from any module zoho crm list Deals zoho crm list Deals "page=1&per_page=5&sort_by=Created_Time&sort_order=desc" zoho crm list Contacts zoho crm list Leads # Get a specific record zoho crm get Deals 1234567890 # Search with criteria zoho crm search Deals "(Stage:equals:Closed Won)" zoho crm search Contacts "(Email:contains:@acme.com)" zoho crm search Leads "(Lead_Source:equals:Web)" # Create a record zoho crm create Contacts '{"data":[{"Last_Name":"Smith","First_Name":"John","Email":"j@co.com"}]}' zoho crm create Deals '{"data":[{"Deal_Name":"New Project","Stage":"Qualification","Amount":50000}]}' # Update a record zoho crm update Deals 1234567890 '{"data":[{"Stage":"Closed Won"}]}' # Delete a record zoho crm delete Deals 1234567890
Leads, Contacts, Accounts, Deals, Tasks, Events, Calls, Notes, Products, Quotes, Sales_Orders, Purchase_Orders, Invoices
equals, not_equal, starts_with, contains, not_contains, in, not_in, between, greater_than, less_than
# List all projects zoho proj list # Get project details zoho proj get 12345678 # Tasks zoho proj tasks 12345678 zoho proj create-task 12345678 "name=Fix+login+bug&priority=High&start_date=01-27-2026" zoho proj update-task 12345678 98765432 "percent_complete=50" # Other zoho proj milestones 12345678 zoho proj tasklists 12345678 zoho proj bugs 12345678 zoho proj timelogs 12345678
name, start_date (MM-DD-YYYY), end_date, priority (None/Low/Medium/High), owner, description, tasklist_id, percent_complete
# List all recordings zoho meeting recordings zoho meeting recordings | jq '[.recordings[] | {topic, sDate, sTime, durationInMins, erecordingId}]' # Download a recording (use downloadUrl from recordings list) zoho meeting download "https://files-accl.zohopublic.com/public?event-id=..." output.mp4 # List meetings/sessions zoho meeting list zoho meeting list "fromDate=2026-01-01T00:00:00Z&toDate=2026-01-31T23:59:59Z" # Get meeting details zoho meeting get 1066944216
Key fields from zoho meeting recordings: erecordingId โ encrypted recording ID (use for dedup/tracking) topic โ meeting title sDate, sTime โ start date/time (human-readable) startTimeinMs โ start time as epoch ms (use for date filtering) durationInMins โ recording duration downloadUrl / publicDownloadUrl โ MP4 download URL transcriptionDownloadUrl โ Zoho-generated transcript (if available) summaryDownloadUrl โ Zoho-generated summary (if available) fileSize / fileSizeInMB โ recording file size status โ e.g. UPLOADED meetingKey โ meeting identifier creatorName โ who started the recording
For automated standup/meeting summarization: # 1. List recordings, filter by today's date (epoch ms) zoho meeting recordings | jq --argjson start "$START_MS" --argjson end "$END_MS" \ '[.recordings[] | select(.startTimeinMs >= $start and .startTimeinMs <= $end)]' # 2. Download recording zoho meeting download "$DOWNLOAD_URL" /tmp/recording.mp4 # 3. Extract audio ffmpeg -i /tmp/recording.mp4 -vn -acodec pcm_s16le -ar 16000 -ac 1 /tmp/audio.wav -y # 4. Transcribe via Gemini Flash API (great for Arabic + English mix) # See scripts/standup-summarizer.sh for full implementation # 5. Summarize transcript with Claude/GPT # 6. Clean up temp files A complete standup summarizer script is included at scripts/standup-summarizer.sh.
For anything not covered by subcommands: # CRM endpoints zoho raw GET /crm/v7/settings/fields?module=Deals zoho raw GET /crm/v7/org # Meeting endpoints zoho raw GET "https://meeting.zoho.com/meeting/api/v2/{zsoid}/recordings.json" # Custom modules zoho raw GET /crm/v7/Custom_Module
zoho crm list Deals "sort_by=Created_Time&sort_order=desc&per_page=10" | jq '.data[] | {Deal_Name, Stage, Amount, Closing_Date}'
zoho proj list | jq '.projects[] | {name, status, id: .id_string}' zoho proj tasks <project_id> | jq '.tasks[] | {name, status: .status.name, percent_complete, priority}'
zoho proj create-task <project_id> "name=Task+description&priority=High&start_date=MM-DD-YYYY&end_date=MM-DD-YYYY"
# Quick list of recent recordings zoho meeting recordings | jq '[.recordings[:5] | .[] | {topic, sDate, sTime, durationInMins, fileSize}]' # Download latest recording URL=$(zoho meeting recordings | jq -r '.recordings[0].downloadUrl') zoho meeting download "$URL" /tmp/latest.mp4
CRM: 100 requests/min Projects: varies by plan Meeting: standard API limits Token refresh: don't call more than needed (cached automatically)
CRM API Fields Projects API Endpoints Meeting API Reference
Code helpers, APIs, CLIs, browser automation, testing, and developer operations.
Largest current source with strong distribution and engagement signals.