Find why your productivity system keeps failing, then apply the smallest fix — capacity math, bottleneck routing, durable local notes.
Documents
toggl-track
Try itRead and manage Toggl Track time entries, projects, clients, workspaces, and tags via OAuth-authenticated API calls.
What it does
Calls the Toggl Track REST API through the Maton proxy at api.maton.ai, authenticated with a Bearer API key. Supports full CRUD on time entries (including start/stop timers), projects, clients, and tags, plus workspace and user lookups. Lists use page-based pagination for projects, clients, and tags, and timestamp-based filtering for time entries. Write operations should be confirmed with the user before execution.
When to use it
- Start, stop, or update a running Toggl timer
- List time entries within a date range
- Create or update a Toggl project with billable settings
- Archive or restore a Toggl client
The skill document
Toggl Track
Access the Toggl Track API with managed OAuth authentication. Track time, manage projects, clients, tags, and workspaces.
Quick Start
# Get current user info
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/toggl-track/api/v9/me')
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://api.maton.ai/toggl-track/{native-api-path}
Maton proxies requests to api.track.toggl.com and automatically injects your credentials.
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
- Sign in or create an account at maton.ai
- Go to maton.ai/settings
- Copy your API key
Connection Management
Manage your Toggl Track OAuth connections at https://api.maton.ai.
List Connections
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=toggl-track&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': 'toggl-track'}).encode()
req = urllib.request.Request('https://api.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://api.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": "{connection_id}",
"status": "ACTIVE",
"creation_time": "2026-02-13T19:31:31.452264Z",
"last_updated_time": "2026-02-13T19:36:10.489069Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "toggl-track",
"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://api.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 Toggl Track connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/toggl-track/api/v9/me')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple connections, always include this header to ensure requests go to the intended account.
Security & Permissions
- Access is scoped to time entries, projects, clients, workspaces, and tags within the connected Toggl Track account.
- All write operations require explicit user approval. Before executing any create, update, or delete call, confirm the target resource and intended effect with the user.
API Reference
User & Workspace
Get Current User
GET /toggl-track/api/v9/me
Response:
{
"id": 12932942,
"email": "user@example.com",
"fullname": "John Doe",
"timezone": "America/Los_Angeles",
"default_workspace_id": 21180405,
"beginning_of_week": 1,
"image_url": "https://assets.track.toggl.com/images/profile.png"
}
List Workspaces
GET /toggl-track/api/v9/me/workspaces
Get Workspace
GET /toggl-track/api/v9/workspaces/{workspace_id}
List Workspace Users
GET /toggl-track/api/v9/workspaces/{workspace_id}/users
Time Entries
List Time Entries
GET /toggl-track/api/v9/me/time_entries
Query Parameters:
since(integer) - UNIX timestamp for entries modified after this timebefore(string) - Get entries before this date (RFC3339 or YYYY-MM-DD)start_date(string) - Filter start date (YYYY-MM-DD)end_date(string) - Filter end date (YYYY-MM-DD)
Get Current (Running) Time Entry
GET /toggl-track/api/v9/me/time_entries/current
Returns null if no time entry is currently running.
Get Time Entry by ID
GET /toggl-track/api/v9/me/time_entries/{time_entry_id}
Create Time Entry
POST /toggl-track/api/v9/workspaces/{workspace_id}/time_entries
Content-Type: application/json
{
"description": "Working on project",
"start": "2026-02-13T10:00:00Z",
"duration": -1,
"workspace_id": 21180405,
"project_id": 216896134,
"tag_ids": [20053808],
"created_with": "maton-api"
}
Note: Set duration to -1 to start a running timer. The created_with field is required.
Response:
{
"id": 4290254971,
"workspace_id": 21180405,
"project_id": null,
"task_id": null,
"billable": false,
"start": "2026-02-13T19:58:43Z",
"stop": null,
"duration": -1,
"description": "Working on project",
"tags": null,
"tag_ids": null,
"user_id": 12932942
}
Update Time Entry
PUT /toggl-track/api/v9/workspaces/{workspace_id}/time_entries/{time_entry_id}
Content-Type: application/json
{
"description": "Updated description",
"project_id": 216896134
}
Stop Running Time Entry
PATCH /toggl-track/api/v9/workspaces/{workspace_id}/time_entries/{time_entry_id}/stop
Delete Time Entry
DELETE /toggl-track/api/v9/workspaces/{workspace_id}/time_entries/{time_entry_id}
Projects
List Projects
GET /toggl-track/api/v9/workspaces/{workspace_id}/projects
Query Parameters:
active(boolean) - Filter by active statussince(integer) - UNIX timestamp for modification filtername(string) - Filter by project namepage(integer) - Page numberper_page(integer) - Items per page (max 200)
Get Project
GET /toggl-track/api/v9/workspaces/{workspace_id}/projects/{project_id}
Create Project
POST /toggl-track/api/v9/workspaces/{workspace_id}/projects
Content-Type: application/json
{
"name": "New Project",
"active": true,
"is_private": true,
"client_id": 68493239,
"color": "#0b83d9",
"billable": true
}
Response:
{
"id": 216896134,
"workspace_id": 21180405,
"client_id": null,
"name": "New Project",
"is_private": true,
"active": true,
"color": "#0b83d9",
"billable": true,
"created_at": "2026-02-13T19:58:36+00:00"
}
Update Project
PUT /toggl-track/api/v9/workspaces/{workspace_id}/projects/{project_id}
Content-Type: application/json
{
"name": "Updated Project Name",
"color": "#ff0000"
}
Delete Project
DELETE /toggl-track/api/v9/workspaces/{workspace_id}/projects/{project_id}
Clients
List Clients
GET /toggl-track/api/v9/workspaces/{workspace_id}/clients
Query Parameters:
status(string) - Filter:active,archived, orbothname(string) - Case-insensitive name filter
Get Client
GET /toggl-track/api/v9/workspaces/{workspace_id}/clients/{client_id}
Create Client
POST /toggl-track/api/v9/workspaces/{workspace_id}/clients
Content-Type: application/json
{
"name": "New Client",
"notes": "Client notes here"
}
Response:
{
"id": 68493239,
"wid": 21180405,
"archived": false,
"name": "New Client",
"at": "2026-02-13T19:58:36+00:00",
"creator_id": 12932942
}
Update Client
PUT /toggl-track/api/v9/workspaces/{workspace_id}/clients/{client_id}
Content-Type: application/json
{
"name": "Updated Client Name"
}
Delete Client
DELETE /toggl-track/api/v9/workspaces/{workspace_id}/clients/{client_id}
Archive Client
POST /toggl-track/api/v9/workspaces/{workspace_id}/clients/{client_id}/archive
Restore Client
POST /toggl-track/api/v9/workspaces/{workspace_id}/clients/{client_id}/restore
Content-Type: application/json
{
"restore_all_projects": true
}
Tags
List Tags
GET /toggl-track/api/v9/workspaces/{workspace_id}/tags
Query Parameters:
page(integer) - Page numberper_page(integer) - Items per page
Create Tag
POST /toggl-track/api/v9/workspaces/{workspace_id}/tags
Content-Type: application/json
{
"name": "New Tag"
}
Response:
{
"id": 20053808,
"workspace_id": 21180405,
"name": "New Tag",
"at": "2026-02-13T19:58:37.115714Z",
"creator_id": 12932942
}
Update Tag
PUT /toggl-track/api/v9/workspaces/{workspace_id}/tags/{tag_id}
Content-Type: application/json
{
"name": "Updated Tag Name"
}
Delete Tag
DELETE /toggl-track/api/v9/workspaces/{workspace_id}/tags/{tag_id}
Pagination
Toggl Track uses page-based pagination for most list endpoints:
GET /toggl-track/api/v9/workspaces/{workspace_id}/projects?page=1&per_page=50
For time entries, use timestamp-based filtering:
GET /toggl-track/api/v9/me/time_entries?since=1707840000&start_date=2026-02-01&end_date=2026-02-28
Code Examples
JavaScript
const response = await fetch(
'https://api.maton.ai/toggl-track/api/v9/me/time_entries',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const timeEntries = await response.json();
Python
import os
import requests
response = requests.get(
'https://api.maton.ai/toggl-track/api/v9/me/time_entries',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
)
time_entries = response.json()
Start a Timer
import os
import requests
from datetime import datetime, timezone
response = requests.post(
'https://api.maton.ai/toggl-track/api/v9/workspaces/21180405/time_entries',
headers={
'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}',
'Content-Type': 'application/json'
},
json={
'description': 'Working on task',
'start': datetime.now(timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ'),
'duration': -1,
'workspace_id': 21180405,
'created_with': 'maton-api'
}
)
Notes
- Workspace IDs are integers (e.g.,
21180405) - Time entry IDs are large integers (e.g.,
4290254971) - Duration is in seconds; use
-1for running timers - Timestamps use ISO 8601 format (e.g.,
2026-02-13T19:58:43Z) - The
created_withfield is required when creating time entries - IMPORTANT: When using curl commands, use
curl -gwhen URLs contain brackets to disable glob parsing - IMPORTANT: When piping curl output to
jqor other commands, environment variables like$MATON_API_KEYmay not expand correctly in some shell environments
Error Handling
| Status | Meaning |
|---|---|
| 400 | Missing Toggl Track connection or invalid request |
| 401 | Invalid or missing Maton API key |
| 403 | Access denied |
| 404 | Resource not found |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Toggl Track API |
Troubleshooting: API Key Issues
- Check that the
MATON_API_KEYenvironment 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://api.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
toggl-track. For example:
- Correct:
https://api.maton.ai/toggl-track/api/v9/me - Incorrect:
https://api.maton.ai/api/v9/me
Resources
Questions people ask
- How are multiple Toggl accounts handled?
- Send the Maton-Connection request header with the desired connection_id so requests target a specific connected Toggl Track account.
- Why is created_with required on time entries?
- Toggl Track requires the created_with field on every new time entry to identify the source; the skill examples use "maton-api".
- How do I paginate list endpoints?
- Projects, clients, and tags use page and per_page query params (max 200 per page). Time entries use since (UNIX timestamp) plus start_date and end_date in YYYY-MM-DD format.
Related skills
Join a video meeting as an AI bot with voice, avatar, and screenshare across four operating modes.
Stores durable facts in a categorized, plain-markdown vault on disk, alongside your agent's built-in memory.
Generate and edit Draw.io, Mermaid, and Excalidraw diagrams from natural language using a structured JSON spec.
Save, search, and manage personal notes and knowledge bases in Get笔记 on explicit request.
Fetch raw ad creative, app, ranking, and revenue data from AdMapix as structured JSON.
More from byungkyu
Browse all skillsRead and write Excel workbooks, worksheets, ranges, tables, and charts in OneDrive through Microsoft Graph with managed OAuth.
Manage Stripe customers, subscriptions, invoices, products, prices, and payments through OAuth-authenticated API calls.
Read and write Google Sheets data with managed OAuth authentication through a single API gateway.
Search, read, and manage YouTube videos, playlists, channels, subscriptions, and comments via managed OAuth.
Manage WooCommerce products, orders, customers, coupons, shipping, taxes, and more through managed OAuth REST API calls.
Manage ClickUp workspaces, spaces, folders, lists, and tasks via the ClickUp API with managed OAuth.