(Morgen) Tasks
Morgen allows you to manage tasks through a unified API. The following documentations explains how to operate on first-party Morgen tasks. Tasks follow a data model inspired by the JSCalendar standard .
List tasks
Returns a list of tasks, optionally filtered by update time.
fetch(
"https://api.morgen.so/v3/tasks/list?limit=<LIMIT>&updatedAfter=<UPDATED_AFTER>",
{
method: "GET",
headers: {
accept: "application/json",
Authorization: "ApiKey <API_KEY>",
},
},
);| Parameter | Type | Default | Required | Description |
|---|---|---|---|---|
limit | Query | 1 | No | Maximum number of tasks to return (max 100). |
updatedAfter | Query | - | No | Only return tasks updated/created after this ISO 8601 datetime. |
limit defaults to 1, not to the maximum. Omitting it returns a single
task, which is easy to misread as an almost empty result. Always set it
explicitly.
The Tasks API is primarily designed for creating tasks in Morgen from unsupported integrations using apps like Zapier. Listing tasks costs 10 points per request. See Rate Limits for details.
Task schema
Here is an example response for the /tasks/list endpoint:
{
"data": {
"tasks": [
{
"@type": "Task",
"id": "WyJBUU1rQURaa1lXWXpOel...",
"accountId": "640a62c9aa5b7e06cf420000",
"integrationId": "morgen",
"taskListId": "default",
"created": "2023-02-28T11:50:57",
"updated": "2023-02-28T17:56:44",
"title": "Review quarterly report",
"description": "Review and provide feedback on Q4 report",
"descriptionContentType": "text/plain",
"due": "2023-03-15T17:00:00",
"timeZone": "Europe/Berlin",
"estimatedDuration": "PT2H",
"priority": 1,
"progress": "needs-action",
"position": 0,
"relatedTo": {
"parent-task-id": {
"@type": "Relation",
"relation": { "parent": true }
}
},
"tags": ["550e8400-e29b-41d4-a716-446655440000"],
"morgen.so:derived": {
"scheduled": true
}
}
],
"labelDefs": [],
"spaces": []
}
}Task Fields Reference
| Field | Type | Description |
|---|---|---|
@type | String | Always "Task" |
id | String | Morgen’s unique identifier for the task |
accountId | String | ID of the account the task belongs to |
integrationId | String | Integration provider ("morgen") |
taskListId | String | ID of the task list containing this task |
title | String | Task title/summary |
description | String | Task description (plain text or HTML) |
descriptionContentType | String | Either "text/plain" or "text/html" |
due | String | Due date in LocalDateTime format (e.g., "2023-03-15T17:00:00") |
timeZone | String | IANA timezone for the due date |
estimatedDuration | String | Estimated duration in ISO 8601 format (e.g., "PT2H") |
priority | Number | Priority level: 0 (undefined), 1 (highest) to 9 (lowest) |
progress | String | Status: "needs-action", "in-process", "completed", "failed", "cancelled" |
position | Number | Sort order within the task list |
relatedTo | Object | Relations to other tasks (for subtask hierarchies) |
tags | Array | Array of tag IDs assigned to this task (see Tags) |
created | String | Creation timestamp (UTC) |
updated | String | Last update timestamp (UTC) |
links | Object | Links attached to the task, keyed by link ID |
morgen.so:derived | Object | Read-only fields derived from the rest of the task, for example scheduled |
Alongside tasks, the response envelope carries two more arrays: labelDefs,
the label definitions referenced by task metadata, and spaces, the workspaces
the tasks belong to. Both are siblings of tasks under data, not fields on a
task.
Additional fields might be added in the future. If you are storing tasks in your database, please make sure to ignore unknown fields.
Get a task
Retrieve a single task by its ID.
fetch("https://api.morgen.so/v3/tasks?id=<TASK_ID>", {
method: "GET",
headers: {
accept: "application/json",
Authorization: "ApiKey <API_KEY>",
},
});| Parameter | Type | Default | Required | Description |
|---|---|---|---|---|
id | Query | - | Yes | The Morgen ID of the task to retrieve. |
Response
{
"data": {
"task": {
"@type": "Task",
"id": "WyJBUU1rQURaa1lXWXpOel...",
"taskListId": "default",
"title": "Review quarterly report",
"progress": "needs-action",
"created": "2023-02-28T11:50:57",
"updated": "2023-02-28T17:56:44"
},
"labelDefs": []
}
}The task object has the same shape as an entry in /tasks/list, see Task
Fields Reference. Fields with no value are omitted
rather than returned as null, so the exact set of keys varies by task.
Create a task
Create a new task in Morgen.
fetch("https://api.morgen.so/v3/tasks/create", {
method: "POST",
headers: {
accept: "application/json",
Authorization: "ApiKey <API_KEY>",
},
body: JSON.stringify({
title: "Review quarterly report",
description: "Review and provide feedback",
due: "2023-03-15T17:00:00",
timeZone: "Europe/Berlin",
priority: 1,
}),
});Request Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
title | String | Yes | Task title (minimum 1 character). |
description | String | No | Task description. |
descriptionContentType | String | No | "text/plain" or "text/html". Default: "text/plain". |
due | String | No | Due date in LocalDateTime format (exactly 19 characters: YYYY-MM-DDTHH:mm:ss). |
timeZone | String | No | IANA timezone for the due date. |
estimatedDuration | String | No | Estimated duration in ISO 8601 format. |
taskListId | String | No | ID of the task list to add the task to. |
priority | Number | No | Priority: 0 (undefined), 1 (highest) to 9 (lowest). |
progress | String | No | Initial status: "needs-action" or "completed". |
relatedTo | Object | No | Relations for creating subtasks. |
tags | Array | No | Array of tag IDs to assign to the task (see Tags). |
Response
Returns HTTP 200 OK on success, with the ID of the new task. Note that this is
200, not 201, and that the created task is not echoed back. If you need the
full object, follow up with Get a task.
{
"data": {
"id": "WyJBUU1rQURaa1lXWXpOel..."
}
}Creating Subtasks
To create a subtask, use the relatedTo field to specify the parent task:
{
"title": "Subtask title",
"relatedTo": {
"<PARENT_TASK_ID>": {
"@type": "Relation",
"relation": { "parent": true }
}
}
}Update a task
Update an existing task. Only include the fields you want to change.
fetch("https://api.morgen.so/v3/tasks/update", {
method: "POST",
headers: {
accept: "application/json",
Authorization: "ApiKey <API_KEY>",
},
body: JSON.stringify({
id: "<TASK_ID>",
title: "Updated title",
}),
});Request Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
id | String | Yes | The Morgen ID of the task to update. |
title | String | No | Updated task title. |
description | String | No | Updated description. |
due | String | No | Updated due date. |
timeZone | String | No | Updated timezone. |
taskListId | String | No | Move task to a different task list. |
priority | Number | No | Updated priority (0-9). |
progress | String | No | Updated status. |
tags | Array | No | Array of tag IDs (see Tags). |
Updates are patch updates. Only the fields you provide will be updated. All other fields remain unchanged.
Response
Returns HTTP 204 No Content on success.
Move a task
Reorder a task within its list or change its parent (for subtask hierarchies).
fetch("https://api.morgen.so/v3/tasks/move", {
method: "POST",
headers: {
accept: "application/json",
Authorization: "ApiKey <API_KEY>",
},
body: JSON.stringify({
id: "<TASK_ID>",
previousId: "<PREVIOUS_TASK_ID>",
parentId: "<PARENT_TASK_ID>",
}),
});Request Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
id | String | Yes | The Morgen ID of the task to move. |
previousId | String | No | ID of the task this should appear after. Use null to move to first position. |
parentId | String | No | ID of the parent task. Use null to move to root level. |
Response
Returns HTTP 204 No Content on success.
Delete a task
Delete a task permanently.
fetch("https://api.morgen.so/v3/tasks/delete", {
method: "POST",
headers: {
accept: "application/json",
Authorization: "ApiKey <API_KEY>",
},
body: JSON.stringify({
id: "<TASK_ID>",
}),
});Request Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
id | String | Yes | The Morgen ID of the task to delete. |
Response
Returns HTTP 204 No Content on success.
Close a task
Mark a task as completed.
fetch("https://api.morgen.so/v3/tasks/close", {
method: "POST",
headers: {
accept: "application/json",
Authorization: "ApiKey <API_KEY>",
},
body: JSON.stringify({
id: "<TASK_ID>",
}),
});Request Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
id | String | Yes | The Morgen ID of the task to close. |
occurrenceStart | String | No | For recurring tasks: ISO 8601 datetime of the specific occurrence to close. |
Response
Returns HTTP 204 No Content on success.
Reopen a task
Mark a completed task as not completed.
fetch("https://api.morgen.so/v3/tasks/reopen", {
method: "POST",
headers: {
accept: "application/json",
Authorization: "ApiKey <API_KEY>",
},
body: JSON.stringify({
id: "<TASK_ID>",
}),
});Request Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
id | String | Yes | The Morgen ID of the task to reopen. |
occurrenceStart | String | No | For recurring tasks: ISO 8601 datetime of the specific occurrence to reopen. |
Response
Returns HTTP 204 No Content on success.
Common Validation Errors
Invalid Due Date Format
Error Message:
due must be a valid ISO 8601 date stringCause: The due date is not in the correct format.
Solution: Use exactly 19 characters in LocalDateTime format: YYYY-MM-DDTHH:mm:ss
Example: "2023-03-15T17:00:00" (not "2023-03-15" or "2023-03-15T17:00:00Z")
Invalid Priority Value
Error Message:
priority must not be greater than 9
priority must not be less than 0Cause: Priority value is outside the valid range.
Solution: Use a value between 0 and 9, where 0 is undefined and 1 is highest priority.
Missing Required Title
Error Message:
title must be longer than or equal to 1 charactersCause: Task title is empty or missing.
Solution: Provide a title with at least 1 character when creating a task.