Tasks
Tasks and corrective actions: create, assign, comment, attach files, move through statuses. Visibility follows the web app: the token sees tasks of its locations (tasks.view_all), its teams, its projects and the tasks it is involved in.
GETList tasks
Tasks visible to the token, newest first. Closed tasks are included; filter with status. Deleted tasks are never returned.
| Token scope | read |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_list · read-only |
Query parameters
page
integer
1. Minimum 1.
per_page
integer
25. Value 1–100.
status
array<string>
priority
array<string>
location_ids
array<integer>
assignee_id
integer
author_id
integer
team_id
integer
project_id
integer
source
string
manualautohaccprequesthrprocessroutinedue_from
date
due_to
date
overdue
boolean
updated_since
date-time
search
string
sort
string
created_desc. created_desccreated_ascupdated_descdue_ascResponses
| Status | Description |
|---|---|
| 200 | OK — a page of results with meta |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Plan without API access
|
| 422 | validation_failed — Invalid parameters — see error.fields
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl 'https://app.jecheck.io/api/ext/v1/tasks?assignee_id=42' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks?assignee_id=42', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
},
});
const { data, meta } = await res.json();import os, requests
res = requests.get(
"https://app.jecheck.io/api/ext/v1/tasks",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
params={"assignee_id":42},
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('GET', 'tasks', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'query' => [
'assignee_id' => 42,
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_list",
"arguments": {
"assignee_id": 42
}
}
}{
"data": [
{
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"key": "OPS-42",
"title": "Replace the broken fridge seal",
"status": "in_progress",
"priority": "high",
"assignees": [
{
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"name": "Aigerim Sadykova"
}
],
"watchers": [],
"author": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"location": {
"id": 12,
"name": "Abay Ave"
},
"team_id": null,
"project_id": null,
"due_date": "2026-11-10",
"tags": [
"Equipment"
],
"source": "auto",
"needs_photo": true,
"needs_review": true,
"comments_count": 2,
"files_count": 1,
"subtasks": {
"done": 1,
"total": 3
},
"audit_id": 99812,
"created_at": "2026-11-03T10:24:00+05:00",
"updated_at": "2026-11-03T12:01:00+05:00",
"completed_at": null,
"url": "https://app.jecheck.io/ui/tasks?task=3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
}
],
"meta": {
"page": 1,
"per_page": 25,
"total": 1,
"has_more": false
}
}GETRetrieve a task
Full task card: description, subtasks, files (signed links valid for 1 hour), comments and the statuses the token may set now.
| Token scope | read |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_get · read-only |
Path parameters
uuid
uuid
Required Responses
| Status | Description |
|---|---|
| 200 | OK |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Plan without API access
|
| 404 | not_found — The record does not exist or is not visible to the token
|
| 422 | validation_failed — Invalid parameters — see error.fields
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl 'https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
},
});
const { data } = await res.json();import os, requests
res = requests.get(
"https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('GET', 'tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_get",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
}
}
}{
"data": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"key": "OPS-42",
"title": "Replace the broken fridge seal",
"status": "in_progress",
"priority": "high",
"assignees": [
{
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"name": "Aigerim Sadykova"
}
],
"watchers": [],
"author": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"location": {
"id": 12,
"name": "Abay Ave"
},
"team_id": null,
"project_id": null,
"due_date": "2026-11-10",
"tags": [
"Equipment"
],
"source": "auto",
"needs_photo": true,
"needs_review": true,
"comments_count": 2,
"files_count": 1,
"subtasks": {
"done": 1,
"total": 3
},
"audit_id": 99812,
"created_at": "2026-11-03T10:24:00+05:00",
"updated_at": "2026-11-03T12:01:00+05:00",
"completed_at": null,
"url": "https://app.jecheck.io/ui/tasks?task=3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
"start_date": null,
"estimate_minutes": null,
"allowed_statuses": [
"in_progress",
"review"
],
"can_delete": false,
"audit": {
"id": 99812,
"checklist": "Kitchen daily check",
"score": 82,
"date": "2026-11-03T09:40:00+05:00"
},
"subtask_items": [
{
"id": 501,
"title": "Order the seal",
"done": true
}
],
"files": [
{
"id": 77,
"name": "fridge.jpg",
"size": 184220,
"is_image": true,
"url": "https://app.jecheck.io/ui/tasks/files/77?signature=…",
"created_at": "2026-11-03T10:30:00+05:00"
}
],
"comments": [
{
"id": 9001,
"author": {
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"name": "Aigerim Sadykova"
},
"text": "Seal ordered, arrives tomorrow.",
"file": null,
"created_at": "2026-11-03T11:00:00+05:00"
}
]
}
}POSTCreate a task
Creates a task with the same rules as the web app: notifications go to assignees, a task with a team and no assignee lands in the team queue (auto-assignment if enabled).
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_create |
| Content type | multipart/form-data application/json |
Request body
title
string
Required description
string | null
priority
string
medium.
urgenthighmediumlowassignee_ids
array<integer>
watcher_ids
array<integer>
location_id
integer | null
team_id
integer | null
due_date
date | null
tags
array<string>
project_id
integer | null
start_date
date | null
estimate_minutes
integer | null
status
string
new.
newin_progressreviewdonerejectedsubtasks
array<string>
files
array<file>
files[]; in MCP — objects with name and content_base64).
Maximum items 10. Responses
| Status | Description |
|---|---|
| 201 | Created |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Read-only token
|
| 422 | validation_failed — Invalid parameters — see error.fields
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl -X POST 'https://app.jecheck.io/api/ext/v1/tasks' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"title": "Replace the broken fridge seal",
"description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
"priority": "urgent",
"assignee_ids": [
12,
14
]
}'const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"title": "Replace the broken fridge seal",
"description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
"priority": "urgent",
"assignee_ids": [
12,
14
]
}),
});
const { data } = await res.json();import os, requests
res = requests.post(
"https://app.jecheck.io/api/ext/v1/tasks",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"title":"Replace the broken fridge seal","description":"Seal on fridge #2 is torn, temperature rises to +9 °C.","priority":"urgent","assignee_ids":[12,14]},
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('POST', 'tasks', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'title' => 'Replace the broken fridge seal',
'description' => 'Seal on fridge #2 is torn, temperature rises to +9 °C.',
'priority' => 'urgent',
'assignee_ids' => [
12,
14,
],
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_create",
"arguments": {
"title": "Replace the broken fridge seal",
"description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
"priority": "urgent",
"assignee_ids": [
12,
14
]
}
}
}{
"data": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"key": "OPS-42",
"title": "Replace the broken fridge seal",
"status": "in_progress",
"priority": "high",
"assignees": [
{
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"name": "Aigerim Sadykova"
}
],
"watchers": [],
"author": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"location": {
"id": 12,
"name": "Abay Ave"
},
"team_id": null,
"project_id": null,
"due_date": "2026-11-10",
"tags": [
"Equipment"
],
"source": "auto",
"needs_photo": true,
"needs_review": true,
"comments_count": 2,
"files_count": 1,
"subtasks": {
"done": 1,
"total": 3
},
"audit_id": 99812,
"created_at": "2026-11-03T10:24:00+05:00",
"updated_at": "2026-11-03T12:01:00+05:00",
"completed_at": null,
"url": "https://app.jecheck.io/ui/tasks?task=3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
"start_date": null,
"estimate_minutes": null,
"allowed_statuses": [
"in_progress",
"review"
],
"can_delete": false,
"audit": {
"id": 99812,
"checklist": "Kitchen daily check",
"score": 82,
"date": "2026-11-03T09:40:00+05:00"
},
"subtask_items": [
{
"id": 501,
"title": "Order the seal",
"done": true
}
],
"files": [
{
"id": 77,
"name": "fridge.jpg",
"size": 184220,
"is_image": true,
"url": "https://app.jecheck.io/ui/tasks/files/77?signature=…",
"created_at": "2026-11-03T10:30:00+05:00"
}
],
"comments": [
{
"id": 9001,
"author": {
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"name": "Aigerim Sadykova"
},
"text": "Seal ordered, arrives tomorrow.",
"file": null,
"created_at": "2026-11-03T11:00:00+05:00"
}
]
}
}PATCHUpdate a task
Partial update: send only the fields to change. Arrays (assignee_ids, watcher_ids, tags) replace the current values.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_update |
Path parameters
uuid
uuid
Required Request body
title
string
description
string | null
priority
string
urgenthighmediumlowassignee_ids
array<integer>
watcher_ids
array<integer>
location_id
integer | null
team_id
integer | null
due_date
date | null
tags
array<string>
project_id
integer | null
start_date
date | null
estimate_minutes
integer | null
Responses
| Status | Description |
|---|---|
| 200 | OK |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Read-only token
|
| 404 | not_found — The record does not exist or is not visible to the token
|
| 422 | validation_failed — Invalid parameters — see error.fields
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl -X PATCH 'https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"title": "Replace the broken fridge seal",
"description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
"priority": "urgent",
"assignee_ids": [
12,
14
]
}'const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"title": "Replace the broken fridge seal",
"description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
"priority": "urgent",
"assignee_ids": [
12,
14
]
}),
});
const { data } = await res.json();import os, requests
res = requests.patch(
"https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"title":"Replace the broken fridge seal","description":"Seal on fridge #2 is torn, temperature rises to +9 °C.","priority":"urgent","assignee_ids":[12,14]},
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('PATCH', 'tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'title' => 'Replace the broken fridge seal',
'description' => 'Seal on fridge #2 is torn, temperature rises to +9 °C.',
'priority' => 'urgent',
'assignee_ids' => [
12,
14,
],
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_update",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"title": "Replace the broken fridge seal",
"description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
"priority": "urgent",
"assignee_ids": [
12,
14
]
}
}
}{
"data": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"key": "OPS-42",
"title": "Replace the broken fridge seal",
"status": "in_progress",
"priority": "high",
"assignees": [
{
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"name": "Aigerim Sadykova"
}
],
"watchers": [],
"author": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"location": {
"id": 12,
"name": "Abay Ave"
},
"team_id": null,
"project_id": null,
"due_date": "2026-11-10",
"tags": [
"Equipment"
],
"source": "auto",
"needs_photo": true,
"needs_review": true,
"comments_count": 2,
"files_count": 1,
"subtasks": {
"done": 1,
"total": 3
},
"audit_id": 99812,
"created_at": "2026-11-03T10:24:00+05:00",
"updated_at": "2026-11-03T12:01:00+05:00",
"completed_at": null,
"url": "https://app.jecheck.io/ui/tasks?task=3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
"start_date": null,
"estimate_minutes": null,
"allowed_statuses": [
"in_progress",
"review"
],
"can_delete": false,
"audit": {
"id": 99812,
"checklist": "Kitchen daily check",
"score": 82,
"date": "2026-11-03T09:40:00+05:00"
},
"subtask_items": [
{
"id": 501,
"title": "Order the seal",
"done": true
}
],
"files": [
{
"id": 77,
"name": "fridge.jpg",
"size": 184220,
"is_image": true,
"url": "https://app.jecheck.io/ui/tasks/files/77?signature=…",
"created_at": "2026-11-03T10:30:00+05:00"
}
],
"comments": [
{
"id": 9001,
"author": {
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"name": "Aigerim Sadykova"
},
"text": "Seal ordered, arrives tomorrow.",
"file": null,
"created_at": "2026-11-03T11:00:00+05:00"
}
]
}
}POSTChange task status
Moves the task to another status. Tasks of the corrective-action loop allow only allowed_statuses from the task card (e.g. a photo "after" is required before review). approval is set by process routes only.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_status |
Path parameters
uuid
uuid
Required Request body
status
string
Required newin_progressreviewdonerejectedResponses
| Status | Description |
|---|---|
| 200 | OK |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Read-only token
|
| 404 | not_found — The record does not exist or is not visible to the token
|
| 422 | validation_failed — The transition is not allowed for this task (see allowed_statuses)
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl -X POST 'https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/status' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"status": "new"
}'const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/status', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"status": "new"
}),
});
const { data } = await res.json();import os, requests
res = requests.post(
"https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/status",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"status":"new"},
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('POST', 'tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/status', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'status' => 'new',
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_status",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"status": "new"
}
}
}{
"data": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"key": "OPS-42",
"title": "Replace the broken fridge seal",
"status": "in_progress",
"priority": "high",
"assignees": [
{
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"name": "Aigerim Sadykova"
}
],
"watchers": [],
"author": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"location": {
"id": 12,
"name": "Abay Ave"
},
"team_id": null,
"project_id": null,
"due_date": "2026-11-10",
"tags": [
"Equipment"
],
"source": "auto",
"needs_photo": true,
"needs_review": true,
"comments_count": 2,
"files_count": 1,
"subtasks": {
"done": 1,
"total": 3
},
"audit_id": 99812,
"created_at": "2026-11-03T10:24:00+05:00",
"updated_at": "2026-11-03T12:01:00+05:00",
"completed_at": null,
"url": "https://app.jecheck.io/ui/tasks?task=3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
"start_date": null,
"estimate_minutes": null,
"allowed_statuses": [
"in_progress",
"review"
],
"can_delete": false,
"audit": {
"id": 99812,
"checklist": "Kitchen daily check",
"score": 82,
"date": "2026-11-03T09:40:00+05:00"
},
"subtask_items": [
{
"id": 501,
"title": "Order the seal",
"done": true
}
],
"files": [
{
"id": 77,
"name": "fridge.jpg",
"size": 184220,
"is_image": true,
"url": "https://app.jecheck.io/ui/tasks/files/77?signature=…",
"created_at": "2026-11-03T10:30:00+05:00"
}
],
"comments": [
{
"id": 9001,
"author": {
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"name": "Aigerim Sadykova"
},
"text": "Seal ordered, arrives tomorrow.",
"file": null,
"created_at": "2026-11-03T11:00:00+05:00"
}
]
}
}DELDelete a task
Soft-deletes the task. Allowed to the author or with the tasks.delete permission.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_delete · destructive |
Path parameters
uuid
uuid
Required Responses
| Status | Description |
|---|---|
| 200 | OK |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Read-only token
|
| 404 | not_found — The record does not exist or is not visible to the token
|
| 422 | validation_failed — Invalid parameters — see error.fields
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl -X DELETE 'https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
},
});
const { data } = await res.json();import os, requests
res = requests.delete(
"https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('DELETE', 'tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_delete",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
}
}
}{
"data": {
"deleted": true
}
}POSTDuplicate a task
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_duplicate |
Path parameters
uuid
uuid
Required Responses
| Status | Description |
|---|---|
| 201 | Created |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Read-only token
|
| 404 | not_found — The record does not exist or is not visible to the token
|
| 422 | validation_failed — Invalid parameters — see error.fields
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl -X POST 'https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/duplicate' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/duplicate', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
},
});
const { data } = await res.json();import os, requests
res = requests.post(
"https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/duplicate",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('POST', 'tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/duplicate', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_duplicate",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
}
}
}{
"data": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"key": "OPS-42",
"title": "Replace the broken fridge seal",
"status": "in_progress",
"priority": "high",
"assignees": [
{
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"name": "Aigerim Sadykova"
}
],
"watchers": [],
"author": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"location": {
"id": 12,
"name": "Abay Ave"
},
"team_id": null,
"project_id": null,
"due_date": "2026-11-10",
"tags": [
"Equipment"
],
"source": "auto",
"needs_photo": true,
"needs_review": true,
"comments_count": 2,
"files_count": 1,
"subtasks": {
"done": 1,
"total": 3
},
"audit_id": 99812,
"created_at": "2026-11-03T10:24:00+05:00",
"updated_at": "2026-11-03T12:01:00+05:00",
"completed_at": null,
"url": "https://app.jecheck.io/ui/tasks?task=3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
"start_date": null,
"estimate_minutes": null,
"allowed_statuses": [
"in_progress",
"review"
],
"can_delete": false,
"audit": {
"id": 99812,
"checklist": "Kitchen daily check",
"score": 82,
"date": "2026-11-03T09:40:00+05:00"
},
"subtask_items": [
{
"id": 501,
"title": "Order the seal",
"done": true
}
],
"files": [
{
"id": 77,
"name": "fridge.jpg",
"size": 184220,
"is_image": true,
"url": "https://app.jecheck.io/ui/tasks/files/77?signature=…",
"created_at": "2026-11-03T10:30:00+05:00"
}
],
"comments": [
{
"id": 9001,
"author": {
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"name": "Aigerim Sadykova"
},
"text": "Seal ordered, arrives tomorrow.",
"file": null,
"created_at": "2026-11-03T11:00:00+05:00"
}
]
}
}POSTTake a task from the team queue
Assigns a queued team task to the acting user (must be a member of the team).
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_take |
Path parameters
uuid
uuid
Required Responses
| Status | Description |
|---|---|
| 200 | OK |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Read-only token
|
| 404 | not_found — The record does not exist or is not visible to the token
|
| 422 | validation_failed — Invalid parameters — see error.fields
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl -X POST 'https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/take' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/take', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
},
});
const { data } = await res.json();import os, requests
res = requests.post(
"https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/take",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('POST', 'tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/take', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_take",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
}
}
}{
"data": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"key": "OPS-42",
"title": "Replace the broken fridge seal",
"status": "in_progress",
"priority": "high",
"assignees": [
{
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"name": "Aigerim Sadykova"
}
],
"watchers": [],
"author": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"location": {
"id": 12,
"name": "Abay Ave"
},
"team_id": null,
"project_id": null,
"due_date": "2026-11-10",
"tags": [
"Equipment"
],
"source": "auto",
"needs_photo": true,
"needs_review": true,
"comments_count": 2,
"files_count": 1,
"subtasks": {
"done": 1,
"total": 3
},
"audit_id": 99812,
"created_at": "2026-11-03T10:24:00+05:00",
"updated_at": "2026-11-03T12:01:00+05:00",
"completed_at": null,
"url": "https://app.jecheck.io/ui/tasks?task=3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
"start_date": null,
"estimate_minutes": null,
"allowed_statuses": [
"in_progress",
"review"
],
"can_delete": false,
"audit": {
"id": 99812,
"checklist": "Kitchen daily check",
"score": 82,
"date": "2026-11-03T09:40:00+05:00"
},
"subtask_items": [
{
"id": 501,
"title": "Order the seal",
"done": true
}
],
"files": [
{
"id": 77,
"name": "fridge.jpg",
"size": 184220,
"is_image": true,
"url": "https://app.jecheck.io/ui/tasks/files/77?signature=…",
"created_at": "2026-11-03T10:30:00+05:00"
}
],
"comments": [
{
"id": 9001,
"author": {
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"name": "Aigerim Sadykova"
},
"text": "Seal ordered, arrives tomorrow.",
"file": null,
"created_at": "2026-11-03T11:00:00+05:00"
}
]
}
}POSTBulk update tasks
Applies the same change to up to 200 tasks. Tasks that cannot be changed (rules of the loop, permissions) are skipped; the response says how many were updated.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_bulk · destructive |
Request body
uuids
array<string>
Required status
string
newin_progressreviewdonerejectedpriority
string
urgenthighmediumlowdue_date
date | null
assignee_ids
array<integer>
location_id
integer | null
team_id
integer | null
delete
boolean
Responses
| Status | Description |
|---|---|
| 200 | OK |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Read-only token
|
| 422 | validation_failed — Invalid parameters — see error.fields
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl -X POST 'https://app.jecheck.io/api/ext/v1/tasks/bulk' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"uuids": [
"example"
],
"status": "new",
"priority": "urgent",
"due_date": "2026-11-01"
}'const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks/bulk', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"uuids": [
"example"
],
"status": "new",
"priority": "urgent",
"due_date": "2026-11-01"
}),
});
const { data } = await res.json();import os, requests
res = requests.post(
"https://app.jecheck.io/api/ext/v1/tasks/bulk",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"uuids":["example"],"status":"new","priority":"urgent","due_date":"2026-11-01"},
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('POST', 'tasks/bulk', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'uuids' => [
'example',
],
'status' => 'new',
'priority' => 'urgent',
'due_date' => '2026-11-01',
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_bulk",
"arguments": {
"uuids": [
"example"
],
"status": "new",
"priority": "urgent",
"due_date": "2026-11-01"
}
}
}{
"data": {
"updated": 18,
"requested": 20
}
}GETGet task history
Audit trail of the task: creation, status changes, reassignment, due date changes, comments by automation.
| Token scope | read |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_history · read-only |
Path parameters
uuid
uuid
Required Responses
| Status | Description |
|---|---|
| 200 | OK |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Plan without API access
|
| 404 | not_found — The record does not exist or is not visible to the token
|
| 422 | validation_failed — Invalid parameters — see error.fields
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl 'https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/history' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/history', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
},
});
const { data } = await res.json();import os, requests
res = requests.get(
"https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/history",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('GET', 'tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/history', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_history",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
}
}
}{
"data": [
{
"type": "status",
"payload": {
"from": "new",
"to": "in_progress"
},
"actor": "user",
"user": "Aigerim Sadykova",
"created_at": "2026-11-03T11:00:00+05:00"
}
]
}GETList task comments
| Token scope | read |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_comments_list · read-only |
Path parameters
uuid
uuid
Required Responses
| Status | Description |
|---|---|
| 200 | OK |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Plan without API access
|
| 404 | not_found — The record does not exist or is not visible to the token
|
| 422 | validation_failed — Invalid parameters — see error.fields
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl 'https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/comments' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/comments', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
},
});
const { data } = await res.json();import os, requests
res = requests.get(
"https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/comments",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('GET', 'tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/comments', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_comments_list",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
}
}
}{
"data": [
{
"id": 9001,
"author": {
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"name": "Aigerim Sadykova"
},
"text": "Seal ordered, arrives tomorrow.",
"file": null,
"created_at": "2026-11-03T11:00:00+05:00"
}
]
}POSTAdd a comment
Adds a comment from the acting user. Participants are notified as in the web app.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_comments_create |
Path parameters
uuid
uuid
Required Request body
text
string
Required Responses
| Status | Description |
|---|---|
| 201 | Created |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Read-only token
|
| 404 | not_found — The record does not exist or is not visible to the token
|
| 422 | validation_failed — Invalid parameters — see error.fields
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl -X POST 'https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/comments' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"text": "Seal on fridge #2 is torn, temperature rises to +9 °C."
}'const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/comments', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"text": "Seal on fridge #2 is torn, temperature rises to +9 °C."
}),
});
const { data } = await res.json();import os, requests
res = requests.post(
"https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/comments",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"text":"Seal on fridge #2 is torn, temperature rises to +9 °C."},
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('POST', 'tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/comments', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'text' => 'Seal on fridge #2 is torn, temperature rises to +9 °C.',
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_comments_create",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"text": "Seal on fridge #2 is torn, temperature rises to +9 °C."
}
}
}{
"data": {
"id": 9001,
"author": {
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"name": "Aigerim Sadykova"
},
"text": "Seal ordered, arrives tomorrow.",
"file": null,
"created_at": "2026-11-03T11:00:00+05:00"
}
}PATCHEdit a comment
Only the author of the comment can edit it.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_comments_update |
Path parameters
id
integer
Required Request body
text
string
Required Responses
| Status | Description |
|---|---|
| 200 | OK |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Read-only token
|
| 404 | not_found — The record does not exist or is not visible to the token
|
| 422 | validation_failed — Invalid parameters — see error.fields
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl -X PATCH 'https://app.jecheck.io/api/ext/v1/tasks/comments/42' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"text": "Seal on fridge #2 is torn, temperature rises to +9 °C."
}'const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks/comments/42', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"text": "Seal on fridge #2 is torn, temperature rises to +9 °C."
}),
});
const { data } = await res.json();import os, requests
res = requests.patch(
"https://app.jecheck.io/api/ext/v1/tasks/comments/42",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"text":"Seal on fridge #2 is torn, temperature rises to +9 °C."},
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('PATCH', 'tasks/comments/42', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'text' => 'Seal on fridge #2 is torn, temperature rises to +9 °C.',
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_comments_update",
"arguments": {
"id": 42,
"text": "Seal on fridge #2 is torn, temperature rises to +9 °C."
}
}
}{
"data": {
"id": 9001,
"author": {
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"name": "Aigerim Sadykova"
},
"text": "Seal ordered, arrives tomorrow.",
"file": null,
"created_at": "2026-11-03T11:00:00+05:00"
}
}DELDelete a comment
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_comments_delete · destructive |
Path parameters
id
integer
Required Responses
| Status | Description |
|---|---|
| 200 | OK |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Read-only token
|
| 404 | not_found — The record does not exist or is not visible to the token
|
| 422 | validation_failed — Invalid parameters — see error.fields
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl -X DELETE 'https://app.jecheck.io/api/ext/v1/tasks/comments/42' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks/comments/42', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
},
});
const { data } = await res.json();import os, requests
res = requests.delete(
"https://app.jecheck.io/api/ext/v1/tasks/comments/42",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('DELETE', 'tasks/comments/42', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_comments_delete",
"arguments": {
"id": 42
}
}
}{
"data": {
"deleted": true
}
}POSTAdd a subtask
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_subtasks_create |
Path parameters
uuid
uuid
Required Request body
title
string
Required Responses
| Status | Description |
|---|---|
| 201 | Created |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Read-only token
|
| 404 | not_found — The record does not exist or is not visible to the token
|
| 422 | validation_failed — Invalid parameters — see error.fields
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl -X POST 'https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/subtasks' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"title": "Replace the broken fridge seal"
}'const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/subtasks', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"title": "Replace the broken fridge seal"
}),
});
const { data } = await res.json();import os, requests
res = requests.post(
"https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/subtasks",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"title":"Replace the broken fridge seal"},
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('POST', 'tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/subtasks', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'title' => 'Replace the broken fridge seal',
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_subtasks_create",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"title": "Replace the broken fridge seal"
}
}
}{
"data": {
"id": 502,
"title": "Install the seal",
"done": false
}
}PATCHUpdate a subtask
Rename a subtask or mark it done / not done.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_subtasks_update |
Path parameters
id
integer
Required Request body
title
string
done
boolean
Responses
| Status | Description |
|---|---|
| 200 | OK |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Read-only token
|
| 404 | not_found — The record does not exist or is not visible to the token
|
| 422 | validation_failed — Invalid parameters — see error.fields
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl -X PATCH 'https://app.jecheck.io/api/ext/v1/tasks/subtasks/42' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"title": "Replace the broken fridge seal",
"done": true
}'const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks/subtasks/42', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"title": "Replace the broken fridge seal",
"done": true
}),
});
const { data } = await res.json();import os, requests
res = requests.patch(
"https://app.jecheck.io/api/ext/v1/tasks/subtasks/42",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"title":"Replace the broken fridge seal","done":True},
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('PATCH', 'tasks/subtasks/42', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'title' => 'Replace the broken fridge seal',
'done' => true,
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_subtasks_update",
"arguments": {
"id": 42,
"title": "Replace the broken fridge seal",
"done": true
}
}
}{
"data": {
"id": 502,
"title": "Install the seal",
"done": true
}
}DELDelete a subtask
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_subtasks_delete · destructive |
Path parameters
id
integer
Required Responses
| Status | Description |
|---|---|
| 200 | OK |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Read-only token
|
| 404 | not_found — The record does not exist or is not visible to the token
|
| 422 | validation_failed — Invalid parameters — see error.fields
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl -X DELETE 'https://app.jecheck.io/api/ext/v1/tasks/subtasks/42' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks/subtasks/42', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
},
});
const { data } = await res.json();import os, requests
res = requests.delete(
"https://app.jecheck.io/api/ext/v1/tasks/subtasks/42",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('DELETE', 'tasks/subtasks/42', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_subtasks_delete",
"arguments": {
"id": 42
}
}
}{
"data": {
"deleted": true
}
}GETList task files
Attachments with signed download links (valid for 1 hour, no token needed).
| Token scope | read |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_files_list · read-only |
Path parameters
uuid
uuid
Required Responses
| Status | Description |
|---|---|
| 200 | OK |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Plan without API access
|
| 404 | not_found — The record does not exist or is not visible to the token
|
| 422 | validation_failed — Invalid parameters — see error.fields
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl 'https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/files' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/files', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
},
});
const { data } = await res.json();import os, requests
res = requests.get(
"https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/files",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('GET', 'tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/files', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_files_list",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
}
}
}{
"data": [
{
"id": 77,
"name": "fridge.jpg",
"size": 184220,
"is_image": true,
"url": "https://app.jecheck.io/ui/tasks/files/77?signature=…",
"created_at": "2026-11-03T10:30:00+05:00"
}
]
}POSTUpload files to a task
Multipart upload, field files[], up to 10 files. In MCP pass files as objects with name and content_base64.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_files_upload |
| Content type | multipart/form-data application/json |
Path parameters
uuid
uuid
Required Request body
files
array<file>
Required Responses
| Status | Description |
|---|---|
| 201 | Created |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Read-only token
|
| 404 | not_found — The record does not exist or is not visible to the token
|
| 422 | validation_failed — Invalid parameters — see error.fields
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl -X POST 'https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/files' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-F 'files[][email protected]'const form = new FormData();
form.append('files[]', fileInput.files[0]);
const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/files', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.JECHECK_TOKEN}` },
body: form,
});
const { data } = await res.json();import os, requests
res = requests.post(
"https://app.jecheck.io/api/ext/v1/tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/files",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
data=[],
files=[("files[]", open("photo.jpg", "rb"))],
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('POST', 'tasks/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/files', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'multipart' => [
['name' => 'files[]', 'contents' => fopen('photo.jpg', 'r')],
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_files_upload",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
}
}
}{
"data": [
{
"id": 77,
"name": "fridge.jpg",
"size": 184220,
"is_image": true,
"url": "https://app.jecheck.io/ui/tasks/files/77?signature=…",
"created_at": "2026-11-03T10:30:00+05:00"
}
]
}DELDelete a task file
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_files_delete · destructive |
Path parameters
id
integer
Required Responses
| Status | Description |
|---|---|
| 200 | OK |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Read-only token
|
| 404 | not_found — The record does not exist or is not visible to the token
|
| 422 | validation_failed — Invalid parameters — see error.fields
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl -X DELETE 'https://app.jecheck.io/api/ext/v1/tasks/files/42' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks/files/42', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
},
});
const { data } = await res.json();import os, requests
res = requests.delete(
"https://app.jecheck.io/api/ext/v1/tasks/files/42",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('DELETE', 'tasks/files/42', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_files_delete",
"arguments": {
"id": 42
}
}
}{
"data": {
"deleted": true
}
}GETList task tags
Tag suggestions and tags already used in the company.
| Token scope | read |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | tasks_tags · read-only |
Responses
| Status | Description |
|---|---|
| 200 | OK |
| 401 | unauthorized — Missing, invalid, revoked or expired token
|
| 403 | forbidden · insufficient_scope · plan_required — Plan without API access
|
| 429 | rate_limited — Too many requests — retry after Retry-After seconds
|
curl 'https://app.jecheck.io/api/ext/v1/tasks/tags' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/tasks/tags', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
},
});
const { data } = await res.json();import os, requests
res = requests.get(
"https://app.jecheck.io/api/ext/v1/tasks/tags",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
)
res.raise_for_status()
data = res.json()["data"]$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('GET', 'tasks/tags', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tasks_tags",
"arguments": {}
}
}{
"data": [
"Equipment",
"Kitchen",
"Cleaning"
]
}