Introduction
# Google Tasks
Access the Google Tasks API with managed OAuth authentication. Manage task lists and tasks with full CRUD operations.
## Quick Start
```bash # List all task lists python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/google-tasks/tasks/v1/users/@me/lists') 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/google-tasks/{native-api-path} ```
Replace `{native-api-path}` with the actual Google Tasks API endpoint path. The gateway proxies requests to `tasks.googleapis.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`:
```bash 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 Google Tasks OAuth connections at `https://ctrl.maton.ai`.
### List Connections
```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections?app=google-tasks&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
```bash python <<'EOF' import urllib.request, os, json data = json.dumps({'app': 'google-tasks'}).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
```bash 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:** ```json { "connection": { "connection_id": "0e13cacd-cec8-4b6b-9368-c62cc9b06dd9", "status": "ACTIVE", "creation_time": "2026-02-07T02:35:51.002199Z", "last_updated_time": "2026-02-07T05:32:30.369186Z", "url": "https://connect.maton.ai/?session_token=...", "app": "google-tasks", "metadata": {} } } ```
Open the returned `url` in a browser to complete OAuth authorization.
### Delete Connection
```bash 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 Google Tasks connections, specify which one to use with the `Maton-Connection` header:
```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/google-tasks/tasks/v1/users/@me/lists') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Maton-Connection', '0e13cacd-cec8-4b6b-9368-c62cc9b06dd9') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```
If omitted, the gateway uses the default (oldest) active connection.
## API Reference
### Task Lists
#### List All Task Lists
```bash GET /google-tasks/tasks/v1/users/@me/lists ```
**Query Parameters:** - `maxResults` - Maximum number of task lists to return (default: 20, max: 100) - `pageToken` - Token for pagination
**Response:** ```json { "kind": "tasks#taskLists", "etag": "\"OW7pv01-vgQ\"", "items": [ { "kind": "tasks#taskList", "id": "MDEzMTQ2ODk4NDc2ODkyOTIyMTE6MDow", "etag": "\"Yz7ljQZ5Xuw\"", "title": "My Tasks", "updated": "2023-09-18T06:12:59.468Z", "selfLink": "https://www.googleapis.com/tasks/v1/users/@me/lists/MDEzMTQ2ODk4NDc2ODkyOTIyMTE6MDow" } ] } ```
#### Get Task List
```bash GET /google-tasks/tasks/v1/users/@me/lists/{tasklistId} ```
#### Create Task List
```bash POST /google-tasks/tasks/v1/users/@me/lists Content-Type: application/json
{ "title": "New Task List" } ```
**Response:** ```json { "kind": "tasks#taskList", "id": "OFYyU09veWMyWl84SjNQXw", "etag": "\"XTqLSxP4QZQ\"", "title": "New Task List", "updated": "2026-02-07T05:45:22.685Z", "selfLink": "https://www.googleapis.com/tasks/v1/users/@me/lists/OFYyU09veWMyWl84SjNQXw" } ```
#### Update Task List (PATCH - partial update)
```bash PATCH /google-tasks/tasks/v1/users/@me/lists/{tasklistId} Content-Type: application/json
{ "title": "Updated Title" } ```
#### Update Task List (PUT - full replace)
```bash PUT /google-tasks/tasks/v1/users/@me/lists/{tasklistId} Content-Type: application/json
{ "title": "Replaced Title" } ```
#### Delete Task List
```bash DELETE /google-tasks/tasks/v1/users/@me/lists/{tasklistId} ```
### Tasks
#### List Tasks
```bash GET /google-tasks/tasks/v1/lists/{tasklistId}/tasks ```
**Query Parameters:** - `maxResults` - Maximum number of tasks to return (default: 20, max: 100) - `pageToken` - Token for pagination - `showCompleted` - Include completed tasks (default: true) - `showDeleted` - Include deleted tasks (default: false) - `showHidden` - Include hidden tasks (default: false) - `dueMin` - Lower bound for due date (RFC 3339 timestamp) - `dueMax` - Upper bound for due date (RFC 3339 timestamp) - `completedMin` - Lower bound for completion date (RFC 3339 timestamp) - `completedMax` - Upper bound for completion date (RFC 3339 timestamp) - `updatedMin` - Lower bound for last update time (RFC 3339 timestamp)
**Response:** ```json { "kind": "tasks#tasks", "etag": "\"Jhh35adkRkU\"", "nextPageToken": "CgwI27nR6AUQsKHh7QIa...", "items": [ { "kind": "tasks#task", "id": "blJQR1hfaXhSU0tMY3gwdg", "etag": "\"Uqc8Y3T9VOA\"", "title": "Example Task", "updated": "2020-11-09T21:17:08.911Z", "selfLink": "https://www.googleapis.com/tasks/v1/lists/.../tasks/blJQR1hfaXhSU0tMY3gwdg", "position": "00000000000000000000", "status": "needsAction", "due": "2020-12-08T00:00:00.000Z", "notes": "Task notes here", "links": [], "webViewLink": "https://tasks.google.com/task/nRPGX_ixRSKLcx0v?sa=6" } ] } ```
#### Get Task
```bash GET /google-tasks/tasks/v1/lists/{tasklistId}/tasks/{taskId} ```
#### Create Task
```bash POST /google-tasks/tasks/v1/lists/{tasklistId}/tasks Content-Type: application/json
{ "title": "New Task", "notes": "Task description", "due": "2026-03-01T00:00:00.000Z" } ```
**Query Parameters (optional):** - `parent` - Parent task ID (for subtasks) - `previous` - Previous sibling task ID (for positioning)
**Response:** ```json { "kind": "tasks#task", "id": "bkludnJmdjZIZWVFejBnYg", "etag": "\"EKX4SVb-Ljk\"", "title": "New Task", "updated": "2026-02-07T05:45:05.371Z", "selfLink": "https://www.googleapis.com/tasks/v1/lists/.../tasks/bkludnJmdjZIZWVFejBnYg", "position": "00000000000000000000", "notes": "Task description", "status": "needsAction", "due": "2026-03-01T00:00:00.000Z", "links": [], "webViewLink": "https://tasks.google.com/task/nInvrfv6HeeEz0gb?sa=6" } ```
#### Update Task (PATCH - partial update)
```bash PATCH /google-tasks/tasks/v1/lists/{tasklistId}/tasks/{taskId} Content-Type: application/json
{ "title": "Updated Task Title", "status": "completed" } ```
**Response:** ```json { "kind": "tasks#task", "id": "bkludnJmdjZIZWVFejBnYg", "etag": "\"OeWHIDNj-os\"", "title": "Updated Task Title", "updated": "2026-02-07T05:45:15.334Z", "selfLink": "https://www.googleapis.com/tasks/v1/lists/.../tasks/bkludnJmdjZIZWVFejBnYg", "position": "00000000000000000000", "notes": "Task description", "status": "completed", "completed": "2026-02-07T05:45:15.307Z", "links": [], "webViewLink": "https://tasks.google.com/task/nInvrfv6HeeEz0gb?sa=6" } ```
#### Update Task (PUT - full replace)
```bash PUT /google-tasks/tasks/v1/lists/{tasklistId}/tasks/{taskId} Content-Type: application/json
{ "title": "Replaced Task", "notes": "New notes", "status": "needsAction" } ```
#### Delete Task
```bash DELETE /google-tasks/tasks/v1/lists/{tasklistId}/tasks/{taskId} ```
#### Move Task
Reposition a task within a task list or change its parent.
```bash POST /google-tasks/tasks/v1/lists/{tasklistId}/tasks/{taskId}/move ```
**Query Parameters (optional):** - `parent` - New parent task ID (for making it a subtask) - `previous` - Previous sibling task ID (for positioning after this task)
**Response:** ```json { "kind": "tasks#task", "id": "VkI5bTEzazdvNzlYNWVycw", "etag": "\"Uplv6eL0sDo\"", "title": "Task B", "updated": "2026-02-07T05:45:36.801Z", "selfLink": "https://www.googleapis.com/tasks/v1/lists/.../tasks/VkI5bTEzazdvNzlYNWVycw", "position": "00000000000000000001", "status": "needsAction", "links": [], "webViewLink": "https://tasks.google.com/task/VB9m13k7o79X5ers?sa=6" } ```
#### Clear Completed Tasks
Delete all completed tasks from a task list.
```bash POST /google-tasks/tasks/v1/lists/{tasklistId}/clear ```
Returns HTTP 204 No Content on success.
## Task Resource Fields
| Field | Type | Description | |-------|------|-------------| | `kind` | string | Always "tasks#task" (output only) | | `id` | string | Task identifier | | `etag` | string | ETag of the resource | | `title` | string | Task title (max 1024 characters) | | `updated` | string | Last modification time (RFC 3339, output only) | | `selfLink` | string | URL to this task (output only) | | `parent` | string | Parent task ID (output only) | | `position` | string | Position among siblings (output only) | | `notes` | string | Task notes (max 8192 characters) | | `status` | string | "needsAction" or "completed" | | `due` | string | Due date (RFC 3339 timestamp) | | `completed` | string | Completion date (RFC 3339, output only) | | `deleted` | boolean | Whether task is deleted | | `hidden` | boolean | Whether task is hidden | | `links` | array | Collection of links (output only) | | `webViewLink` | string | Link to task in Google Tasks UI (output only) |
## Task List Resource Fields
| Field | Type | Description | |-------|------|-------------| | `kind` | string | Always "tasks#taskList" (output only) | | `id` | string | Task list identifier | | `etag` | string | ETag of the resource | | `title` | string | Task list title (max 1024 characters) | | `updated` | string | Last modification time (RFC 3339, output only) | | `selfLink` | string | URL to this task list (output only) |
## Pagination
Use `maxResults` and `pageToken` for pagination:
```bash GET /google-tasks/tasks/v1/lists/{tasklistId}/tasks?maxResults=50 ```
Response includes `nextPageToken` when more results exist:
```json { "kind": "tasks#tasks", "etag": "...", "nextPageToken": "CgwI27nR6AUQsKHh7QIa...", "items": [...] } ```
Use the `nextPageToken` value in subsequent requests:
```bash GET /google-tasks/tasks/v1/lists/{tasklistId}/tasks?maxResults=50&pageToken=CgwI27nR6AUQsKHh7QIa... ```
## Code Examples
### JavaScript
```javascript // List all task lists const response = await fetch( 'https://gateway.maton.ai/google-tasks/tasks/v1/users/@me/lists', { headers: { 'Authorization': `Bearer ${process.env.MATON_API_KEY}` } } );
// Create a new task const createResponse = await fetch( `https://gateway.maton.ai/google-tasks/tasks/v1/lists/${tasklistId}/tasks`, { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.MATON_API_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ title: 'New Task', notes: 'Task description', due: '2026-03-01T00:00:00.000Z' }) } ); ```
### Python
```python import os import requests
# List all task lists response = requests.get( 'https://gateway.maton.ai/google-tasks/tasks/v1/users/@me/lists', headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'} )
# Create a new task create_response = requests.post( f'https://gateway.maton.ai/google-tasks/tasks/v1/lists/{tasklist_id}/tasks', headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}, json={ 'title': 'New Task', 'notes': 'Task description', 'due': '2026-03-01T00:00:00.000Z' } ) ```
## Notes
- Task list IDs and task IDs are opaque strings (base64-encoded) - Status values are "needsAction" or "completed" - Due dates are RFC 3339 timestamps - Maximum title length: 1024 characters - Maximum notes length: 8192 characters - 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. You may get "Invalid API key" errors when piping.
## Error Handling
| Status | Meaning | |--------|---------| | 400 | Missing Google Tasks connection | | 401 | Invalid or missing Maton API key | | 404 | Task or task list not found | | 429 | Rate limited | | 4xx/5xx | Passthrough error from Google Tasks API |
### Troubleshooting: API Key Issues
1. Check that the `MATON_API_KEY` environment variable is set:
```bash echo $MATON_API_KEY ```
2. Verify the API key is valid by listing connections:
```bash 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 `google-tasks`. For example:
- Correct: `https://gateway.maton.ai/google-tasks/tasks/v1/users/@me/lists` - Incorrect: `https://gateway.maton.ai/tasks/v1/users/@me/lists`
## Resources
- [Google Tasks API Overview](https://developers.google.com/workspace/tasks) - [Tasks Reference](https://developers.google.com/workspace/tasks/reference/rest/v1/tasks) - [TaskLists Reference](https://developers.google.com/workspace/tasks/reference/rest/v1/tasklists) - [Maton Community](https://discord.com/invite/dBfFAcefs2) - [Maton Support](mailto:[email protected])