Podio

v1.0.0

Podio API integration with managed OAuth. Manage workspaces, apps, items, tasks, and comments. Use this skill when users want to read, create, update, or delete Podio items, manage tasks, or interact with Podio apps and workspaces. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).

2· 1.2k·0 current·0 all-time
Security Scan
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Benign
medium confidence
Purpose & Capability
Name and description claim a Podio integration using managed OAuth and the SKILL.md instructs use of Maton gateway endpoints (gateway.maton.ai, ctrl.maton.ai). The single required env var (MATON_API_KEY) matches the described gateway-based auth model.
Instruction Scope
Instructions only show HTTP calls to Maton proxy/control endpoints and use os.environ['MATON_API_KEY']. They do not instruct reading unrelated files, other environment variables, or system state, nor do they redirect data to unexpected third parties beyond Maton endpoints.
Install Mechanism
No install spec and no code files beyond SKILL.md and LICENSE — this is instruction-only, which minimizes disk-write and install risk.
Credentials
Only one required environment variable (MATON_API_KEY) is declared and used. That key is consistent with the Maton gateway described; no unrelated credentials or broad-scoped secrets are requested.
Persistence & Privilege
always:false (default) and no install/config steps are present. The skill does not request persistent or elevated system privileges and does not modify other skills or agent-wide settings.
Assessment
This skill delegates Podio access through Maton (gateway.maton.ai / ctrl.maton.ai) and requires your MATON_API_KEY. Before installing: verify you trust maton.ai (it will mediate access to your Podio accounts), treat MATON_API_KEY like a sensitive credential (it can grant access to Podio via the gateway), consider creating a least-privileged Maton API key if available, review Maton account connection listings and revoke unused connections, and monitor audit logs for unexpected activity. If you need higher assurance, ask the publisher for a verifiable homepage or source repo and confirm the exact scopes/permissions granted to the MATON_API_KEY.

Like a lobster shell, security has layers — review code before you run it.

Runtime requirements

🧠 Clawdis
EnvMATON_API_KEY
latestvk9726kbd2qxn7g47evm5pw1mbh81121y
1.2kdownloads
2stars
1versions
Updated 1mo ago
v1.0.0
MIT-0

Podio

Access the Podio API with managed OAuth authentication. Manage organizations, workspaces (spaces), apps, items, tasks, comments, and files.

Quick Start

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

Replace {native-api-path} with the actual Podio API endpoint path. The gateway proxies requests to api.podio.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
  2. Go to maton.ai/settings
  3. Copy your API key

Connection Management

Manage your Podio 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=podio&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': 'podio'}).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": "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": "podio",
    "metadata": {}
  }
}

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 Podio 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/podio/org/')
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.

API Reference

Organization Operations

List Organizations

Returns all organizations and spaces the user is a member of.

GET /podio/org/

Response:

[
  {
    "org_id": 123456,
    "name": "My Organization",
    "url": "https://podio.com/myorg",
    "url_label": "myorg",
    "type": "premium",
    "role": "admin",
    "status": "active",
    "spaces": [
      {
        "space_id": 789,
        "name": "Project Space",
        "url": "https://podio.com/myorg/project-space",
        "role": "admin"
      }
    ]
  }
]

Get Organization

GET /podio/org/{org_id}

Space (Workspace) Operations

Get Space

GET /podio/space/{space_id}

Response:

{
  "space_id": 789,
  "name": "Project Space",
  "privacy": "closed",
  "auto_join": false,
  "url": "https://podio.com/myorg/project-space",
  "url_label": "project-space",
  "role": "admin",
  "created_on": "2025-01-15T10:30:00Z",
  "created_by": {
    "user_id": 12345,
    "name": "John Doe"
  }
}

Create Space

POST /podio/space/
Content-Type: application/json

{
  "org_id": 123456,
  "name": "New Project Space",
  "privacy": "closed",
  "auto_join": false,
  "post_on_new_app": true,
  "post_on_new_member": true
}

Response:

{
  "space_id": 790,
  "url": "https://podio.com/myorg/new-project-space"
}

Application Operations

Get Apps by Space

GET /podio/app/space/{space_id}/

Optional query parameters:

  • include_inactive - Include inactive apps (default: false)

Get App

GET /podio/app/{app_id}

Response:

{
  "app_id": 456,
  "status": "active",
  "space_id": 789,
  "config": {
    "name": "Tasks",
    "item_name": "Task",
    "description": "Track project tasks",
    "icon": "list"
  },
  "fields": [...]
}

Item Operations

Get Item

GET /podio/item/{item_id}

Optional query parameters:

  • mark_as_viewed - Mark notifications as viewed (default: true)

Response:

{
  "item_id": 123,
  "title": "Complete project plan",
  "app": {
    "app_id": 456,
    "name": "Tasks"
  },
  "fields": [
    {
      "field_id": 1,
      "external_id": "status",
      "type": "category",
      "values": [{"value": {"text": "In Progress"}}]
    }
  ],
  "created_on": "2025-01-20T14:00:00Z",
  "created_by": {
    "user_id": 12345,
    "name": "John Doe"
  }
}

Filter Items

POST /podio/item/app/{app_id}/filter/
Content-Type: application/json

{
  "sort_by": "created_on",
  "sort_desc": true,
  "filters": {
    "status": [1, 2]
  },
  "limit": 30,
  "offset": 0
}

Response:

{
  "total": 150,
  "filtered": 45,
  "items": [
    {
      "item_id": 123,
      "title": "Complete project plan",
      "fields": [...],
      "comment_count": 5,
      "file_count": 2
    }
  ]
}

Add New Item

POST /podio/item/app/{app_id}/
Content-Type: application/json

{
  "fields": {
    "title": "New task",
    "status": 1,
    "due-date": {"start": "2025-02-15"}
  },
  "tags": ["urgent", "project-alpha"],
  "file_ids": [12345]
}

Optional query parameters:

  • hook - Execute hooks (default: true)
  • silent - Suppress notifications (default: false)

Response:

{
  "item_id": 124,
  "title": "New task"
}

Update Item

PUT /podio/item/{item_id}
Content-Type: application/json

{
  "fields": {
    "status": 2
  },
  "revision": 5
}

Optional query parameters:

  • hook - Execute hooks (default: true)
  • silent - Suppress notifications (default: false)

Response:

{
  "revision": 6,
  "title": "New task"
}

Delete Item

DELETE /podio/item/{item_id}

Optional query parameters:

  • hook - Execute hooks (default: true)
  • silent - Suppress notifications (default: false)

Task Operations

Get Tasks

Note: Tasks require at least one filter: org, space, app, responsible, reference, created_by, or completed_by.

GET /podio/task/?org={org_id}
GET /podio/task/?space={space_id}
GET /podio/task/?app={app_id}&completed=false

Query parameters:

  • org - Filter by organization ID (required if no other filter)
  • space - Filter by space ID
  • app - Filter by app ID
  • completed - Filter by completion status (true or false)
  • responsible - Filter by responsible user IDs
  • created_by - Filter by creator
  • due_date - Date range (YYYY-MM-DD-YYYY-MM-DD)
  • limit - Maximum results
  • offset - Result offset
  • sort_by - Sort by: created_on, completed_on, rank (default: rank)
  • grouping - Group by: due_date, created_by, responsible, app, space, org

Get Task

GET /podio/task/{task_id}

Response:

{
  "task_id": 789,
  "text": "Review project proposal",
  "description": "Detailed review of the Q1 proposal",
  "status": "active",
  "due_date": "2025-02-15",
  "due_time": "17:00:00",
  "responsible": {
    "user_id": 12345,
    "name": "John Doe"
  },
  "created_on": "2025-01-20T10:00:00Z",
  "labels": [
    {"label_id": 1, "text": "High Priority", "color": "red"}
  ]
}

Create Task

POST /podio/task/
Content-Type: application/json

{
  "text": "Review project proposal",
  "description": "Detailed review of the Q1 proposal",
  "due_date": "2025-02-15",
  "due_time": "17:00:00",
  "responsible": 12345,
  "private": false,
  "ref_type": "item",
  "ref_id": 123,
  "labels": [1, 2]
}

Optional query parameters:

  • hook - Execute hooks (default: true)
  • silent - Suppress notifications (default: false)

Response:

{
  "task_id": 790,
  ...
}

Comment Operations

Get Comments on Object

GET /podio/comment/{type}/{id}/

Where {type} is the object type (e.g., "item", "task") and {id} is the object ID.

Optional query parameters:

  • limit - Maximum comments (default: 100)
  • offset - Pagination offset (default: 0)

Response:

[
  {
    "comment_id": 456,
    "value": "This looks great!",
    "created_on": "2025-01-20T15:30:00Z",
    "created_by": {
      "user_id": 12345,
      "name": "John Doe"
    },
    "files": []
  }
]

Add Comment to Object

POST /podio/comment/{type}/{id}
Content-Type: application/json

{
  "value": "Great progress on this task!",
  "file_ids": [12345],
  "embed_url": "https://example.com/doc"
}

Optional query parameters:

  • alert_invite - Auto-invite mentioned users (default: false)
  • hook - Execute hooks (default: true)
  • silent - Suppress notifications (default: false)

Response:

{
  "comment_id": 457,
  ...
}

Pagination

Podio uses offset-based pagination with limit and offset parameters:

POST /podio/item/app/{app_id}/filter/
Content-Type: application/json

{
  "limit": 30,
  "offset": 0
}

Response includes total counts:

{
  "total": 150,
  "filtered": 45,
  "items": [...]
}

For subsequent pages, increment the offset:

{
  "limit": 30,
  "offset": 30
}

Code Examples

JavaScript

const response = await fetch(
  'https://gateway.maton.ai/podio/org/',
  {
    headers: {
      'Authorization': `Bearer ${process.env.MATON_API_KEY}`
    }
  }
);
const data = await response.json();

Python

import os
import requests

response = requests.get(
    'https://gateway.maton.ai/podio/org/',
    headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
)
data = response.json()

Notes

  • Organization IDs, space IDs, app IDs, and item IDs are integers
  • Field values can be specified by field_id or external_id
  • Category fields use option IDs (integers), not text values
  • Deleting an item also deletes associated tasks (cascade delete)
  • Tasks require at least one filter (org, space, app, responsible, reference, created_by, or completed_by)
  • Use silent=true to suppress notifications for bulk operations
  • Use hook=false to skip webhook triggers
  • Include revision in update requests for conflict detection (returns 409 if conflict)
  • 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

Error Handling

StatusMeaning
400Missing Podio connection or invalid request
401Invalid or missing Maton API key
403Forbidden - insufficient permissions
404Resource not found
409Conflict (revision mismatch on update)
410Resource has been deleted
429Rate limited
4xx/5xxPassthrough error from Podio API

Troubleshooting: API Key Issues

  1. Check that the MATON_API_KEY environment variable is set:
echo $MATON_API_KEY
  1. 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

  1. Ensure your URL path starts with podio. For example:
  • Correct: https://gateway.maton.ai/podio/org/
  • Incorrect: https://gateway.maton.ai/org/

Resources

Comments

Loading comments...