Instructions
Company knowledge base: folders, documents with published versions, read acknowledgements and editing. Visibility follows the document and folder permissions of the acting user ("who can view / who can edit"); content is returned as Markdown, HTML or plain text and accepted as Markdown or HTML.
GETList instructions
Instructions visible to the acting user, in library order. Readers get published documents; editors also get drafts and archived documents they can edit (filter with status). Read status (viewed, acknowledged, needs_ack) is for the acting user.
| Token scope | read |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_list · read-only |
Query parameters
page
integer
1. Minimum 1.
per_page
integer
25. Value 1–100.
folder_id
integer
root
boolean
search
string
status
array<string>
filter
string
needs_ack — waiting for the acting user's acknowledgement; unread — never opened by the acting user.
needs_ackunreadtags
array<string>
updated_since
date-time
Responses
| 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/instructions?folder_id=42' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions?folder_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/instructions",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
params={"folder_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', 'instructions', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'query' => [
'folder_id' => 42,
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_list",
"arguments": {
"folder_id": 42
}
}
}{
"data": [
{
"uuid": "5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a",
"title": "Opening the coffee shop",
"icon": "coffee",
"summary": "Morning checklist for baristas",
"folder_id": 14,
"status": "published",
"version": 3,
"published_at": "2026-10-28T09:12:00+05:00",
"updated_at": "2026-10-28T09:12:00+05:00",
"require_ack": true,
"tags": [
"Barista",
"Opening"
],
"words": 412,
"viewed": true,
"acknowledged": false,
"needs_ack": true,
"has_unpublished_changes": null,
"can_edit": false,
"url": "https://app.jecheck.io/ui/instructions/5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a"
}
],
"meta": {
"page": 1,
"per_page": 25,
"total": 1,
"has_more": false
}
}GETGet my reading counters
Counters for the acting user over the published instructions they can read: total, never opened, and waiting for acknowledgement.
| Token scope | read |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_badge · 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/instructions/badge' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/badge', {
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/instructions/badge",
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', 'instructions/badge', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_badge",
"arguments": {}
}
}{
"data": {
"total": 42,
"unread": 5,
"needs_ack": 2
}
}GETSearch instructions
Full-text search over the instructions visible to the acting user (readers — published text; editors — also working titles). Returns up to limit matches with a text snippet. Legacy AI-bot keys keep the previous behaviour of this endpoint (see the instructions external API guide).
| Token scope | read |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_search · read-only |
Query parameters
q
string
Required folder_id
integer
limit
integer
20. Value 1–50.
Responses
| Status | Description |
|---|---|
| 200 | OK |
| 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/instructions/search?q=fridge' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/search?q=fridge', {
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/instructions/search",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
params={"q":"fridge"},
)
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', 'instructions/search', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'query' => [
'q' => 'fridge',
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_search",
"arguments": {
"q": "fridge"
}
}
}{
"data": [
{
"uuid": "5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a",
"title": "Opening the coffee shop",
"icon": "coffee",
"status": "published",
"folder_id": 14,
"snippet": "…calibrate the grinder before the first espresso…",
"url": "https://app.jecheck.io/ui/instructions/5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a"
}
]
}GETGet the library tree
The whole library in one call: the folder tree (with document counts and edit rights) and the list of documents visible to the acting user (see instructions.list for the item shape).
| Token scope | read |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_tree · 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/instructions/tree' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/tree', {
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/instructions/tree",
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', 'instructions/tree', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_tree",
"arguments": {}
}
}{
"data": {
"folders": [
{
"id": 14,
"parent_id": 3,
"name": "Barista",
"icon": "coffee",
"color": null,
"count": 6,
"total": 6,
"can_edit": false,
"restricted": false,
"children": []
}
],
"documents": [
{
"uuid": "5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a",
"title": "Opening the coffee shop",
"icon": "coffee",
"summary": "Morning checklist for baristas",
"folder_id": 14,
"status": "published",
"version": 3,
"published_at": "2026-10-28T09:12:00+05:00",
"updated_at": "2026-10-28T09:12:00+05:00",
"require_ack": true,
"tags": [
"Barista",
"Opening"
],
"words": 412,
"viewed": true,
"acknowledged": false,
"needs_ack": true,
"has_unpublished_changes": null,
"can_edit": false,
"url": "https://app.jecheck.io/ui/instructions/5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a"
}
],
"can_create_in_root": false
}
}GETList instruction changes
Change feed for mirrors and caches, oldest first: every document of the company changed after updated_since, with state = active (published and readable by the acting user) or removed (deleted, archived, unpublished or no longer visible). Store the last updated_at and pass it as updated_since next time.
| Token scope | read |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_changes · read-only |
Query parameters
page
integer
1. Minimum 1.
per_page
integer
25. Value 1–100.
updated_since
date-time
Responses
| 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/instructions/changes?updated_since=2026-11-03T09:00:00+05:00' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/changes?updated_since=2026-11-03T09:00:00+05:00', {
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/instructions/changes",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
params={"updated_since":"2026-11-03T09:00:00+05:00"},
)
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', 'instructions/changes', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'query' => [
'updated_since' => '2026-11-03T09:00:00+05:00',
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_changes",
"arguments": {
"updated_since": "2026-11-03T09:00:00+05:00"
}
}
}{
"data": [
{
"uuid": "5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a",
"state": "active",
"version": 3,
"updated_at": "2026-10-28T09:12:00+05:00"
}
],
"meta": {
"page": 1,
"per_page": 25,
"total": 1,
"has_more": false
}
}GETFind an instruction by external reference
Resolves an external reference (for example confluence:12345 for pages imported from Confluence) to the instruction UUID — use it to redirect old links.
| Token scope | read |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_by_ref · read-only |
Path parameters
ref
string
Required confluence:12345.
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/instructions/by-ref/string' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/by-ref/string', {
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/instructions/by-ref/string",
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', 'instructions/by-ref/string', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_by_ref",
"arguments": {
"ref": "string"
}
}
}{
"data": {
"uuid": "5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a",
"title": "Opening the coffee shop",
"url": "https://app.jecheck.io/ui/instructions/5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a"
}
}GETRetrieve an instruction
The current published version of a document (or an older one with version) with its content in Markdown (default), HTML or plain text, the table of contents, attachments with download links and the acting user's acknowledgement status. Editors can request the unpublished draft with draft=true; a never-published document returns its draft. Pass track=true to count the call as a view by the acting user (as when the employee opens it in the app).
| Token scope | read |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_get · read-only |
Path parameters
uuid
uuid
Required Query parameters
format
string
content.
Default markdown. markdownhtmltextversion
integer
draft
boolean
track
boolean
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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b?format=markdown' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b?format=markdown', {
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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
params={"format":"markdown"},
)
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', 'instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'query' => [
'format' => 'markdown',
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_get",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"format": "markdown"
}
}
}{
"data": {
"uuid": "5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a",
"title": "Opening the coffee shop",
"icon": "coffee",
"summary": "Morning checklist for baristas",
"status": "published",
"folder": {
"id": 14,
"name": "Barista"
},
"folder_path": [
{
"id": 3,
"name": "Operations"
},
{
"id": 14,
"name": "Barista"
}
],
"tags": [
"Barista",
"Opening"
],
"version": 3,
"is_latest": true,
"is_draft": false,
"published_at": "2026-10-28T09:12:00+05:00",
"published_by": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"change_note": "New grinder settings",
"is_major": true,
"versions_count": 3,
"format": "markdown",
"content": "## Before opening\n\n1. Turn on the espresso machine\n2. Calibrate the grinder\n\n> **Important:** check fridge temperatures.",
"toc": [
{
"id": "before-opening",
"text": "Before opening",
"level": 2
}
],
"words": 412,
"read_minutes": 3,
"require_ack": true,
"acknowledged": false,
"needs_ack": true,
"attachments": [
{
"uuid": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
"kind": "file",
"name": "Cleaning schedule.pdf",
"mime": "application/pdf",
"size": 182044,
"width": null,
"height": null,
"url": "https://files.jecheck.io/instructions/761/2026/11/0c1d2e3f.pdf"
}
],
"can_edit": true,
"has_unpublished_changes": false,
"review_every_days": 180,
"review_due_at": "2027-04-26",
"owner": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"updated_at": "2026-10-28T09:12:00+05:00",
"url": "https://app.jecheck.io/ui/instructions/5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a"
}
}GETList versions of an instruction
Published versions, newest first. Read an older version with GET /instructions/{uuid}?version=N.
| Token scope | read |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_versions · 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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/versions' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/versions', {
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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/versions",
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', 'instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/versions', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_versions",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
}
}
}{
"data": [
{
"number": 3,
"title": "Opening the coffee shop",
"change_note": "New grinder settings",
"is_major": true,
"words": 412,
"published_by": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"published_at": "2026-10-28T09:12:00+05:00",
"is_latest": true
}
]
}GETCompare versions
Block-level comparison of two versions: from (0 — empty document) and to (default — current version; editors may pass draft). Each block is HTML with op = added, removed or same.
| Token scope | read |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| Plan feature | instructions_pro |
| MCP tool | instructions_diff · read-only |
Path parameters
uuid
uuid
Required Query parameters
from
integer
Required to
string
draft (editors only). Default — current version.
Maximum length 10. 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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/diff?from=42' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/diff?from=42', {
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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/diff",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
params={"from":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', 'instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/diff', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'query' => [
'from' => 42,
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_diff",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"from": 42
}
}
}{
"data": {
"from": 2,
"to": "3",
"blocks": [
{
"op": "removed",
"html": "<p>Grind size 12</p>"
},
{
"op": "added",
"html": "<p>Grind size 10</p>"
}
],
"added": 1,
"removed": 1
}
}GETList instruction files
Images and attachments used in the current published version (editors: in the draft with draft=true) with download links.
| Token scope | read |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_files_list · read-only |
Path parameters
uuid
uuid
Required Query parameters
draft
boolean
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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/files?draft=true' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/files?draft=true', {
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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/files",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
params={"draft":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('GET', 'instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/files', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'query' => [
'draft' => true,
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_files_list",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"draft": true
}
}
}{
"data": [
{
"uuid": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
"kind": "file",
"name": "Cleaning schedule.pdf",
"mime": "application/pdf",
"size": 182044,
"width": null,
"height": null,
"url": "https://files.jecheck.io/instructions/761/2026/11/0c1d2e3f.pdf"
}
]
}POSTAcknowledge an instruction
Records that the acting user has read the current version ("I have read it"). Required again after each major version when the document has require_ack.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_acknowledge |
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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/acknowledge' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/acknowledge', {
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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/acknowledge",
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', 'instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/acknowledge', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_acknowledge",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
}
}
}{
"data": {
"acknowledged": true,
"version": 3
}
}GETGet the acknowledgement report
Who in the audience of the document has opened and acknowledged the current major version. Editors of the document only.
| Token scope | read |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| Plan feature | instructions_pro |
| MCP tool | instructions_acknowledgements · 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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/acknowledgements' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/acknowledgements', {
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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/acknowledgements",
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', 'instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/acknowledgements', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_acknowledgements",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
}
}
}{
"data": {
"total": 18,
"viewed": 15,
"acknowledged": 12,
"ack_rate": 67,
"ack_since_version": 3,
"users": [
{
"user": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"position": "Barista",
"last_viewed_at": "2026-10-29T08:01:00+05:00",
"viewed_version": 3,
"acknowledged_at": "2026-10-29T08:03:00+05:00",
"source": "app"
}
]
}
}POSTRemind employees to read an instruction
Sends a push / in-app notification to everyone in the audience who has not acknowledged the current version yet.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| Plan feature | instructions_pro |
| MCP tool | instructions_remind |
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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/remind' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/remind', {
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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/remind",
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', 'instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/remind', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_remind",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
}
}
}{
"data": {
"reminded": 6
}
}POSTCreate an instruction
Creates a draft in a folder where the acting user can edit (the library root — knowledge-base managers only). Content is converted to the editor format; pass publish=true to publish the first version right away (employees are notified).
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_create |
Request body
title
string
Required content
string
content_format
string
content, default markdown. HTML is sanitised to text formatting, headings, lists, tables, quotes, code and links; add images and files with the upload operation.
markdownhtmltexttemplate
string
content is passed).
sopopeningsanitationequipmentfolder_id
integer | null
icon
string | null
summary
string | null
require_ack
boolean
review_every_days
integer | null
owner_id
integer | null
tags
array<string>
ai_visibility
string
inheritnonestaffclientai_note
string | null
ai_visibility).
Maximum length 2000. publish
boolean
change_note
string
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/instructions' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"title": "Replace the broken fridge seal",
"content": "string",
"content_format": "markdown",
"template": "sop"
}'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"title": "Replace the broken fridge seal",
"content": "string",
"content_format": "markdown",
"template": "sop"
}),
});
const { data } = await res.json();import os, requests
res = requests.post(
"https://app.jecheck.io/api/ext/v1/instructions",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"title":"Replace the broken fridge seal","content":"string","content_format":"markdown","template":"sop"},
)
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', 'instructions', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'title' => 'Replace the broken fridge seal',
'content' => 'string',
'content_format' => 'markdown',
'template' => 'sop',
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_create",
"arguments": {
"title": "Replace the broken fridge seal",
"content": "string",
"content_format": "markdown",
"template": "sop"
}
}
}{
"data": {
"uuid": "5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a",
"title": "Opening the coffee shop",
"icon": "coffee",
"summary": "Morning checklist for baristas",
"status": "published",
"folder": {
"id": 14,
"name": "Barista"
},
"folder_path": [
{
"id": 3,
"name": "Operations"
},
{
"id": 14,
"name": "Barista"
}
],
"tags": [
"Barista",
"Opening"
],
"version": 3,
"is_latest": true,
"is_draft": false,
"published_at": "2026-10-28T09:12:00+05:00",
"published_by": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"change_note": "New grinder settings",
"is_major": true,
"versions_count": 3,
"format": "markdown",
"content": "## Before opening\n\n1. Turn on the espresso machine\n2. Calibrate the grinder\n\n> **Important:** check fridge temperatures.",
"toc": [
{
"id": "before-opening",
"text": "Before opening",
"level": 2
}
],
"words": 412,
"read_minutes": 3,
"require_ack": true,
"acknowledged": false,
"needs_ack": true,
"attachments": [
{
"uuid": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
"kind": "file",
"name": "Cleaning schedule.pdf",
"mime": "application/pdf",
"size": 182044,
"width": null,
"height": null,
"url": "https://files.jecheck.io/instructions/761/2026/11/0c1d2e3f.pdf"
}
],
"can_edit": true,
"has_unpublished_changes": false,
"review_every_days": 180,
"review_due_at": "2027-04-26",
"owner": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"updated_at": "2026-10-28T09:12:00+05:00",
"url": "https://app.jecheck.io/ui/instructions/5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a"
}
}PATCHUpdate an instruction
Edits the working draft (title, content) and document settings. Changes to title or content are saved to the draft and become visible to readers only after publish; settings (folder, tags, review period, acknowledgement) apply immediately. Moving to another folder requires edit rights on it.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_update |
Path parameters
uuid
uuid
Required Request body
title
string
content
string
content_format
string
content, default markdown. HTML is sanitised to text formatting, headings, lists, tables, quotes, code and links; add images and files with the upload operation.
markdownhtmltextfolder_id
integer | null
icon
string | null
summary
string | null
require_ack
boolean
review_every_days
integer | null
owner_id
integer | null
tags
array<string>
ai_visibility
string
inheritnonestaffclientai_note
string | null
ai_visibility).
Maximum length 2000. 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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"title": "Replace the broken fridge seal",
"content": "string",
"content_format": "markdown",
"folder_id": 42
}'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/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",
"content": "string",
"content_format": "markdown",
"folder_id": 42
}),
});
const { data } = await res.json();import os, requests
res = requests.patch(
"https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"title":"Replace the broken fridge seal","content":"string","content_format":"markdown","folder_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('PATCH', 'instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'title' => 'Replace the broken fridge seal',
'content' => 'string',
'content_format' => 'markdown',
'folder_id' => 42,
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_update",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"title": "Replace the broken fridge seal",
"content": "string",
"content_format": "markdown",
"folder_id": 42
}
}
}{
"data": {
"uuid": "5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a",
"title": "Opening the coffee shop",
"icon": "coffee",
"summary": "Morning checklist for baristas",
"status": "published",
"folder": {
"id": 14,
"name": "Barista"
},
"folder_path": [
{
"id": 3,
"name": "Operations"
},
{
"id": 14,
"name": "Barista"
}
],
"tags": [
"Barista",
"Opening"
],
"version": 3,
"is_latest": true,
"is_draft": false,
"published_at": "2026-10-28T09:12:00+05:00",
"published_by": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"change_note": "New grinder settings",
"is_major": true,
"versions_count": 3,
"format": "markdown",
"content": "## Before opening\n\n1. Turn on the espresso machine\n2. Calibrate the grinder\n\n> **Important:** check fridge temperatures.",
"toc": [
{
"id": "before-opening",
"text": "Before opening",
"level": 2
}
],
"words": 412,
"read_minutes": 3,
"require_ack": true,
"acknowledged": false,
"needs_ack": true,
"attachments": [
{
"uuid": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
"kind": "file",
"name": "Cleaning schedule.pdf",
"mime": "application/pdf",
"size": 182044,
"width": null,
"height": null,
"url": "https://files.jecheck.io/instructions/761/2026/11/0c1d2e3f.pdf"
}
],
"can_edit": true,
"has_unpublished_changes": false,
"review_every_days": 180,
"review_due_at": "2027-04-26",
"owner": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"updated_at": "2026-10-28T09:12:00+05:00",
"url": "https://app.jecheck.io/ui/instructions/5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a"
}
}POSTPublish an instruction
Publishes the draft as a new version. A major version (default) requires a new acknowledgement and notifies employees; a minor one notifies only when notify=true.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_publish |
Path parameters
uuid
uuid
Required Request body
change_note
string
is_major
boolean
notify
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 POST 'https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/publish' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"change_note": "string",
"is_major": true,
"notify": true
}'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/publish', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"change_note": "string",
"is_major": true,
"notify": true
}),
});
const { data } = await res.json();import os, requests
res = requests.post(
"https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/publish",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"change_note":"string","is_major":True,"notify":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('POST', 'instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/publish', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'change_note' => 'string',
'is_major' => true,
'notify' => true,
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_publish",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"change_note": "string",
"is_major": true,
"notify": true
}
}
}{
"data": {
"uuid": "5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a",
"title": "Opening the coffee shop",
"icon": "coffee",
"summary": "Morning checklist for baristas",
"status": "published",
"folder": {
"id": 14,
"name": "Barista"
},
"folder_path": [
{
"id": 3,
"name": "Operations"
},
{
"id": 14,
"name": "Barista"
}
],
"tags": [
"Barista",
"Opening"
],
"version": 3,
"is_latest": true,
"is_draft": false,
"published_at": "2026-10-28T09:12:00+05:00",
"published_by": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"change_note": "New grinder settings",
"is_major": true,
"versions_count": 3,
"format": "markdown",
"content": "## Before opening\n\n1. Turn on the espresso machine\n2. Calibrate the grinder\n\n> **Important:** check fridge temperatures.",
"toc": [
{
"id": "before-opening",
"text": "Before opening",
"level": 2
}
],
"words": 412,
"read_minutes": 3,
"require_ack": true,
"acknowledged": false,
"needs_ack": true,
"attachments": [
{
"uuid": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
"kind": "file",
"name": "Cleaning schedule.pdf",
"mime": "application/pdf",
"size": 182044,
"width": null,
"height": null,
"url": "https://files.jecheck.io/instructions/761/2026/11/0c1d2e3f.pdf"
}
],
"can_edit": true,
"has_unpublished_changes": false,
"review_every_days": 180,
"review_due_at": "2027-04-26",
"owner": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"updated_at": "2026-10-28T09:12:00+05:00",
"url": "https://app.jecheck.io/ui/instructions/5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a"
}
}POSTDiscard draft changes
Resets the draft to the current published version.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_discard |
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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/discard' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/discard', {
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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/discard",
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', 'instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/discard', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_discard",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
}
}
}{
"data": {
"uuid": "5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a",
"title": "Opening the coffee shop",
"icon": "coffee",
"summary": "Morning checklist for baristas",
"status": "published",
"folder": {
"id": 14,
"name": "Barista"
},
"folder_path": [
{
"id": 3,
"name": "Operations"
},
{
"id": 14,
"name": "Barista"
}
],
"tags": [
"Barista",
"Opening"
],
"version": 3,
"is_latest": true,
"is_draft": false,
"published_at": "2026-10-28T09:12:00+05:00",
"published_by": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"change_note": "New grinder settings",
"is_major": true,
"versions_count": 3,
"format": "markdown",
"content": "## Before opening\n\n1. Turn on the espresso machine\n2. Calibrate the grinder\n\n> **Important:** check fridge temperatures.",
"toc": [
{
"id": "before-opening",
"text": "Before opening",
"level": 2
}
],
"words": 412,
"read_minutes": 3,
"require_ack": true,
"acknowledged": false,
"needs_ack": true,
"attachments": [
{
"uuid": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
"kind": "file",
"name": "Cleaning schedule.pdf",
"mime": "application/pdf",
"size": 182044,
"width": null,
"height": null,
"url": "https://files.jecheck.io/instructions/761/2026/11/0c1d2e3f.pdf"
}
],
"can_edit": true,
"has_unpublished_changes": false,
"review_every_days": 180,
"review_due_at": "2027-04-26",
"owner": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"updated_at": "2026-10-28T09:12:00+05:00",
"url": "https://app.jecheck.io/ui/instructions/5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a"
}
}POSTRestore an old version to the draft
Copies an older version into the draft; publish it to make it current again.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| Plan feature | instructions_pro |
| MCP tool | instructions_restore |
Path parameters
uuid
uuid
Required Request body
version
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 POST 'https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/restore' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"version": 42
}'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/restore', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"version": 42
}),
});
const { data } = await res.json();import os, requests
res = requests.post(
"https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/restore",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"version":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('POST', 'instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/restore', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'version' => 42,
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_restore",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"version": 42
}
}
}{
"data": {
"uuid": "5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a",
"title": "Opening the coffee shop",
"icon": "coffee",
"summary": "Morning checklist for baristas",
"status": "published",
"folder": {
"id": 14,
"name": "Barista"
},
"folder_path": [
{
"id": 3,
"name": "Operations"
},
{
"id": 14,
"name": "Barista"
}
],
"tags": [
"Barista",
"Opening"
],
"version": 3,
"is_latest": true,
"is_draft": false,
"published_at": "2026-10-28T09:12:00+05:00",
"published_by": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"change_note": "New grinder settings",
"is_major": true,
"versions_count": 3,
"format": "markdown",
"content": "## Before opening\n\n1. Turn on the espresso machine\n2. Calibrate the grinder\n\n> **Important:** check fridge temperatures.",
"toc": [
{
"id": "before-opening",
"text": "Before opening",
"level": 2
}
],
"words": 412,
"read_minutes": 3,
"require_ack": true,
"acknowledged": false,
"needs_ack": true,
"attachments": [
{
"uuid": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
"kind": "file",
"name": "Cleaning schedule.pdf",
"mime": "application/pdf",
"size": 182044,
"width": null,
"height": null,
"url": "https://files.jecheck.io/instructions/761/2026/11/0c1d2e3f.pdf"
}
],
"can_edit": true,
"has_unpublished_changes": false,
"review_every_days": 180,
"review_due_at": "2027-04-26",
"owner": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"updated_at": "2026-10-28T09:12:00+05:00",
"url": "https://app.jecheck.io/ui/instructions/5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a"
}
}POSTArchive or unarchive an instruction
Archived documents are hidden from readers. Pass archived=false to return a document from the archive.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_archive |
Path parameters
uuid
uuid
Required Request body
archived
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 POST 'https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/archive' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"archived": true
}'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/archive', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"archived": true
}),
});
const { data } = await res.json();import os, requests
res = requests.post(
"https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/archive",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"archived":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('POST', 'instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/archive', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'archived' => true,
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_archive",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"archived": true
}
}
}{
"data": {
"uuid": "5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a",
"title": "Opening the coffee shop",
"icon": "coffee",
"summary": "Morning checklist for baristas",
"status": "published",
"folder": {
"id": 14,
"name": "Barista"
},
"folder_path": [
{
"id": 3,
"name": "Operations"
},
{
"id": 14,
"name": "Barista"
}
],
"tags": [
"Barista",
"Opening"
],
"version": 3,
"is_latest": true,
"is_draft": false,
"published_at": "2026-10-28T09:12:00+05:00",
"published_by": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"change_note": "New grinder settings",
"is_major": true,
"versions_count": 3,
"format": "markdown",
"content": "## Before opening\n\n1. Turn on the espresso machine\n2. Calibrate the grinder\n\n> **Important:** check fridge temperatures.",
"toc": [
{
"id": "before-opening",
"text": "Before opening",
"level": 2
}
],
"words": 412,
"read_minutes": 3,
"require_ack": true,
"acknowledged": false,
"needs_ack": true,
"attachments": [
{
"uuid": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
"kind": "file",
"name": "Cleaning schedule.pdf",
"mime": "application/pdf",
"size": 182044,
"width": null,
"height": null,
"url": "https://files.jecheck.io/instructions/761/2026/11/0c1d2e3f.pdf"
}
],
"can_edit": true,
"has_unpublished_changes": false,
"review_every_days": 180,
"review_due_at": "2027-04-26",
"owner": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"updated_at": "2026-10-28T09:12:00+05:00",
"url": "https://app.jecheck.io/ui/instructions/5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a"
}
}POSTDuplicate an instruction
Creates a draft copy in the same folder with the same settings and permissions.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/duplicate' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/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/instructions/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', 'instructions/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": "instructions_duplicate",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
}
}
}{
"data": {
"uuid": "5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a",
"title": "Opening the coffee shop",
"icon": "coffee",
"summary": "Morning checklist for baristas",
"status": "published",
"folder": {
"id": 14,
"name": "Barista"
},
"folder_path": [
{
"id": 3,
"name": "Operations"
},
{
"id": 14,
"name": "Barista"
}
],
"tags": [
"Barista",
"Opening"
],
"version": 3,
"is_latest": true,
"is_draft": false,
"published_at": "2026-10-28T09:12:00+05:00",
"published_by": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"change_note": "New grinder settings",
"is_major": true,
"versions_count": 3,
"format": "markdown",
"content": "## Before opening\n\n1. Turn on the espresso machine\n2. Calibrate the grinder\n\n> **Important:** check fridge temperatures.",
"toc": [
{
"id": "before-opening",
"text": "Before opening",
"level": 2
}
],
"words": 412,
"read_minutes": 3,
"require_ack": true,
"acknowledged": false,
"needs_ack": true,
"attachments": [
{
"uuid": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
"kind": "file",
"name": "Cleaning schedule.pdf",
"mime": "application/pdf",
"size": 182044,
"width": null,
"height": null,
"url": "https://files.jecheck.io/instructions/761/2026/11/0c1d2e3f.pdf"
}
],
"can_edit": true,
"has_unpublished_changes": false,
"review_every_days": 180,
"review_due_at": "2027-04-26",
"owner": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"updated_at": "2026-10-28T09:12:00+05:00",
"url": "https://app.jecheck.io/ui/instructions/5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a"
}
}POSTMark an instruction as reviewed
Confirms the document is still up to date without changes: the next review date moves one period ahead. Only for published documents with a review period.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_reviewed |
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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/reviewed' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/reviewed', {
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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/reviewed",
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', 'instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/reviewed', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_reviewed",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
}
}
}{
"data": {
"uuid": "5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a",
"title": "Opening the coffee shop",
"icon": "coffee",
"summary": "Morning checklist for baristas",
"status": "published",
"folder": {
"id": 14,
"name": "Barista"
},
"folder_path": [
{
"id": 3,
"name": "Operations"
},
{
"id": 14,
"name": "Barista"
}
],
"tags": [
"Barista",
"Opening"
],
"version": 3,
"is_latest": true,
"is_draft": false,
"published_at": "2026-10-28T09:12:00+05:00",
"published_by": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"change_note": "New grinder settings",
"is_major": true,
"versions_count": 3,
"format": "markdown",
"content": "## Before opening\n\n1. Turn on the espresso machine\n2. Calibrate the grinder\n\n> **Important:** check fridge temperatures.",
"toc": [
{
"id": "before-opening",
"text": "Before opening",
"level": 2
}
],
"words": 412,
"read_minutes": 3,
"require_ack": true,
"acknowledged": false,
"needs_ack": true,
"attachments": [
{
"uuid": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
"kind": "file",
"name": "Cleaning schedule.pdf",
"mime": "application/pdf",
"size": 182044,
"width": null,
"height": null,
"url": "https://files.jecheck.io/instructions/761/2026/11/0c1d2e3f.pdf"
}
],
"can_edit": true,
"has_unpublished_changes": false,
"review_every_days": 180,
"review_due_at": "2027-04-26",
"owner": {
"id": 120,
"uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"name": "Daniyar Omarov"
},
"updated_at": "2026-10-28T09:12:00+05:00",
"url": "https://app.jecheck.io/ui/instructions/5d3c2b1a-9f8e-4d7c-8b6a-5f4e3d2c1b0a"
}
}DELDelete an instruction
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/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/instructions/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', 'instructions/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": "instructions_delete",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
}
}
}{
"data": {
"deleted": true
}
}POSTUpload a file to an instruction
Uploads an image (JPEG, PNG, WebP, GIF up to 15 MB) or a file (PDF, Office, TXT, CSV, ZIP, MP4, MOV up to 50 MB) and, by default, appends it to the end of the draft as an image or attachment block. Publish to show it to readers.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_files_upload |
| Content type | multipart/form-data application/json |
Path parameters
uuid
uuid
Required Request body
file
file
Required append
boolean
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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/files' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-F 'append=1' \
-F '[email protected]'const form = new FormData();
form.append('append', true);
form.append('file', fileInput.files[0]);
const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/files",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
data={"append":True},
files=[("file", 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', 'instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/files', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'multipart' => [
['name' => 'append', 'contents' => '1'],
['name' => 'file', 'contents' => fopen('photo.jpg', 'r')],
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_files_upload",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"append": true
}
}
}{
"data": {
"uuid": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
"kind": "file",
"name": "Cleaning schedule.pdf",
"mime": "application/pdf",
"size": 182044,
"width": null,
"height": null,
"url": "https://files.jecheck.io/instructions/761/2026/11/0c1d2e3f.pdf"
}
}GETGet instruction permissions
Who can view and who can edit the document, plus folders above that restrict viewing and the inherited editors. Editors of the document only.
| Token scope | read |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_access_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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/access' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/access', {
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/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/access",
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', 'instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/access', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_access_get",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
}
}
}{
"data": {
"view": [
{
"type": "position",
"id": 7,
"name": "Barista"
},
{
"type": "department",
"id": 12,
"name": "Abay Ave"
}
],
"edit": [
{
"type": "user",
"id": 120,
"name": "Daniyar Omarov"
}
],
"restricted_by": [],
"inherited_edit": {
"folder": null,
"subjects": []
}
}
}PUTSet instruction permissions
Replaces the view and/or edit lists of the document. Subjects: user, position, department (location), team. If the change would remove the acting user's own edit rights, they are kept as an editor.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_access_update |
Path parameters
uuid
uuid
Required Request body
view
array<object> | null
type
string
Required userpositiondepartmentteamid
integer
Required edit
array<object> | null
type
string
Required userpositiondepartmentteamid
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 PUT 'https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/access' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"view": [
{
"type": "user",
"id": 42
}
],
"edit": [
{
"type": "user",
"id": 42
}
]
}'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/access', {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"view": [
{
"type": "user",
"id": 42
}
],
"edit": [
{
"type": "user",
"id": 42
}
]
}),
});
const { data } = await res.json();import os, requests
res = requests.put(
"https://app.jecheck.io/api/ext/v1/instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/access",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"view":[{"type":"user","id":42}],"edit":[{"type":"user","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('PUT', 'instructions/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/access', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'view' => [
[
'type' => 'user',
'id' => 42,
],
],
'edit' => [
[
'type' => 'user',
'id' => 42,
],
],
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_access_update",
"arguments": {
"uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
"view": [
{
"type": "user",
"id": 42
}
],
"edit": [
{
"type": "user",
"id": 42
}
]
}
}
}{
"data": {
"view": [
{
"type": "position",
"id": 7,
"name": "Barista"
},
{
"type": "department",
"id": 12,
"name": "Abay Ave"
}
],
"edit": [
{
"type": "user",
"id": 120,
"name": "Daniyar Omarov"
}
],
"restricted_by": [],
"inherited_edit": {
"folder": null,
"subjects": []
}
}
}GETList folders
Folder tree visible to the acting user with document counts (count — directly in the folder, total — with subfolders). Readers see only branches that contain readable documents.
| Token scope | read |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_folders_list · 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/instructions/folders' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/folders', {
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/instructions/folders",
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', 'instructions/folders', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_folders_list",
"arguments": {}
}
}{
"data": [
{
"id": 14,
"parent_id": 3,
"name": "Barista",
"icon": "coffee",
"color": null,
"count": 6,
"total": 6,
"can_edit": false,
"restricted": false,
"children": []
}
]
}POSTCreate a folder
Creates a folder inside parent_id (requires edit rights on it) or in the root (knowledge-base managers only).
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_folders_create |
Request body
name
string
Required parent_id
integer | null
icon
string | null
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/instructions/folders' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"name": "Replace the broken fridge seal",
"parent_id": 42,
"icon": "string"
}'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/folders', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Replace the broken fridge seal",
"parent_id": 42,
"icon": "string"
}),
});
const { data } = await res.json();import os, requests
res = requests.post(
"https://app.jecheck.io/api/ext/v1/instructions/folders",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"name":"Replace the broken fridge seal","parent_id":42,"icon":"string"},
)
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', 'instructions/folders', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'name' => 'Replace the broken fridge seal',
'parent_id' => 42,
'icon' => 'string',
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_folders_create",
"arguments": {
"name": "Replace the broken fridge seal",
"parent_id": 42,
"icon": "string"
}
}
}{
"data": {
"id": 14,
"parent_id": 3,
"name": "Barista",
"icon": "coffee",
"color": null,
"count": 6,
"total": 6,
"can_edit": false,
"restricted": false,
"children": []
}
}PATCHUpdate a folder
Rename, change the icon/colour or move the folder (parent_id; moving requires edit rights on both the old and the new parent).
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_folders_update |
Path parameters
id
integer
Required Request body
name
string
parent_id
integer | null
icon
string | null
color
string | null
ai_visibility
string
inheritnonestaffclientResponses
| 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/instructions/folders/42' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"name": "Replace the broken fridge seal",
"parent_id": 42,
"icon": "string",
"color": "string"
}'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/folders/42', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Replace the broken fridge seal",
"parent_id": 42,
"icon": "string",
"color": "string"
}),
});
const { data } = await res.json();import os, requests
res = requests.patch(
"https://app.jecheck.io/api/ext/v1/instructions/folders/42",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"name":"Replace the broken fridge seal","parent_id":42,"icon":"string","color":"string"},
)
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', 'instructions/folders/42', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'name' => 'Replace the broken fridge seal',
'parent_id' => 42,
'icon' => 'string',
'color' => 'string',
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_folders_update",
"arguments": {
"id": 42,
"name": "Replace the broken fridge seal",
"parent_id": 42,
"icon": "string",
"color": "string"
}
}
}{
"data": {
"id": 14,
"parent_id": 3,
"name": "Barista",
"icon": "coffee",
"color": null,
"count": 6,
"total": 6,
"can_edit": false,
"restricted": false,
"children": []
}
}DELDelete a folder
Deletes the folder; its subfolders and documents move one level up and keep the folder's permissions.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_folders_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/instructions/folders/42' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/folders/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/instructions/folders/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', 'instructions/folders/42', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_folders_delete",
"arguments": {
"id": 42
}
}
}{
"data": {
"deleted": true
}
}GETGet folder permissions
Who can view and edit the folder (inherited by its documents and subfolders). Requires edit rights on the folder.
| Token scope | read |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_folders_access_get · read-only |
Path parameters
id
integer
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/instructions/folders/42/access' \
-H 'Authorization: Bearer $JECHECK_TOKEN'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/folders/42/access', {
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/instructions/folders/42/access",
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', 'instructions/folders/42/access', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_folders_access_get",
"arguments": {
"id": 42
}
}
}{
"data": {
"view": [
{
"type": "position",
"id": 7,
"name": "Barista"
},
{
"type": "department",
"id": 12,
"name": "Abay Ave"
}
],
"edit": [
{
"type": "user",
"id": 120,
"name": "Daniyar Omarov"
}
],
"restricted_by": [],
"inherited_edit": {
"folder": null,
"subjects": []
}
}
}PUTSet folder permissions
Replaces the view and/or edit lists of the folder. Same subjects and self-protection rules as for documents.
| Token scope | write |
|---|---|
| Permission | Any employee; results follow the token's visibility |
| MCP tool | instructions_folders_access_update |
Path parameters
id
integer
Required Request body
view
array<object> | null
type
string
Required userpositiondepartmentteamid
integer
Required edit
array<object> | null
type
string
Required userpositiondepartmentteamid
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 PUT 'https://app.jecheck.io/api/ext/v1/instructions/folders/42/access' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"view": [
{
"type": "user",
"id": 42
}
],
"edit": [
{
"type": "user",
"id": 42
}
]
}'const res = await fetch('https://app.jecheck.io/api/ext/v1/instructions/folders/42/access', {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"view": [
{
"type": "user",
"id": 42
}
],
"edit": [
{
"type": "user",
"id": 42
}
]
}),
});
const { data } = await res.json();import os, requests
res = requests.put(
"https://app.jecheck.io/api/ext/v1/instructions/folders/42/access",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"view":[{"type":"user","id":42}],"edit":[{"type":"user","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('PUT', 'instructions/folders/42/access', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'view' => [
[
'type' => 'user',
'id' => 42,
],
],
'edit' => [
[
'type' => 'user',
'id' => 42,
],
],
],
]);
$data = json_decode($res->getBody(), true)['data'];{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "instructions_folders_access_update",
"arguments": {
"id": 42,
"view": [
{
"type": "user",
"id": 42
}
],
"edit": [
{
"type": "user",
"id": 42
}
]
}
}
}{
"data": {
"view": [
{
"type": "position",
"id": 7,
"name": "Barista"
},
{
"type": "department",
"id": 12,
"name": "Abay Ave"
}
],
"edit": [
{
"type": "user",
"id": 120,
"name": "Daniyar Omarov"
}
],
"restricted_by": [],
"inherited_edit": {
"folder": null,
"subjects": []
}
}
}