Skip to main content

Checklist Tasks

A checklist task is one of the steps a template wrote down, running inside a checklist. These routes read a checklist's tasks and do to them what a person does on the checklist page: complete a task or mark it not applicable, assign it, give it a due date, comment on it, snooze it, tag it and read its activity. Every route lives under the checklist, at /v3/checklists/{checklistKey}/tasks/{taskKey}, and a task key that belongs to a different checklist answers 404 exactly as a key that names nothing.

Only the checklist's own tasks are addressable here. A task somebody attached to the checklist afterwards is a standalone task: it is not in the task list, it answers 404 on every route on this page, and you read and change it at /v3/tasks/{taskKey} instead. GET /v3/checklists/{key}/attached-tasks on the Checklists page lists those.

Every write acts as the member the API key acts as (see Who a Key Acts As), is recorded in their name, and is checked against what they may do — Who Can Change a Task sets out the rules. Every write on this page accepts an Idempotency-Key header. Most of them name a state rather than an action, so repeating one is already harmless; the exception is Add a Comment, which says the same thing twice if it is sent twice without a key.

Endpoints​

All paths start /v3/checklists/{checklistKey}/tasks.

MethodPathDescriptionMCP tool
GET/List checklist taskslist_checklist_tasks
GET/{taskKey}Get a taskget_task
POST/{taskKey}/completeComplete a taskcomplete_task
DELETE/{taskKey}/completeUncomplete a taskuncomplete_task
POST/{taskKey}/not-applicableMark a task not applicableset_task_not_applicable
DELETE/{taskKey}/not-applicableClear not applicableclear_task_not_applicable
GET/{taskKey}/assigneesGet task assignees—
PUT/{taskKey}/assigneesAssign a taskset_task_assignees
DELETE/{taskKey}/assigneesUnassign a taskclear_task_assignees
GET/{taskKey}/due-dateGet the due date—
PUT/{taskKey}/due-dateSet the due dateset_task_due_date
DELETE/{taskKey}/due-dateClear the due dateclear_task_due_date
GET/{taskKey}/commentsList comments—
POST/{taskKey}/commentsAdd a commentadd_task_comment
DELETE/{taskKey}/comments/{commentId}Delete a commentremove_task_comment
GET/{taskKey}/snoozeGet the snoozeget_task_snooze
PUT/{taskKey}/snoozeSnooze a taskset_task_snooze
DELETE/{taskKey}/snoozeEnd a snoozeend_task_snooze
GET/{taskKey}/tagsList task tags—
POST/{taskKey}/tagsTag a taskadd_task_tags
DELETE/{taskKey}/tags?name=Untag a taskremove_task_tag
GET/{taskKey}/activityGet task activityget_task_activity

The reads marked — have no MCP tool because get_task already returns the assignees, due date, comments and tags. See Task Tools.

Fields, Files and Table Rows​

A task's input controls — Short Text, Dropdown, Date & Time, File Upload, Table and the rest (see Control Types) — are its fields in the API. They come back in the fields array of Get a Task, and they have routes of their own under /v3/checklists/{checklistKey}/tasks/{taskKey}/fields: read every field or one field, answer one field or up to 50 in a single call, add and remove the files on a File Upload field at .../fields/{fieldKey}/files, and add rows to, remove rows from and set cells in a Table field at .../fields/{fieldKey}/rows. Answering a field is what satisfies a required control, which is what lets a task be completed. The field object, the value each control type takes and those routes are documented on Task Fields.

Who Can Change a Task​

Reading a task — its list entry, detail, assignees, due date, comments, tags, activity, fields, files and table rows — needs permission to see the checklist, the same rule as reading the checklist itself on Checklists. A key that acts as an Administrator or as the workspace may read every checklist's tasks. A key that acts as a member may read them when the member's checklist permission on the template is Run and View or View But Not Run; with any other permission, or none, only when something in the checklist is assigned to them, directly or through a group. Otherwise the read is refused with 403 FORBIDDEN. A checklist in another workspace answers 404 CHECKLIST_NOT_FOUND rather than 403.

A member who may see the checklist may read all of its tasks. An exclusive assignment limits who may change a task, not who may read it.

Writes are checked against the member the key acts as. A key can never act as a Guest.

WriteWho may make itRefusal
Complete, uncomplete, mark or clear not applicableAn Administrator; a member whose checklist permission on the checklist is Run and View or Run and View Assigned To; or a member assigned to a task on the checklist.403 FORBIDDEN
Assign, unassign, set or clear the due dateAny Administrator or Member. When the task is assigned exclusively, only its assignees and Administrators. A key that acts as the workspace is refused.403 FORBIDDEN
Add a comment, tag or untagAny key for the workspace.—
Delete a commentThe comment's author or an Administrator.403 FORBIDDEN
Snooze, read or end a snoozeA key that acts as a member.403 API_KEY_ACTS_AS_WORKSPACE

Completing a task has three further checks of its own, answered with 409 CONFLICT — see Complete a Task.

An exclusive assignment (isAssignedExclusively) means only the task's assignees — and Administrators — may complete, reassign or re-date it. It has no effect while nobody is assigned: a task assigned exclusively to nobody is open to everybody.

The Task Object​

A task is returned in three sizes, each a superset of the one before:

  • Task summary — what List Checklist Tasks returns for each task: everything stored on the task's own row.
  • Task — the summary plus assignees, fields and comments. The status routes return this.
  • Task detail — the task plus checklist and tags. Get a Task returns this.
FieldTypeInDescription
keystring (GUID)AllThe task key — the taskKey in every route on this page.
namestringAllThe task's name.
orderintegerAllWhere the task sits on the checklist. The list is already in this order; compare the values rather than counting with them, because they are ascending but not always consecutive, and headings are numbered in the same sequence.
isHeadingbooleanAlltrue for a heading — a divider rather than work. A heading has no status, due date, assignees or comments, and the status, assignee, due date and comment writes refuse it.
statusstringAllIncomplete, Complete or NotApplicable. Absent for a heading. This is the field to branch on — the three states are exclusive.
isCompletebooleanAlltrue only when the task was completed. false for a not-applicable task and for a heading.
isNotApplicablebooleanAlltrue only when the task was marked not applicable. false for a heading.
isCurrentlyHaltedbooleanAlltrue while the task sits behind an incomplete halt task. A halted task cannot be completed.
isCurrentlyHiddenbooleanAlltrue while a condition is hiding the task. Hidden tasks are returned and flagged rather than left out, so that you choose whether to show them.
isAssignedExclusivelybooleanAlltrue when only the assignees may complete, reassign or re-date the task. Kept while nobody is assigned, when it has no effect, because it decides how the next assignment behaves.
dueDateTimestring (date-time)AllWhen the task is due. Absent when it has no due date.
completedDateTimestring (date-time)AllWhen the task was completed. Absent while it is not.
completedByuserAllWho completed it. Absent while nobody has, or when that member has since left the workspace.
notApplicableDateTimestring (date-time)AllWhen the task was marked not applicable. Absent while it is not.
notApplicableByuserAllWho marked it not applicable. Absent while nobody has, or when that member has since left.
assigneesarray of assigneeTask, detailWho the task is assigned to — groups first, then by name. Empty when nobody is.
fieldsarray of fieldTask, detailThe task's fields and their current values, leaving out any a condition is currently hiding. See Task Fields for the field object.
commentsarray of commentTask, detailThe task's comments, oldest first.
checklistchecklist referenceDetailThe checklist the task belongs to.
tagsarray of stringDetailThe task's own tags, by name, in name order. Tags on the checklist are not included.
{
"checklist": {
"key": "9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93",
"name": "Invoice Review — INV-2041",
"url": "https://app.checkflow.io/Checklist/Index?checklistKey=9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93",
"template": {
"key": "3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"name": "Invoice Review",
"url": "https://app.checkflow.io/Template/Index?templateKey=3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"version": 3
}
},
"tags": ["q3-audit"],
"assignees": [
{ "id": 12, "type": "Group", "name": "Finance Team" },
{ "id": 1043, "type": "TeamMember", "name": "James Okafor" }
],
"fields": [
{
"key": "c5a19e3d-4f72-4b08-9e6a-2d81f0b7c4e9",
"name": "Purchase Order Number",
"type": "ShortText",
"isRequired": true,
"value": "PO-7713"
}
],
"comments": [
{
"id": 88213,
"text": "Totals match the purchase order.",
"html": "<p>Totals match the purchase order.</p>",
"createdBy": { "name": "James Okafor", "email": "james.okafor@acme.example" },
"createdDateTime": "2026-09-29T10:14:22Z",
"mentions": []
}
],
"key": "e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68",
"name": "Match invoice to purchase order",
"order": 3,
"isHeading": false,
"status": "Incomplete",
"isComplete": false,
"isNotApplicable": false,
"isCurrentlyHalted": false,
"isCurrentlyHidden": false,
"isAssignedExclusively": false,
"dueDateTime": "2026-10-02T17:00:00Z"
}

The User Reference​

FieldTypeDescription
namestringThe member's full name.
emailstringThe member's email address.

The Checklist Reference​

FieldTypeDescription
keystring (GUID)The checklist key.
namestringThe checklist's name.
urlstringThe checklist's page in the app.
templateobjectThe template it was run from: key, name, url, version, and description and createdDateTime when the template has them.

The Assignee Object​

An assignee is a team member or a group. The same shape is used for a comment's mentions and for assignedMentioned on Add a Comment.

FieldTypeDescription
idintegerThe member's or group's id.
typestringTeamMember or Group. Part of the identity: member 12 and group 12 are different assignees.
namestringThe member's full name or the group's name. Absent for a member recorded with a surname and no first name.
{ "id": 1044, "type": "TeamMember", "name": "Priya Patel" }

Naming an Assignee​

Wherever a request names somebody — assignees on Assign a Task and mentions on Add a Comment — each entry takes one of two forms:

FormExampleMatched against
Type and id{ "type": "TeamMember", "id": 1044 }The member or group with that id. type is TeamMember or Group, case-insensitive, and is required with an id.
Name{ "name": "priya.patel@acme.example" }A member's full name, a member's email address, or a group's name, case-insensitively. Ignored when id is given.
  • Only people and groups the workspace can assign match. That is every active Administrator, Member and Guest, and every group — the lists GET /v3/workspace returns. Deactivated members do not match.
  • A name that matches more than one member or group is refused with 400 VALIDATION_ERROR, and the message lists the candidates by type and id so that you can name the one you mean. Nothing is guessed.
  • Prefer the email address for a person. It is always present and always unique; a member recorded with a surname and no first name has no full name to match at all.
  • The types Unassigned, CurrentUser and ChecklistCreator that template assignment rules use are not accepted — they are refused with 400 on type.

The Comment Object​

FieldTypeDescription
idintegerThe comment's id — what Delete a Comment takes.
textstringWhat the comment says, with the markup removed. Paragraphs are separated by a blank line and line breaks by a newline, and a mention reads as the name it was written against. Read this unless you need the markup. Empty for a comment that is only an attachment.
htmlstringThe comment as stored and as the checklist page renders it. Absent for a comment that is only an attachment. Comments written before v3 were stored as the browser sent them, so do not re-render this elsewhere without sanitising it.
createdByuserWho wrote it. An author who has since left the workspace keeps their name and loses their email.
createdDateTimestring (date-time)When it was written.
attachmentobjectThe file attached to the comment: name, contentType and url. Absent when there is none.
mentionsarray of assigneeEverybody the comment mentions, in the order it mentions them, each listed once. name is the name the mention was written against, not necessarily what the member or group is called now. Read from the comment's own markup, so it always agrees with what the comment says.
warning

An attachment's url is not protected by your API key — anybody holding the address can download the file. Treat it as a secret rather than a link to publish.

{
"id": 88240,
"text": "Over to @Priya Patel for sign-off.",
"html": "<p>Over to <span contenteditable=\"false\"><a class=\"mention-link\" data-id=\"1044\" data-assignable-type=\"1\">@Priya Patel</a></span> for sign-off.</p>",
"createdBy": { "name": "Sarah Chen", "email": "sarah.chen@acme.example" },
"createdDateTime": "2026-09-29T11:02:07Z",
"attachment": {
"name": "INV-2041.pdf",
"contentType": "application/pdf",
"url": "https://storage.example/attachments/5b7e0c1d/INV-2041.pdf"
},
"mentions": [
{ "id": 1044, "type": "TeamMember", "name": "Priya Patel" }
]
}

Comments cannot be edited, through the API or in the app. A comment is written once and either stays or is deleted whole.

List Checklist Tasks​

Returns every task on a checklist, in the order the checklist page lays them out, headings included. Use it to see what is left to do: it reads the whole checklist in two queries, where Get a Task and GET /v3/checklists/{key} also load each task's fields, assignees and comments.

GET /v3/checklists/{checklistKey}/tasks

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
statusquerystringNoComma-separated statuses to return: Incomplete, Complete, NotApplicable. Case, spaces, hyphens and underscores are ignored, so not-applicable works. Omit it for every task, headings included; because a heading has no status, any status filter leaves headings out. Any other value, or an empty status=, is refused.

The response is not paged: a checklist has as many tasks as its template gave it, and they all come back at once. For tasks across many checklists — what is assigned to you, what is overdue — use the Tasks grid.

Example​

GET https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"tasks": [
{
"key": "5a0f3d92-8e61-4c7b-9f24-1d6b8e3a7c05",
"name": "Verification",
"order": 1,
"isHeading": true,
"isComplete": false,
"isNotApplicable": false,
"isCurrentlyHalted": false,
"isCurrentlyHidden": false,
"isAssignedExclusively": false
},
{
"key": "b81c55e0-2f4a-4d6b-a1e9-7c3d0f2e8a46",
"name": "Check supplier details",
"order": 2,
"isHeading": false,
"status": "Complete",
"isComplete": true,
"isNotApplicable": false,
"isCurrentlyHalted": false,
"isCurrentlyHidden": false,
"isAssignedExclusively": false,
"completedDateTime": "2026-09-28T15:41:09Z",
"completedBy": { "name": "James Okafor", "email": "james.okafor@acme.example" }
},
{
"key": "e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68",
"name": "Match invoice to purchase order",
"order": 3,
"isHeading": false,
"status": "Incomplete",
"isComplete": false,
"isNotApplicable": false,
"isCurrentlyHalted": false,
"isCurrentlyHidden": false,
"isAssignedExclusively": false,
"dueDateTime": "2026-10-02T17:00:00Z"
},
{
"key": "71f8b3c6-0d2e-4a95-8b17-c4e6a9d2f053",
"name": "Approve payment",
"order": 4,
"isHeading": false,
"status": "Incomplete",
"isComplete": false,
"isNotApplicable": false,
"isCurrentlyHalted": true,
"isCurrentlyHidden": false,
"isAssignedExclusively": true
}
]
}

Each entry is a task summary.

Responses​

StatusCodeWhen
200—The checklist's tasks.
400VALIDATION_ERRORchecklistKey is not a GUID, or status names something other than the three statuses (field is status).
403FORBIDDENThe member the key acts as may not see this checklist. See Who Can Change a Task.
404CHECKLIST_NOT_FOUNDNo checklist with that key in your workspace.

Get a Task​

Returns one task in full: its state, assignees, fields and their values, comments, tags and the checklist it belongs to.

GET /v3/checklists/{checklistKey}/tasks/{taskKey}

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.

Example​

GET https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK

The body is a task detail, as in the example under The Task Object.

Responses​

StatusCodeWhen
200—The task.
400VALIDATION_ERRORchecklistKey or taskKey is not a GUID.
403FORBIDDENThe member the key acts as may not see this checklist. See Who Can Change a Task.
404CHECKLIST_NOT_FOUNDNo checklist with that key in your workspace.
404TASK_NOT_FOUNDNo task with that key on this checklist — including a standalone task attached to it.

Complete a Task​

Marks a task complete. Use this rather than Mark a Task Not Applicable when the work was done: a completed task is credited to the member the key acts as.

POST /v3/checklists/{checklistKey}/tasks/{taskKey}/complete

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.

Request Body​

This endpoint takes no request body.

Example​

POST https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68/complete
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"assignees": [
{ "id": 12, "type": "Group", "name": "Finance Team" },
{ "id": 1043, "type": "TeamMember", "name": "James Okafor" }
],
"fields": [
{
"key": "c5a19e3d-4f72-4b08-9e6a-2d81f0b7c4e9",
"name": "Purchase Order Number",
"type": "ShortText",
"isRequired": true,
"value": "PO-7713"
}
],
"comments": [],
"key": "e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68",
"name": "Match invoice to purchase order",
"order": 3,
"isHeading": false,
"status": "Complete",
"isComplete": true,
"isNotApplicable": false,
"isCurrentlyHalted": false,
"isCurrentlyHidden": false,
"isAssignedExclusively": false,
"dueDateTime": "2026-10-02T17:00:00Z",
"completedDateTime": "2026-09-30T09:12:45Z",
"completedBy": { "name": "James Okafor", "email": "james.okafor@acme.example" }
}

The body is the task as it now stands, read back after the change.

Responses​

StatusCodeWhen
200—The task is complete — including when it already was, in which case nothing is written.
400VALIDATION_ERRORA key is not a GUID, or the task is a heading (field is checklistTaskId).
403FORBIDDENThe member the key acts as may not change this checklist's tasks. See Who Can Change a Task.
404CHECKLIST_NOT_FOUND / TASK_NOT_FOUNDNo such checklist, or no such task on it.
409CONFLICTThe task cannot be completed yet — see below. The message says which reason applies.

When Completion Is Refused​

A task is checked in this order, and the first failure is returned as 409 CONFLICT:

  1. It is halted. The task sits behind an incomplete halt task (isCurrentlyHalted is true). Complete the halt task first. The halt task itself is never halted.
  2. It is assigned exclusively to somebody else. Only its assignees and Administrators may complete it.
  3. A required field is empty. Answer it through Task Fields and try again.

What counts as an empty required field depends on the control. Fields a condition is currently hiding are skipped.

ControlHolds the task open when
Short Text, Long Text, E-Mail, WebsiteIt is required and empty.
Date & TimeIt is required and has no value.
Dropdown, Multi-ChoiceIt is required and nothing is selected.
MembersIt is required and nobody is selected.
Sub-TasksIt is required and any sub-task is unticked.
File UploadIt holds fewer files than its minimum, or more than its maximum.
Mail-ToIt is set to be sent from the task and has not been sent.

A required Table does not hold a task open.

Notes​

  • Completing a task does everything completing it in the app does. It fires the task_completed webhook, records an activity entry, notifies Administrators and the task's assignees (not the member who completed it), releases tasks halted behind it, re-evaluates dynamic due dates across the checklist, and marks the checklist complete — notifying Administrators and the checklist's assignees — when this was the last task outstanding.
  • Repeating it is harmless. Completing a task that is already complete writes nothing, fires nothing and notifies nobody, and still answers 200.
  • The response reflects any change the conditions engine made to this task as a result. Other tasks may have been released or hidden too; list the tasks again to see them.

Uncomplete a Task​

Returns a completed task to Incomplete, and reopens the checklist if completing this task had finished it.

DELETE /v3/checklists/{checklistKey}/tasks/{taskKey}/complete

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.

Example​

DELETE https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68/complete
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK

The body is the task as it now stands, with status Incomplete and no completedDateTime or completedBy.

Responses​

StatusCodeWhen
200—The task is not complete — including when it was not complete to begin with.
400VALIDATION_ERRORA key is not a GUID, or the task is a heading (field is checklistTaskId).
403FORBIDDENThe member the key acts as may not change this checklist's tasks.
404CHECKLIST_NOT_FOUND / TASK_NOT_FOUNDNo such checklist, or no such task on it.

Notes​

  • This clears completion and nothing else. A task marked not applicable is left not applicable and the call still answers 200 — use Clear Not Applicable for that. Each state has one route back to Incomplete, so neither can undo the other by accident.
  • Uncompleting is never refused for halts, exclusive assignment or required fields; those checks apply only to completing.
  • It records an activity entry and notifies Administrators and the task's assignees, as completing does, and re-evaluates halts and due dates across the checklist.

Mark a Task Not Applicable​

Marks a task as not needing to be done. A not-applicable task stops holding the checklist open and releases any tasks halted behind it, exactly as completing it would, but it reads as NotApplicable and nobody is credited with doing it.

POST /v3/checklists/{checklistKey}/tasks/{taskKey}/not-applicable

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.

Request Body​

This endpoint takes no request body.

Example​

POST https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/71f8b3c6-0d2e-4a95-8b17-c4e6a9d2f053/not-applicable
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK

The body is the task as it now stands, with status NotApplicable, isNotApplicable true and notApplicableDateTime and notApplicableBy filled in.

Responses​

StatusCodeWhen
200—The task is not applicable — including when it already was.
400VALIDATION_ERRORA key is not a GUID, or the task is a heading (field is checklistTaskId).
403FORBIDDENThe member the key acts as may not change this checklist's tasks.
404CHECKLIST_NOT_FOUND / TASK_NOT_FOUNDNo such checklist, or no such task on it.

Notes​

  • It is never refused for empty required fields, a halt or an exclusive assignment — only the permission check in Who Can Change a Task applies.
  • Marking a completed task not applicable replaces the completion.
  • It records an activity entry, notifies Administrators and the task's assignees, re-evaluates halts and due dates, and completes the checklist if this was the last task outstanding. It does not fire the task_completed webhook.

Clear Not Applicable​

Returns a not-applicable task to Incomplete.

DELETE /v3/checklists/{checklistKey}/tasks/{taskKey}/not-applicable

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.

Example​

DELETE https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/71f8b3c6-0d2e-4a95-8b17-c4e6a9d2f053/not-applicable
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK

The body is the task as it now stands, with status Incomplete.

Responses​

StatusCodeWhen
200—The task is not marked not applicable — including when it was not to begin with.
400VALIDATION_ERRORA key is not a GUID, or the task is a heading (field is checklistTaskId).
403FORBIDDENThe member the key acts as may not change this checklist's tasks.
404CHECKLIST_NOT_FOUND / TASK_NOT_FOUNDNo such checklist, or no such task on it.

Notes​

  • A completed task is left completed. This route clears not applicable and nothing else; use Uncomplete a Task to clear a completion.

Get Task Assignees​

Returns who a task is assigned to and whether the assignment is exclusive. The same assignees are on Get a Task; this is the smaller read.

GET /v3/checklists/{checklistKey}/tasks/{taskKey}/assignees

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.

Example​

GET https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68/assignees
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"assignees": [
{ "id": 12, "type": "Group", "name": "Finance Team" },
{ "id": 1043, "type": "TeamMember", "name": "James Okafor" }
],
"isAssignedExclusively": false
}
FieldTypeDescription
assigneesarray of assigneeEverybody the task is assigned to — groups first, then by name, then by id, so two reads of an unchanged task answer identically. Empty when nobody is.
isAssignedExclusivelybooleantrue when only these assignees (and Administrators) may complete, reassign or re-date the task.

Responses​

StatusCodeWhen
200—Who the task is assigned to.
400VALIDATION_ERRORA key is not a GUID.
403FORBIDDENThe member the key acts as may not see this checklist. See Who Can Change a Task.
404CHECKLIST_NOT_FOUND / TASK_NOT_FOUNDNo such checklist, or no such task on it.

Assign a Task​

Sets who a task is assigned to. The list replaces the task's assignees: anybody not in it is unassigned. To add somebody, read the current assignees and send them back with the new one.

PUT /v3/checklists/{checklistKey}/tasks/{taskKey}/assignees

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.

Request Body​

{
"assignees": [
{ "type": "Group", "id": 12 },
{ "name": "priya.patel@acme.example" }
],
"isAssignedExclusively": false
}
FieldTypeRequiredDescription
assigneesarrayNoWho the task is assigned to afterwards. Each entry is { "type", "id" } or { "name" } — see Naming an Assignee. An empty or missing list unassigns the task. Naming the same assignee twice is not an error.
isAssignedExclusivelybooleanNotrue to let only the assignees (and Administrators) complete, reassign or re-date the task. Defaults to false, and it is written on every call — send the current value back if you mean to keep it.

Example​

PUT https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68/assignees
X-API-KEY: your-api-key-here
Content-Type: application/json

{
"assignees": [
{ "type": "Group", "id": 12 },
{ "name": "priya.patel@acme.example" }
],
"isAssignedExclusively": false
}
HTTP/1.1 200 OK
{
"assignees": [
{ "id": 12, "type": "Group", "name": "Finance Team" },
{ "id": 1044, "type": "TeamMember", "name": "Priya Patel" }
],
"isAssignedExclusively": false
}

The body has the same shape as Get Task Assignees.

Responses​

StatusCodeWhen
200—The task is assigned as the body says — including when it already was.
400VALIDATION_ERRORA key is not a GUID; the task is a heading (field is checklistTaskId); an entry names nobody (assignees[0]), gives an id without a type or an unknown type (assignees[0].type), or gives a name that matches nobody or more than one assignee (assignees[0].name); or an id is not somebody this workspace can assign (assignees).
403FORBIDDENThe key acts as the workspace, or the task is assigned exclusively and the member the key acts as is neither an assignee nor an Administrator.
404CHECKLIST_NOT_FOUND / TASK_NOT_FOUNDNo such checklist, or no such task on it.

Notes​

  • Newly assigned people are notified, as they are when assigned in the app. Anybody already on the task is not notified again, so sending the same body twice writes nothing and tells nobody.
  • Nobody is told they have been unassigned.
  • An assignee a dynamic assignment put on the task stays linked to it when you send them back in the list.

Unassign a Task​

Assigns a task to nobody — the same write as Assign a Task with an empty list, without composing a body.

DELETE /v3/checklists/{checklistKey}/tasks/{taskKey}/assignees

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.

Example​

DELETE https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68/assignees
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"assignees": [],
"isAssignedExclusively": true
}

Responses​

StatusCodeWhen
200—Nobody is assigned — including when nobody was.
400VALIDATION_ERRORA key is not a GUID, or the task is a heading (field is checklistTaskId).
403FORBIDDENThe key acts as the workspace, or the task is assigned exclusively and the member the key acts as is neither an assignee nor an Administrator.
404CHECKLIST_NOT_FOUND / TASK_NOT_FOUNDNo such checklist, or no such task on it.

Notes​

  • isAssignedExclusively is kept as it was, unlike a PUT with an empty list, which sets it to whatever the body says. It has no effect while nobody is assigned, and keeping it means the next assignment starts on the same terms as the last.
  • Nobody is notified.

Get the Due Date​

Returns when a task is due, and whether the template works the date out for itself. The date is also on every read of the task; isRuleGoverned is only here.

GET /v3/checklists/{checklistKey}/tasks/{taskKey}/due-date

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.

Example​

GET https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68/due-date
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"dueDateTime": "2026-10-02T17:00:00Z",
"isRuleGoverned": false
}
FieldTypeDescription
dueDateTimestring (date-time)When the task is due, in UTC. Absent when it has no due date.
isRuleGovernedbooleantrue when a dynamic due date rule on the template dates this task. A date you set still applies, but only until the rule is next evaluated — for example when the task it counts from is completed.

Responses​

StatusCodeWhen
200—When the task is due.
400VALIDATION_ERRORA key is not a GUID.
403FORBIDDENThe member the key acts as may not see this checklist. See Who Can Change a Task.
404CHECKLIST_NOT_FOUND / TASK_NOT_FOUNDNo such checklist, or no such task on it.

Set the Due Date​

Says when a task is due.

PUT /v3/checklists/{checklistKey}/tasks/{taskKey}/due-date

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.

Request Body​

{
"dueDateTime": "2026-10-02T17:00:00Z"
}
FieldTypeRequiredDescription
dueDateTimestring (date-time)NoWhen the task is due. A date without an offset is read as UTC — see Dates and Times. A date in the past is accepted and makes the task overdue. null, or leaving the field out, clears the due date — the same as Clear the Due Date.

Example​

PUT https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68/due-date
X-API-KEY: your-api-key-here
Content-Type: application/json

{
"dueDateTime": "2026-10-02T17:00:00Z"
}
HTTP/1.1 200 OK
{
"dueDateTime": "2026-10-02T17:00:00Z",
"isRuleGoverned": false
}

The body has the same shape as Get the Due Date.

Responses​

StatusCodeWhen
200—The task is due when the body says — including when it already was.
400VALIDATION_ERRORA key is not a GUID; the body is missing or is not valid JSON; the task is a heading (field is checklistTaskId); or the date is 0001-01-01T00:00:00Z, which cannot be told apart from no date (field is dueDate).
403FORBIDDENThe key acts as the workspace, or the task is assigned exclusively and the member the key acts as is neither an assignee nor an Administrator.
404CHECKLIST_NOT_FOUND / TASK_NOT_FOUNDNo such checklist, or no such task on it.

Notes​

  • Setting the date the task already has writes nothing. That matters because every change reschedules the task's due date reminders.
  • A rule-governed task is dated anyway. Naming one task is an override, as it is in the app, and the response says isRuleGoverned: true so that you know the date lasts only until the rule next runs.
  • Nobody is notified.

Clear the Due Date​

Says a task is not due by any particular time. The same write as sending "dueDateTime": null.

DELETE /v3/checklists/{checklistKey}/tasks/{taskKey}/due-date

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.

Example​

DELETE https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68/due-date
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"isRuleGoverned": false
}

dueDateTime is absent because the task no longer has one.

Responses​

StatusCodeWhen
200—The task has no due date — including when it had none.
400VALIDATION_ERRORA key is not a GUID, or the task is a heading (field is checklistTaskId).
403FORBIDDENThe key acts as the workspace, or the task is assigned exclusively and the member the key acts as is neither an assignee nor an Administrator.
404CHECKLIST_NOT_FOUND / TASK_NOT_FOUNDNo such checklist, or no such task on it.

Notes​

  • Reminders scheduled against the old date stop. Nobody is notified.

List Comments​

Returns a task's comments, oldest first. The same comments are on Get a Task.

GET /v3/checklists/{checklistKey}/tasks/{taskKey}/comments

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.

Example​

GET https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68/comments
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"comments": [
{
"id": 88213,
"text": "Totals match the purchase order.",
"html": "<p>Totals match the purchase order.</p>",
"createdBy": { "name": "James Okafor", "email": "james.okafor@acme.example" },
"createdDateTime": "2026-09-29T10:14:22Z",
"mentions": []
}
]
}

comments is an array of comment objects. It is not paged. A heading answers with an empty list.

Responses​

StatusCodeWhen
200—The task's comments.
400VALIDATION_ERRORA key is not a GUID.
403FORBIDDENThe member the key acts as may not see this checklist. See Who Can Change a Task.
404CHECKLIST_NOT_FOUND / TASK_NOT_FOUNDNo such checklist, or no such task on it.

Add a Comment​

Adds a comment to a task, written as the member the key acts as, optionally mentioning people and carrying a file.

POST /v3/checklists/{checklistKey}/tasks/{taskKey}/comments

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.

Request Body​

{
"text": "Over to Priya Patel for sign-off.\n\nThe invoice is attached.",
"mentions": [
{ "name": "priya.patel@acme.example" }
],
"attachment": {
"name": "INV-2041.pdf",
"contentType": "application/pdf",
"content": "JVBERi0xLjcKJeLjz9MK..."
}
}
FieldTypeRequiredDescription
textstringNoWhat to say, as plain text. Send text or html, not both.
htmlstringNoWhat to say, as HTML. Send html or text, not both.
mentionsarrayNoPeople and groups to mention, each named as in Naming an Assignee.
assignMentionedbooleanNoWhether mentioning somebody on an exclusively assigned task also assigns them to it. Default true.
attachmentobjectNoA file to attach.
attachment.namestringWith attachmentThe file name to record.
attachment.contentstringWith attachmentThe file's bytes, base64 encoded. At most 32 MB.
attachment.contentTypestringNoThe file's media type. Recorded as application/octet-stream when you leave it out.

A comment needs something in it: text, html, at least one mention, or an attachment. One with none of these is refused.

Text and HTML​

text is plain text. It is escaped and wrapped into paragraphs: a blank line starts a new paragraph, a single newline is a line break, and anything that looks like markup is shown as typed rather than obeyed. Markdown is not rendered — **bold** is stored as the characters you sent. Use text unless you have HTML.

html is filtered through an allow-list. Elements not on the list are unwrapped — the markup goes and the words inside it are kept. Attributes not on the list are dropped.

AllowedElementsAttributes kept
Blocksp, div, blockquote, pre, h1–h6, bralign on div
Lists and tablesul, ol, li, table, thead, tbody, tfoot, tr, td, th—
Inlineb, strong, i, em, u, s, strike, sub, sup, code, spanclass and contenteditable on span
Linksahref, class, data-id, data-assignable-type
  • A link's href survives only when it is relative or its scheme is http, https or mailto. Any other scheme, such as javascript:, loses its href.
  • script, style, iframe, object, embed, noscript, svg, math, template, head, title, link, meta and base are removed together with their contents, and HTML comments are removed.
  • HTML that is nothing but markup — for example only a script element — is refused rather than stored as an empty comment.

Mentions​

A mention notifies the person or group it names. There are two ways to write one.

Name them in mentions (recommended). Each entry is resolved against the workspace and turned into a mention where the comment already says the name: the first place the comment's text reads Priya Patel or @Priya Patel (case-insensitively) becomes the mention, written in the workspace's own spelling of the name. A mention whose name does not appear in the comment is added on a line of its own at the end. A comment can be nothing but mentions.

Write the anchor in html. A mention is this exact markup, which the allow-list keeps:

<a class="mention-link" data-id="1044" data-assignable-type="1">@Priya Patel</a>

data-id is the member or group id and data-assignable-type is 1 for a member or 2 for a group. The class must be exactly mention-link. If mentions names somebody the markup already mentions, they are mentioned once.

What a mention does:

  • Everybody mentioned is emailed and notified in Slack, however the task is assigned.
  • On a task assigned exclusively, anybody mentioned who is not already an assignee — other than an Administrator — is added to the assignees, so that they can open the task. The response lists them in assignedMentioned. Send "assignMentioned": false when you are telling somebody rather than asking them: they are still notified but not assigned.
  • On a task that is not assigned exclusively, or that nobody is assigned to, nobody is assigned.

Example​

POST https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68/comments
X-API-KEY: your-api-key-here
Content-Type: application/json
Idempotency-Key: 6a9c2e4f-comment-inv-2041

{
"text": "Over to Priya Patel for sign-off.",
"mentions": [
{ "name": "priya.patel@acme.example" }
]
}
HTTP/1.1 201 Created
{
"comment": {
"id": 88240,
"text": "Over to @Priya Patel for sign-off.",
"html": "<p>Over to <span contenteditable=\"false\"><a class=\"mention-link\" data-id=\"1044\" data-assignable-type=\"1\">@Priya Patel</a></span> for sign-off.</p>",
"createdBy": { "name": "Sarah Chen", "email": "sarah.chen@acme.example" },
"createdDateTime": "2026-09-29T11:02:07Z",
"mentions": [
{ "id": 1044, "type": "TeamMember", "name": "Priya Patel" }
]
},
"assignedMentioned": []
}
FieldTypeDescription
commentcommentThe comment as stored, with its id.
assignedMentionedarray of assigneeAnybody the comment's mentions added to the task's assignees. Empty unless the task is assigned exclusively and assignMentioned was not false. This is not the list of who was mentioned or notified — that is comment.mentions.

Responses​

StatusCodeWhen
201—The comment was added.
400VALIDATION_ERRORA key is not a GUID; the body is missing or not valid JSON; both text and html were sent (html); the comment is empty (text), or its html was all removed by the allow-list (html); a mention names nobody, gives an id without a type, gives an id or name the workspace does not have, or a name that matches more than one assignee (mentions[0], mentions[0].type, mentions[0].name); the attachment has no name (attachment.name), is not base64 or is over 32 MB (attachment.content); or the task is a heading (taskKey).
404CHECKLIST_NOT_FOUND / TASK_NOT_FOUNDNo such checklist, or no such task on it.

Notes​

  • Everybody assigned to the task is emailed and notified in Slack, as they are for a comment left in the app, as well as everybody mentioned.
  • This write is not idempotent on its own — sending it twice posts two comments. Send an Idempotency-Key if you may retry.
  • The MCP tool add_task_comment takes text, html, mentions and assignMentioned, but not an attachment.

Delete a Comment​

Deletes one comment, and its attachment with it.

DELETE /v3/checklists/{checklistKey}/tasks/{taskKey}/comments/{commentId}

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.
commentIdpathintegerYesThe comment's id, from List Comments or Get a Task.

Example​

DELETE https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68/comments/88240
X-API-KEY: your-api-key-here

Responds 204 No Content with no body.

Responses​

StatusCodeWhen
204—The comment and any attachment were deleted.
400VALIDATION_ERRORA key is not a GUID, or commentId is not a positive whole number (commentId).
403FORBIDDENThe member the key acts as did not write the comment and is not an Administrator.
404CHECKLIST_NOT_FOUND / TASK_NOT_FOUNDNo such checklist, or no such task on it.
404COMMENT_NOT_FOUNDNo comment with that id on this task — including one that has already been deleted, or one on a different task.
danger

Deleting a comment is permanent. The comment and its attached file cannot be recovered, and there is no edit to use instead.

Get the Snooze​

Says whether the task is snoozed for the member the key acts as, and until when. A snooze is personal: it hides the task from one person's Tasks grid and changes nothing anybody else sees, so two keys acting as different members can get different answers for the same task.

GET /v3/checklists/{checklistKey}/tasks/{taskKey}/snooze

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.

Example​

GET https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68/snooze
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"isSnoozed": true,
"snoozedUntil": "2026-10-05T08:00:00Z"
}
FieldTypeDescription
isSnoozedbooleanWhether the task is hidden from this member's Tasks grid right now. A snooze whose date has passed reads as false.
snoozedUntilstring (date-time)When the snooze runs out, in UTC. Still reported after it has passed, until the expired snooze is cleaned up, so that "snoozed and ran out" can be told apart from "never snoozed". Absent when this member has not snoozed the task.

Responses​

StatusCodeWhen
200—The snooze state for the acting member.
400VALIDATION_ERRORA key is not a GUID.
403API_KEY_ACTS_AS_WORKSPACEThe key acts as the workspace, which has nobody to snooze a task for (field is X-API-KEY).
404CHECKLIST_NOT_FOUND / TASK_NOT_FOUNDNo such checklist, or no such task on it.

Snooze a Task​

Hides the task from the Tasks grid of the member the key acts as until a date you choose. To snooze many tasks at once, see bulk snooze.

PUT /v3/checklists/{checklistKey}/tasks/{taskKey}/snooze

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.

Request Body​

{
"snoozedUntil": "2026-10-05T08:00:00Z"
}
FieldTypeRequiredDescription
snoozedUntilstring (date-time)YesWhen the snooze runs out. Must be in the future. A date without an offset is read as UTC. null does not clear a snooze — use End a Snooze.

Example​

PUT https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68/snooze
X-API-KEY: your-api-key-here
Content-Type: application/json

{
"snoozedUntil": "2026-10-05T08:00:00Z"
}
HTTP/1.1 200 OK
{
"isSnoozed": true,
"snoozedUntil": "2026-10-05T08:00:00Z"
}

snoozedUntil is the value stored, in UTC — a date sent with an offset comes back converted.

Responses​

StatusCodeWhen
200—The task is snoozed until the date given. Sending the same date again stores it again and still answers 200.
400VALIDATION_ERRORA key is not a GUID; the body is missing or not valid JSON; or snoozedUntil is missing, null or not in the future (snoozedUntil).
403API_KEY_ACTS_AS_WORKSPACEThe key acts as the workspace (field is X-API-KEY).
404CHECKLIST_NOT_FOUND / TASK_NOT_FOUNDNo such checklist, or no such task on it.

Notes​

  • Nobody else is affected. No activity entry is recorded, nobody is notified, no webhook fires, and the task goes on appearing on everybody else's Tasks grid.

End a Snooze​

Returns the task to the Tasks grid of the member the key acts as.

DELETE /v3/checklists/{checklistKey}/tasks/{taskKey}/snooze

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.

Example​

DELETE https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68/snooze
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"isSnoozed": false
}

Responses​

StatusCodeWhen
200—The task is not snoozed for this member — including when it was not snoozed, or its snooze had already run out. The response is the same in every case.
400VALIDATION_ERRORA key is not a GUID.
403API_KEY_ACTS_AS_WORKSPACEThe key acts as the workspace (field is X-API-KEY).
404CHECKLIST_NOT_FOUND / TASK_NOT_FOUNDNo such checklist, or no such task on it.

Notes​

  • Nobody else is affected and nothing is announced.

List Task Tags​

Returns the tags on a task, by name, in name order. A task's tags are its own: tagging a checklist does not tag its tasks, and this returns none of the checklist's tags — those are on the Checklists routes.

GET /v3/checklists/{checklistKey}/tasks/{taskKey}/tags

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.

Example​

GET https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68/tags
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"tags": ["q3-audit", "urgent"]
}

Responses​

StatusCodeWhen
200—The task's tags.
400VALIDATION_ERRORA key is not a GUID.
403FORBIDDENThe member the key acts as may not see this checklist. See Who Can Change a Task.
404CHECKLIST_NOT_FOUND / TASK_NOT_FOUNDNo such checklist, or no such task on it.

Tag a Task​

Puts one or more tags on a task, by name. The rules for tag names are the same as on a checklist — see Tags.

POST /v3/checklists/{checklistKey}/tasks/{taskKey}/tags

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.

Request Body​

{
"tags": ["urgent", "q3-audit"]
}
FieldTypeRequiredDescription
tagsarray of stringYesThe tag names. At least one and at most 25, counted after blanks are dropped, names are trimmed and duplicates are collapsed case-insensitively. Each at most 100 characters.

Example​

POST https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68/tags
X-API-KEY: your-api-key-here
Content-Type: application/json

{
"tags": ["urgent", "q3-audit"]
}
HTTP/1.1 200 OK
{
"created": [],
"tags": ["q3-audit", "urgent"]
}
FieldTypeDescription
createdarray of stringTags that did not exist anywhere in the workspace until this call created them. Usually empty.
tagsarray of stringEvery tag now on the task, in name order.

Responses​

StatusCodeWhen
200—The tags are on the task — including any it already carried, which are not written again.
400VALIDATION_ERRORA key is not a GUID; the body is missing or not valid JSON; or tags names no tag, more than 25, or one longer than 100 characters (tags).
404CHECKLIST_NOT_FOUND / TASK_NOT_FOUNDNo such checklist, or no such task on it.
warning

A name the workspace has not used before creates a new tag — there is no separate step for creating one. A misspelling therefore succeeds and adds a tag; check created to catch it, or read the existing names from GET /v3/workspace first. Matching is case-insensitive, so Urgent and urgent are one tag.

Untag a Task​

Takes one tag off a task. The name goes in the name query parameter rather than the path, because a tag name may contain any character, including a slash.

DELETE /v3/checklists/{checklistKey}/tasks/{taskKey}/tags?name={name}

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.
namequerystringYesThe tag to remove, URL-encoded. Matched case-insensitively. At most 100 characters.

Example​

DELETE https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/e27c9a14-6b3d-4f8e-a5c1-9d0b2f7e4a68/tags?name=urgent
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"tagDeleted": false,
"tags": ["q3-audit"]
}
FieldTypeDescription
tagDeletedbooleantrue when that was the tag's last use anywhere in the workspace, so the workspace no longer has the tag at all. false when the tag was not on the task.
tagsarray of stringThe tags left on the task, in name order.

Responses​

StatusCodeWhen
200—The tag is not on the task — including when it was not there to begin with, in which case nothing is written.
400VALIDATION_ERRORA key is not a GUID, or name is missing, blank or longer than 100 characters (name).
404CHECKLIST_NOT_FOUND / TASK_NOT_FOUNDNo such checklist, or no such task on it.

Notes​

  • Tags are created by being used and removed when they stop being used. Removing a tag from the last thing carrying it removes it from the workspace, and tagDeleted says so.

Get Task Activity​

Returns what has happened to one task, most recent first: the checklist's activity feed narrowed to this task, in the same shape.

GET /v3/checklists/{checklistKey}/tasks/{taskKey}/activity

Parameters​

NameInTypeRequiredDescription
checklistKeypathstring (GUID)YesThe checklist key.
taskKeypathstring (GUID)YesThe task key.
sortquerystringNooccurredAt, occurredAt:asc or occurredAt:desc. Default occurredAt:desc, most recent first.
pageSizequeryintegerNoEntries per page, 1–100. Default 50. A value outside the range, or one that is not a number, is replaced by 50 rather than refused. You can change it between pages without losing your place.
afterquerystringNoThe nextCursor from the previous page. Send the same sort it was issued under. A cursor from a different order, or from the checklist's own feed, is refused.

Example​

GET https://api.checkflow.io/v3/checklists/9d4e2b71-3c8a-4f15-b6d2-0e7a1c5f8b93/tasks/b81c55e0-2f4a-4d6b-a1e9-7c3d0f2e8a46/activity?pageSize=1
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"items": [
{
"occurredAt": "2026-09-28T15:41:09Z",
"actor": { "name": "James Okafor", "email": "james.okafor@acme.example" },
"description": "Completed task 'Check supplier details'",
"taskKey": "b81c55e0-2f4a-4d6b-a1e9-7c3d0f2e8a46",
"taskName": "Check supplier details"
}
],
"nextCursor": "eyJ2IjoxLCJzIjoib2NjdXJyZWRBdDpkZXNjIn0",
"hasMore": true,
"total": 7
}

The response is paged; total counts the task's whole feed, not the page.

FieldTypeDescription
occurredAtstring (date-time)When it happened.
actoruserWho did it. API Service and Scheduler Service are not team members and carry no email. A member who has since left reads as Unknown User.
descriptionstringWhat happened, as a sentence with the task and field names filled in. Dates in it are written in the time zone described in Time Zones.
taskKeystring (GUID)The task the entry is about.
taskNamestringThe task's current name. Absent when the task has been deleted.
fieldKeystring (GUID)The field the entry is about. Absent when it is not about a field.
fieldNamestringThe field's current label. Absent when the field has been deleted.
dateTimeValuestring (date-time)The value a Date & Time field was set to, for entries that record one.

Responses​

StatusCodeWhen
200—A page of the task's activity.
400VALIDATION_ERRORA key is not a GUID; sort is not one of the three values (sort); or after is unreadable, was issued under a different sort or for a different feed (after).
403FORBIDDENThe member the key acts as may not see this checklist. See Who Can Change a Task.
404CHECKLIST_NOT_FOUND / TASK_NOT_FOUNDNo such checklist, or no such task on it.

Notes​

  • Activity is written a second or two after the event, so this is not the way to confirm a write you have just made — the response to the write is.
  • There is no event type. Names are resolved when the feed is read, so a renamed task reads under its current name throughout its history, and an entry about a deleted field says (deleted).
  • Task Fields — read and answer a task's fields, and manage its files and table rows.
  • Checklists — the checklist itself, its tags, its activity feed and its attached tasks.
  • Standalone Tasks — tasks that are not part of a checklist's template, including those attached to a checklist.
  • My Work — the Tasks grid across every checklist, saved views and bulk snooze.
  • Task Tools — the MCP tools for the same operations.