HomeBrowseUpload
← Back to registry
// Skill profile

Zoho Projects

name: zohoprojects

by byungkyu · published 2026-03-22

邮件处理数据处理加密货币
Total installs
0
Stars
★ 0
Last updated
2026-03
// Install command
$ claw add gh:byungkyu/byungkyu-zoho-projects
View on GitHub
// Full documentation

---

name: zohoprojects

description: |

Zoho Projects API integration with managed OAuth. Manage projects, tasks, milestones, tasklists, and team collaboration.

Use this skill when users want to manage project tasks, track time, organize milestones, or collaborate on projects.

For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).

compatibility: Requires network access and valid Maton API key

metadata:

author: maton

version: "1.0"

clawdbot:

emoji:

homepage: "https://maton.ai"

requires:

env:

- MATON_API_KEY

---

# Zoho Projects

Access the Zoho Projects API with managed OAuth authentication. Manage projects, tasks, milestones, tasklists, and team collaboration.

Quick Start

# List all portals
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/zoho-projects/restapi/portals/')
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://gateway.maton.ai/zoho-projects/{native-api-path}

Replace `{native-api-path}` with the actual Zoho Projects API endpoint path. The gateway proxies requests to `projectsapi.zoho.com` and automatically injects your OAuth token.

Authentication

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"

Getting Your API Key

1. Sign in or create an account at [maton.ai](https://maton.ai)

2. Go to [maton.ai/settings](https://maton.ai/settings)

3. Copy your API key

Connection Management

Manage your Zoho Projects OAuth connections at `https://ctrl.maton.ai`.

List Connections

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=zoho-projects&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

python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'zoho-projects'}).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

Get Connection

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": "522c11a9-b879-4504-b267-355e3dbac99f",
    "status": "ACTIVE",
    "creation_time": "2026-02-28T00:12:25.223434Z",
    "last_updated_time": "2026-02-28T00:16:32.882675Z",
    "url": "https://connect.maton.ai/?session_token=...",
    "app": "zoho-projects",
    "metadata": {},
    "method": "OAUTH2"
  }
}

Open the returned `url` in a browser to complete OAuth authorization.

Delete Connection

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

Specifying Connection

If you have multiple Zoho Projects 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-projects/restapi/portals/')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '522c11a9-b879-4504-b267-355e3dbac99f')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

If omitted, the gateway uses the default (oldest) active connection.

API Reference

Portals

#### List Portals

GET /zoho-projects/restapi/portals/

**Response:**

{
  "portals": [
    {
      "id": 916020774,
      "id_string": "916020774",
      "name": "nunchidotapp",
      "plan": "Ultimate",
      "role": "admin",
      "project_count": {"active": 1}
    }
  ]
}

#### Get Portal Details

GET /zoho-projects/restapi/portal/{portal_id}/

---

Projects

#### List Projects

GET /zoho-projects/restapi/portal/{portal_id}/projects/

Query parameters: `index`, `range`, `status`, `sort_column`, `sort_order`

**Response:**

{
  "projects": [
    {
      "id": 2644874000000089119,
      "name": "My Project",
      "status": "active",
      "owner_name": "Byungkyu Park",
      "task_count": {"open": 3, "closed": 0},
      "project_percent": "0"
    }
  ]
}

#### Get Project Details

GET /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/

#### Create Project

POST /zoho-projects/restapi/portal/{portal_id}/projects/
Content-Type: application/x-www-form-urlencoded

name=New+Project&owner={user_id}&description=Project+description

Required: `name`

Optional: `owner`, `description`, `start_date`, `end_date`, `template_id`, `group_id`

**Response:**

{
  "projects": [
    {
      "id": 2644874000000096003,
      "name": "New Project",
      "status": "active"
    }
  ]
}

#### Update Project

POST /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/
Content-Type: application/x-www-form-urlencoded

name=Updated+Name&status=active

#### Delete Project

DELETE /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/

**Response:**

{"response": "Project Trashed successfully"}

---

Tasks

#### List Tasks

GET /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/tasks/

Query parameters: `index`, `range`, `owner`, `status`, `priority`, `tasklist_id`, `sort_column`

**Response:**

{
  "tasks": [
    {
      "id": 2644874000000089255,
      "name": "Task 3",
      "status": {"name": "Open", "type": "open"},
      "priority": "None",
      "completed": false,
      "tasklist": {"name": "General", "id": "2644874000000089245"}
    }
  ]
}

#### Get Task Details

GET /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/tasks/{task_id}/

#### Get My Tasks

GET /zoho-projects/restapi/portal/{portal_id}/mytasks/

Query parameters: `index`, `range`, `owner`, `status`, `priority`, `projects_ids`

#### Create Task

POST /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/tasks/
Content-Type: application/x-www-form-urlencoded

name=New+Task&tasklist_id={tasklist_id}&priority=High

Required: `name`

Optional: `person_responsible`, `tasklist_id`, `start_date`, `end_date`, `priority`, `description`

**Response:**

{
  "tasks": [
    {
      "id": 2644874000000094001,
      "key": "EZ1-T4",
      "name": "New Task",
      "status": {"name": "Open", "type": "open"}
    }
  ]
}

#### Update Task

POST /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/tasks/{task_id}/
Content-Type: application/x-www-form-urlencoded

name=Updated+Name&priority=High&percent_complete=50

#### Delete Task

DELETE /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/tasks/{task_id}/

**Response:**

{"response": "Task Trashed successfully"}

---

Task Comments

#### List Comments

GET /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/tasks/{task_id}/comments/

#### Add Comment

POST /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/tasks/{task_id}/comments/
Content-Type: application/x-www-form-urlencoded

content=This+is+a+comment

**Response:**

{
  "comments": [
    {
      "id": 2644874000000094015,
      "content": "This is a comment",
      "added_person": "Byungkyu Park"
    }
  ]
}

#### Update Comment

POST /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/tasks/{task_id}/comments/{comment_id}/
Content-Type: application/x-www-form-urlencoded

content=Updated+comment

#### Delete Comment

DELETE /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/tasks/{task_id}/comments/{comment_id}/

---

Tasklists

#### List Tasklists

GET /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/tasklists/

Query parameters: `index`, `range`, `flag`, `milestone_id`, `sort_column`

**Response:**

{
  "tasklists": [
    {
      "id": 2644874000000089245,
      "name": "General",
      "flag": "internal",
      "is_default": true,
      "task_count": {"open": 3}
    }
  ]
}

#### Create Tasklist

POST /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/tasklists/
Content-Type: application/x-www-form-urlencoded

name=New+Tasklist&flag=internal

Required: `name`

Optional: `milestone_id`, `flag`

#### Update Tasklist

POST /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/tasklists/{tasklist_id}/
Content-Type: application/x-www-form-urlencoded

name=Updated+Name&milestone_id={milestone_id}

#### Delete Tasklist

DELETE /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/tasklists/{tasklist_id}/

**Response:**

{"response": "Tasklist Trashed successfully"}

---

Milestones

#### List Milestones

GET /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/milestones/

Query parameters: `index`, `range`, `status`, `flag`, `sort_column`

**Note:** Returns 204 No Content if no milestones exist.

#### Create Milestone

POST /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/milestones/
Content-Type: application/x-www-form-urlencoded

name=Phase+1&start_date=03-01-2026&end_date=03-15-2026&owner={user_id}&flag=internal

Required: `name`, `start_date`, `end_date`, `owner`, `flag`

**Response:**

{
  "milestones": [
    {
      "id": 2644874000000096133,
      "name": "Phase 1",
      "start_date": "03-01-2026",
      "end_date": "03-15-2026",
      "status": "notcompleted"
    }
  ]
}

#### Update Milestone

POST /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/milestones/{milestone_id}/
Content-Type: application/x-www-form-urlencoded

name=Updated+Phase&start_date=03-01-2026&end_date=03-20-2026&owner={user_id}&flag=internal

#### Update Milestone Status

POST /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/milestones/{milestone_id}/status/
Content-Type: application/x-www-form-urlencoded

status=2

Status values: `1` = not completed, `2` = completed

#### Delete Milestone

DELETE /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/milestones/{milestone_id}/

**Response:**

{"response": "Milestone Trashed successfully"}

---

Users

#### List Users

GET /zoho-projects/restapi/portal/{portal_id}/users/

**Response:**

{
  "users": [
    {
      "id": "801698114",
      "zpuid": "2644874000000085003",
      "name": "Byungkyu Park",
      "email": "byungkyu@example.com",
      "role_name": "Administrator",
      "active": true
    }
  ]
}

---

Project Groups

#### List Groups

GET /zoho-projects/restapi/portal/{portal_id}/projects/groups

**Response:**

{
  "groups": [
    {
      "id": "2644874000000018001",
      "name": "Ungrouped Projects",
      "is_default": "true"
    }
  ]
}

#### Create Group

POST /zoho-projects/restapi/portal/{portal_id}/projectgroups
Content-Type: application/x-www-form-urlencoded

name=New+Group

---

Pagination

Use `index` and `range` parameters for pagination:

GET /zoho-projects/restapi/portal/{portal_id}/projects/{project_id}/tasks/?index=1&range=50
  • `index`: Starting record number (1-based)
  • `range`: Number of records to return
  • Code Examples

    JavaScript

    // List tasks in a project
    const response = await fetch(
      'https://gateway.maton.ai/zoho-projects/restapi/portal/916020774/projects/2644874000000089119/tasks/',
      {
        headers: {
          'Authorization': `Bearer ${process.env.MATON_API_KEY}`
        }
      }
    );
    const data = await response.json();
    console.log(data.tasks);

    Python

    import os
    import requests
    
    # Create a task
    response = requests.post(
        'https://gateway.maton.ai/zoho-projects/restapi/portal/916020774/projects/2644874000000089119/tasks/',
        headers={
            'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}',
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        data={'name': 'New Task', 'priority': 'High'}
    )
    task = response.json()
    print(task['tasks'][0]['id'])

    Notes

  • All POST requests for create/update use `application/x-www-form-urlencoded` content type, not JSON
  • Portal ID is required for most endpoints and can be obtained from `GET /restapi/portals/`
  • Date format is `MM-dd-yyyy` (e.g., `03-01-2026`)
  • Milestone creation requires all fields: `name`, `start_date`, `end_date`, `owner`, `flag`
  • Empty list responses return HTTP 204 No Content
  • Deleted items are moved to trash, not permanently deleted
  • Error Handling

    | Status | Meaning |

    |--------|---------|

    | 204 | No content (empty list) |

    | 400 | Missing/invalid input parameter |

    | 401 | Invalid or missing Maton API key |

    | 404 | Resource not found |

    | 429 | Rate limited (100 requests per 2 minutes) |

    | 4xx/5xx | Passthrough error from Zoho Projects API |

    Common error codes:

  • `6831`: Input Parameter Missing
  • `6832`: Input Parameter Does not Match the Pattern Specified
  • Troubleshooting: API Key Issues

    1. Check that the `MATON_API_KEY` environment variable is set:

    echo $MATON_API_KEY

    2. 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

    Troubleshooting: Invalid App Name

    Ensure your URL path starts with `zoho-projects`. For example:

  • Correct: `https://gateway.maton.ai/zoho-projects/restapi/portals/`
  • Incorrect: `https://gateway.maton.ai/restapi/portals/`
  • Resources

  • [Zoho Projects API Documentation](https://www.zoho.com/projects/help/rest-api/zohoprojectsapi.html)
  • [Projects API](https://www.zoho.com/projects/help/rest-api/projects-api.html)
  • [Tasks API](https://www.zoho.com/projects/help/rest-api/tasks-api.html)
  • [Milestones API](https://www.zoho.com/projects/help/rest-api/milestones-api.html)
  • [Maton Community](https://discord.com/invite/dBfFAcefs2)
  • [Maton Support](mailto:support@maton.ai)
  • // Comments
    Sign in with GitHub to leave a comment.
    // Related skills

    More tools from the same signal band