jeCheckDevelopers
Get an API key

GETList checklists

GET /checklists

Checklists of the company, recently changed first, with structure size and usage over the last 30 days. Without checklists.edit only checklists available to the token user are returned (see "who can run" in the checklist). Deleted checklists (trash, last 30 days) — with deleted=true and the checklists.delete permission.

Token scoperead
Permission checklists.view
MCP toolchecklists_list · read-only

Query parameters

page integer
Page number, starting from 1. Default 1. Minimum 1.
per_page integer
Items per page (max 100). Default 25. Value 1–100.
folder_id integer
Only checklists of this folder; 0 — checklists without a folder. Minimum 0.
search string
Search in name and description. Maximum length 200.
updated_since date-time
Only checklists changed after this moment — use for incremental sync.
deleted boolean
Return deleted checklists (trash) instead of active ones; requires checklists.delete. Default false.

Responses

StatusDescription
200OK — a page of results with meta
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks checklists.view
422validation_failed — Invalid parameters — see error.fields
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl 'https://app.jecheck.io/api/ext/v1/checklists?folder_id=42' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/checklists?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/checklists",
    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', 'checklists', [
    '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": "checklists_list",
        "arguments": {
            "folder_id": 42
        }
    }
}
Response 200
{
  "data": [
    {
      "id": 5845,
      "name": "Daily dining room check",
      "description": "Opening check of the hall, restrooms and staff",
      "folder": {
        "id": 31,
        "name": "Front of house"
      },
      "scoring": "points",
      "sections_count": 4,
      "questions_count": 18,
      "author": {
        "id": 120,
        "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
        "name": "Daniyar Omarov"
      },
      "audits_30d": 12,
      "avg_result_30d": 81.4,
      "last_audit_at": "2026-11-02T18:40:00+05:00",
      "restricted": true,
      "ai_summary": false,
      "require_location": true,
      "require_signature": false,
      "deleted": false,
      "created_at": "2026-03-14T09:10:00+05:00",
      "updated_at": "2026-10-28T16:22:00+05:00",
      "url": "https://app.jecheck.io/ui/checklists/5845/edit"
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 25,
    "total": 1,
    "has_more": false
  }
}

GETRetrieve a checklist with its structure

GET /checklists/{id}

Settings, who may run it (access; empty — everyone) and the full structure: sections in order, questions with answer type, weight, photo requirement, type settings (options, norms, show_if display conditions, fail_all), responsible for fixing violations and auto-task settings. scoring: points — result is the share of earned weight, percent — share of compliant answers.

Token scoperead
Permission checklists.view
MCP toolchecklists_get · read-only

Path parameters

id integer Required
Checklist id.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks checklists.view
404not_found — The record does not exist or is not visible to the token
422validation_failed — Invalid parameters — see error.fields
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl 'https://app.jecheck.io/api/ext/v1/checklists/42' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/checklists/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/checklists/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('GET', 'checklists/42', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "checklists_get",
        "arguments": {
            "id": 42
        }
    }
}
Response 200
{
  "data": {
    "id": 5845,
    "name": "Daily dining room check",
    "description": "Opening check of the hall, restrooms and staff",
    "folder": {
      "id": 31,
      "name": "Front of house"
    },
    "scoring": "points",
    "sections_count": 4,
    "questions_count": 18,
    "author": {
      "id": 120,
      "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
      "name": "Daniyar Omarov"
    },
    "audits_30d": 12,
    "avg_result_30d": 81.4,
    "last_audit_at": "2026-11-02T18:40:00+05:00",
    "restricted": true,
    "ai_summary": false,
    "require_location": true,
    "require_signature": false,
    "deleted": false,
    "created_at": "2026-03-14T09:10:00+05:00",
    "updated_at": "2026-10-28T16:22:00+05:00",
    "url": "https://app.jecheck.io/ui/checklists/5845/edit",
    "available_from": "00:01",
    "available_to": "23:59",
    "select_manager": false,
    "send_to_location": false,
    "scenario_id": null,
    "access": [
      {
        "type": "position",
        "id": 14
      },
      {
        "type": "department",
        "id": 12
      }
    ],
    "sections": [
      {
        "id": 21626,
        "name": "Kitchen",
        "responsible": null,
        "questions": [
          {
            "id": 197426,
            "number": 1,
            "text": "Fridge temperature is within the norm",
            "description": "Check the display of fridge #2",
            "type": "number",
            "weight": 5,
            "can_skip": false,
            "photo_required": true,
            "settings": {
              "unit": "°C",
              "min": 2,
              "max": 6,
              "decimals": 1,
              "fail_all": true
            },
            "responsible": {
              "to": "role",
              "position_id": 14
            },
            "auto_task": {
              "enabled": true,
              "deadline_hours": 24
            }
          }
        ]
      }
    ]
  }
}

POSTCreate a checklist

POST /checklists

Creates a checklist with sections and questions in one call. Minimal question: {"text": "Floors are clean"} — a yes/no question with weight 1. Display conditions (settings.show_if) reference question ids, so add them later with checklists.structure.update.

Token scopewrite
Permission checklists.edit
MCP toolchecklists_create

Request body

name string Required
Checklist name (at least 5 characters). Length 5–255.
description string | null
Description. Maximum length 5000.
folder_id integer | null
Folder id (see checklists.folders.list).
scoring string
points — weighted score (default), percent — share of compliant answers. Default points.
pointspercent
sections array<object>
Sections with questions, in order. Maximum items 60.
name string Required
Section name. Length 2–512.
questions array<object> Required
Questions of the section, in order.
text string Required
Question wording (at least 5 characters). Length 5–2000.
description string | null
Hint for the auditor. Maximum length 5000.
type string
Answer type. yes_no (default) — complies / violation / not applicable; choice/multi need settings.options; number may have a norm settings.min/max; see the Checklists guide. Default yes_no.
yes_notextchoicemultinumberscaledatesignaturephotoinstructionbarcodeemployee
weight integer
Weight (points) of the question, 1–100. Default 1. Value 1–100.
photo_required boolean
The auditor must attach a photo. Default false.
can_skip boolean
The question may be skipped. Default false.
fail_all boolean
A violation on this question sets the whole audit result to 0 (scored types only).
settings object | null
Type settings, e.g. {"options":[{"id":"a1","label":"Clean","result":1,"score":1},{"id":"a2","label":"Dirty","result":2,"score":0}]} for choice, {"unit":"°C","min":2,"max":6} for number, {"min":1,"max":5,"pass":4} for scale; common keys fail_all, show_if, media.

Responses

StatusDescription
201Created
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks checklists.edit, is read-only
422validation_failed — Invalid parameters — see error.fields
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl -X POST 'https://app.jecheck.io/api/ext/v1/checklists' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Replace the broken fridge seal",
    "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
    "folder_id": 42,
    "scoring": "points"
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/checklists', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "Replace the broken fridge seal",
      "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
      "folder_id": 42,
      "scoring": "points"
  }),
});
const { data } = await res.json();
import os, requests

res = requests.post(
    "https://app.jecheck.io/api/ext/v1/checklists",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"name":"Replace the broken fridge seal","description":"Seal on fridge #2 is torn, temperature rises to +9 °C.","folder_id":42,"scoring":"points"},
)
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', 'checklists', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'name' => 'Replace the broken fridge seal',
        'description' => 'Seal on fridge #2 is torn, temperature rises to +9 °C.',
        'folder_id' => 42,
        'scoring' => 'points',
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "checklists_create",
        "arguments": {
            "name": "Replace the broken fridge seal",
            "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
            "folder_id": 42,
            "scoring": "points"
        }
    }
}
Response 201
{
  "data": {
    "id": 5845,
    "name": "Daily dining room check",
    "description": "Opening check of the hall, restrooms and staff",
    "folder": {
      "id": 31,
      "name": "Front of house"
    },
    "scoring": "points",
    "sections_count": 4,
    "questions_count": 18,
    "author": {
      "id": 120,
      "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
      "name": "Daniyar Omarov"
    },
    "audits_30d": 12,
    "avg_result_30d": 81.4,
    "last_audit_at": "2026-11-02T18:40:00+05:00",
    "restricted": true,
    "ai_summary": false,
    "require_location": true,
    "require_signature": false,
    "deleted": false,
    "created_at": "2026-03-14T09:10:00+05:00",
    "updated_at": "2026-10-28T16:22:00+05:00",
    "url": "https://app.jecheck.io/ui/checklists/5845/edit",
    "available_from": "00:01",
    "available_to": "23:59",
    "select_manager": false,
    "send_to_location": false,
    "scenario_id": null,
    "access": [
      {
        "type": "position",
        "id": 14
      },
      {
        "type": "department",
        "id": 12
      }
    ],
    "sections": [
      {
        "id": 21626,
        "name": "Kitchen",
        "responsible": null,
        "questions": [
          {
            "id": 197426,
            "number": 1,
            "text": "Fridge temperature is within the norm",
            "description": "Check the display of fridge #2",
            "type": "number",
            "weight": 5,
            "can_skip": false,
            "photo_required": true,
            "settings": {
              "unit": "°C",
              "min": 2,
              "max": 6,
              "decimals": 1,
              "fail_all": true
            },
            "responsible": {
              "to": "role",
              "position_id": 14
            },
            "auto_task": {
              "enabled": true,
              "deadline_hours": 24
            }
          }
        ]
      }
    ]
  }
}

PUTReplace the checklist structure

PUT /checklists/{id}/structure

Sends the whole structure at once (as in checklists.get). Pass id for sections and questions you keep — their audit history stays linked; items without id are created, items not listed are removed. Existing sections cannot be reordered (new ones are appended at the end); questions can be reordered and moved between sections. For an existing question without settings the current settings are kept.

Token scopewrite
Permission checklists.edit
MCP toolchecklists_structure_update

Path parameters

id integer Required
Checklist id.

Request body

name string
New name (kept if omitted). Length 5–255.
description string | null
New description (kept if omitted). Maximum length 5000.
sections array<object> Required
The complete new structure. Existing sections keep their order (new sections can only be appended); sections and questions not listed are removed. Maximum items 60.
id integer | null
Existing section id to keep; omit for a new section.
name string Required
Section name. Length 2–512.
questions array<object> Required
Questions of the section, in order.
id integer | null
Existing question id to keep (its audit history stays linked); omit for a new question.
text string Required
Question wording (at least 5 characters). Length 5–2000.
description string | null
Hint for the auditor. Maximum length 5000.
type string
Answer type. yes_no (default) — complies / violation / not applicable; choice/multi need settings.options; number may have a norm settings.min/max; see the Checklists guide. Default yes_no.
yes_notextchoicemultinumberscaledatesignaturephotoinstructionbarcodeemployee
weight integer
Weight (points) of the question, 1–100. Default 1. Value 1–100.
photo_required boolean
The auditor must attach a photo. Default false.
can_skip boolean
The question may be skipped. Default false.
fail_all boolean
A violation on this question sets the whole audit result to 0 (scored types only).
settings object | null
Type settings, e.g. {"options":[{"id":"a1","label":"Clean","result":1,"score":1},{"id":"a2","label":"Dirty","result":2,"score":0}]} for choice, {"unit":"°C","min":2,"max":6} for number, {"min":1,"max":5,"pass":4} for scale; common keys fail_all, show_if, media.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks checklists.edit, is read-only
404not_found — The record does not exist or is not visible to the token
422validation_failed — Invalid parameters — see error.fields
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl -X PUT 'https://app.jecheck.io/api/ext/v1/checklists/42/structure' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Replace the broken fridge seal",
    "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
    "sections": [
        {
            "id": 42,
            "name": "Replace the broken fridge seal",
            "questions": [
                {
                    "id": 42,
                    "text": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
                    "description": "Seal on fridge #2 is torn, temperature rises to +9 °C."
                }
            ]
        }
    ]
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/checklists/42/structure', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "Replace the broken fridge seal",
      "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
      "sections": [
          {
              "id": 42,
              "name": "Replace the broken fridge seal",
              "questions": [
                  {
                      "id": 42,
                      "text": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
                      "description": "Seal on fridge #2 is torn, temperature rises to +9 °C."
                  }
              ]
          }
      ]
  }),
});
const { data } = await res.json();
import os, requests

res = requests.put(
    "https://app.jecheck.io/api/ext/v1/checklists/42/structure",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"name":"Replace the broken fridge seal","description":"Seal on fridge #2 is torn, temperature rises to +9 °C.","sections":[{"id":42,"name":"Replace the broken fridge seal","questions":[{"id":42,"text":"Seal on fridge #2 is torn, temperature rises to +9 °C.","description":"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('PUT', 'checklists/42/structure', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'name' => 'Replace the broken fridge seal',
        'description' => 'Seal on fridge #2 is torn, temperature rises to +9 °C.',
        'sections' => [
            [
                'id' => 42,
                'name' => 'Replace the broken fridge seal',
                'questions' => [
                    [
                        'id' => 42,
                        'text' => 'Seal on fridge #2 is torn, temperature rises to +9 °C.',
                        'description' => '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": "checklists_structure_update",
        "arguments": {
            "id": 42,
            "name": "Replace the broken fridge seal",
            "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
            "sections": [
                {
                    "id": 42,
                    "name": "Replace the broken fridge seal",
                    "questions": [
                        {
                            "id": 42,
                            "text": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
                            "description": "Seal on fridge #2 is torn, temperature rises to +9 °C."
                        }
                    ]
                }
            ]
        }
    }
}
Response 200
{
  "data": {
    "id": 5845,
    "name": "Daily dining room check",
    "description": "Opening check of the hall, restrooms and staff",
    "folder": {
      "id": 31,
      "name": "Front of house"
    },
    "scoring": "points",
    "sections_count": 4,
    "questions_count": 18,
    "author": {
      "id": 120,
      "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
      "name": "Daniyar Omarov"
    },
    "audits_30d": 12,
    "avg_result_30d": 81.4,
    "last_audit_at": "2026-11-02T18:40:00+05:00",
    "restricted": true,
    "ai_summary": false,
    "require_location": true,
    "require_signature": false,
    "deleted": false,
    "created_at": "2026-03-14T09:10:00+05:00",
    "updated_at": "2026-10-28T16:22:00+05:00",
    "url": "https://app.jecheck.io/ui/checklists/5845/edit",
    "available_from": "00:01",
    "available_to": "23:59",
    "select_manager": false,
    "send_to_location": false,
    "scenario_id": null,
    "access": [
      {
        "type": "position",
        "id": 14
      },
      {
        "type": "department",
        "id": 12
      }
    ],
    "sections": [
      {
        "id": 21626,
        "name": "Kitchen",
        "responsible": null,
        "questions": [
          {
            "id": 197426,
            "number": 1,
            "text": "Fridge temperature is within the norm",
            "description": "Check the display of fridge #2",
            "type": "number",
            "weight": 5,
            "can_skip": false,
            "photo_required": true,
            "settings": {
              "unit": "°C",
              "min": 2,
              "max": 6,
              "decimals": 1,
              "fail_all": true
            },
            "responsible": {
              "to": "role",
              "position_id": 14
            },
            "auto_task": {
              "enabled": true,
              "deadline_hours": 24
            }
          }
        ]
      }
    ]
  }
}

PATCHUpdate checklist settings

PATCH /checklists/{id}

Partial update of the checklist settings: send only the fields to change. The structure is changed with checklists.structure.update. ai_summary (AI report on each audit) requires the AI feature of the plan.

Token scopewrite
Permission checklists.edit
MCP toolchecklists_update

Path parameters

id integer Required
Checklist id.

Request body

name string
Name. Length 5–255.
description string | null
Description. Maximum length 5000.
folder_id integer | null
Folder id; null — no folder.
scoring string
Scoring mode.
pointspercent
ai_summary boolean
Generate an AI report for each audit.
require_location boolean
The app records the auditor geolocation.
require_signature boolean
The audit must be signed.
select_manager boolean
The auditor picks the location manager at the end of the audit.
send_to_location boolean
Send the report to the location managers.
available_from string
The checklist can be started from this time of day, HH:MM.
available_to string
…and until this time of day, HH:MM.
scenario_id integer | null
Automation scenario for violations; null — the company default.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks checklists.edit, is read-only
404not_found — The record does not exist or is not visible to the token
422validation_failed — Invalid parameters — see error.fields
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl -X PATCH 'https://app.jecheck.io/api/ext/v1/checklists/42' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Replace the broken fridge seal",
    "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
    "folder_id": 42,
    "scoring": "points"
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/checklists/42', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "Replace the broken fridge seal",
      "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
      "folder_id": 42,
      "scoring": "points"
  }),
});
const { data } = await res.json();
import os, requests

res = requests.patch(
    "https://app.jecheck.io/api/ext/v1/checklists/42",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"name":"Replace the broken fridge seal","description":"Seal on fridge #2 is torn, temperature rises to +9 °C.","folder_id":42,"scoring":"points"},
)
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', 'checklists/42', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'name' => 'Replace the broken fridge seal',
        'description' => 'Seal on fridge #2 is torn, temperature rises to +9 °C.',
        'folder_id' => 42,
        'scoring' => 'points',
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "checklists_update",
        "arguments": {
            "id": 42,
            "name": "Replace the broken fridge seal",
            "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
            "folder_id": 42,
            "scoring": "points"
        }
    }
}
Response 200
{
  "data": {
    "id": 5845,
    "name": "Daily dining room check",
    "description": "Opening check of the hall, restrooms and staff",
    "folder": {
      "id": 31,
      "name": "Front of house"
    },
    "scoring": "points",
    "sections_count": 4,
    "questions_count": 18,
    "author": {
      "id": 120,
      "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
      "name": "Daniyar Omarov"
    },
    "audits_30d": 12,
    "avg_result_30d": 81.4,
    "last_audit_at": "2026-11-02T18:40:00+05:00",
    "restricted": true,
    "ai_summary": false,
    "require_location": true,
    "require_signature": false,
    "deleted": false,
    "created_at": "2026-03-14T09:10:00+05:00",
    "updated_at": "2026-10-28T16:22:00+05:00",
    "url": "https://app.jecheck.io/ui/checklists/5845/edit",
    "available_from": "00:01",
    "available_to": "23:59",
    "select_manager": false,
    "send_to_location": false,
    "scenario_id": null,
    "access": [
      {
        "type": "position",
        "id": 14
      },
      {
        "type": "department",
        "id": 12
      }
    ],
    "sections": [
      {
        "id": 21626,
        "name": "Kitchen",
        "responsible": null,
        "questions": [
          {
            "id": 197426,
            "number": 1,
            "text": "Fridge temperature is within the norm",
            "description": "Check the display of fridge #2",
            "type": "number",
            "weight": 5,
            "can_skip": false,
            "photo_required": true,
            "settings": {
              "unit": "°C",
              "min": 2,
              "max": 6,
              "decimals": 1,
              "fail_all": true
            },
            "responsible": {
              "to": "role",
              "position_id": 14
            },
            "auto_task": {
              "enabled": true,
              "deadline_hours": 24
            }
          }
        ]
      }
    ]
  }
}

POSTDuplicate a checklist

POST /checklists/{id}/duplicate

Copies the checklist with all sections, questions, settings and access rules. The copy gets the original name with a fixed "copy" suffix (written in Russian, as in the web app) — rename it with checklists.update.

Token scopewrite
Permission checklists.edit
MCP toolchecklists_duplicate

Path parameters

id integer Required
Checklist id.

Responses

StatusDescription
201Created
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks checklists.edit, is read-only
404not_found — The record does not exist or is not visible to the token
422validation_failed — Invalid parameters — see error.fields
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl -X POST 'https://app.jecheck.io/api/ext/v1/checklists/42/duplicate' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/checklists/42/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/checklists/42/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', 'checklists/42/duplicate', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "checklists_duplicate",
        "arguments": {
            "id": 42
        }
    }
}
Response 201
{
  "data": {
    "id": 5845,
    "name": "Daily dining room check",
    "description": "Opening check of the hall, restrooms and staff",
    "folder": {
      "id": 31,
      "name": "Front of house"
    },
    "scoring": "points",
    "sections_count": 4,
    "questions_count": 18,
    "author": {
      "id": 120,
      "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
      "name": "Daniyar Omarov"
    },
    "audits_30d": 12,
    "avg_result_30d": 81.4,
    "last_audit_at": "2026-11-02T18:40:00+05:00",
    "restricted": true,
    "ai_summary": false,
    "require_location": true,
    "require_signature": false,
    "deleted": false,
    "created_at": "2026-03-14T09:10:00+05:00",
    "updated_at": "2026-10-28T16:22:00+05:00",
    "url": "https://app.jecheck.io/ui/checklists/5845/edit",
    "available_from": "00:01",
    "available_to": "23:59",
    "select_manager": false,
    "send_to_location": false,
    "scenario_id": null,
    "access": [
      {
        "type": "position",
        "id": 14
      },
      {
        "type": "department",
        "id": 12
      }
    ],
    "sections": [
      {
        "id": 21626,
        "name": "Kitchen",
        "responsible": null,
        "questions": [
          {
            "id": 197426,
            "number": 1,
            "text": "Fridge temperature is within the norm",
            "description": "Check the display of fridge #2",
            "type": "number",
            "weight": 5,
            "can_skip": false,
            "photo_required": true,
            "settings": {
              "unit": "°C",
              "min": 2,
              "max": 6,
              "decimals": 1,
              "fail_all": true
            },
            "responsible": {
              "to": "role",
              "position_id": 14
            },
            "auto_task": {
              "enabled": true,
              "deadline_hours": 24
            }
          }
        ]
      }
    ]
  }
}

DELDelete a checklist

DELETE /checklists/{id}

Moves the checklist to the trash for 30 days (restore with checklists.restore). Audits already conducted stay in the journal and analytics.

Token scopewrite
Permission checklists.delete
MCP toolchecklists_delete · destructive

Path parameters

id integer Required
Checklist id.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks checklists.delete, is read-only
404not_found — The record does not exist or is not visible to the token
422validation_failed — Invalid parameters — see error.fields
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl -X DELETE 'https://app.jecheck.io/api/ext/v1/checklists/42' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/checklists/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/checklists/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', 'checklists/42', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "checklists_delete",
        "arguments": {
            "id": 42
        }
    }
}
Response 200
{
  "data": {
    "deleted": true
  }
}

POSTRestore a deleted checklist

POST /checklists/{id}/restore

Returns a checklist from the trash: it is available again in the list, the planner and the app.

Token scopewrite
Permission checklists.delete
MCP toolchecklists_restore

Path parameters

id integer Required
Checklist id.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks checklists.delete, is read-only
404not_found — The record does not exist or is not visible to the token
422validation_failed — Invalid parameters — see error.fields
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl -X POST 'https://app.jecheck.io/api/ext/v1/checklists/42/restore' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/checklists/42/restore', {
  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/checklists/42/restore",
    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', 'checklists/42/restore', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "checklists_restore",
        "arguments": {
            "id": 42
        }
    }
}
Response 200
{
  "data": {
    "id": 5845,
    "name": "Daily dining room check",
    "description": "Opening check of the hall, restrooms and staff",
    "folder": {
      "id": 31,
      "name": "Front of house"
    },
    "scoring": "points",
    "sections_count": 4,
    "questions_count": 18,
    "author": {
      "id": 120,
      "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
      "name": "Daniyar Omarov"
    },
    "audits_30d": 12,
    "avg_result_30d": 81.4,
    "last_audit_at": "2026-11-02T18:40:00+05:00",
    "restricted": true,
    "ai_summary": false,
    "require_location": true,
    "require_signature": false,
    "deleted": false,
    "created_at": "2026-03-14T09:10:00+05:00",
    "updated_at": "2026-10-28T16:22:00+05:00",
    "url": "https://app.jecheck.io/ui/checklists/5845/edit",
    "available_from": "00:01",
    "available_to": "23:59",
    "select_manager": false,
    "send_to_location": false,
    "scenario_id": null,
    "access": [
      {
        "type": "position",
        "id": 14
      },
      {
        "type": "department",
        "id": 12
      }
    ],
    "sections": [
      {
        "id": 21626,
        "name": "Kitchen",
        "responsible": null,
        "questions": [
          {
            "id": 197426,
            "number": 1,
            "text": "Fridge temperature is within the norm",
            "description": "Check the display of fridge #2",
            "type": "number",
            "weight": 5,
            "can_skip": false,
            "photo_required": true,
            "settings": {
              "unit": "°C",
              "min": 2,
              "max": 6,
              "decimals": 1,
              "fail_all": true
            },
            "responsible": {
              "to": "role",
              "position_id": 14
            },
            "auto_task": {
              "enabled": true,
              "deadline_hours": 24
            }
          }
        ]
      }
    ]
  }
}

POSTMove checklists to a folder

POST /checklists/move
Token scopewrite
Permission checklists.edit
MCP toolchecklists_move

Request body

ids array<integer> Required
Checklist ids. Items 1–500.
folder_id integer | null Required
Target folder id; null — no folder.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks checklists.edit, is read-only
422validation_failed — Invalid parameters — see error.fields
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl -X POST 'https://app.jecheck.io/api/ext/v1/checklists/move' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "ids": [
        12,
        14
    ],
    "folder_id": 42
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/checklists/move', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "ids": [
          12,
          14
      ],
      "folder_id": 42
  }),
});
const { data } = await res.json();
import os, requests

res = requests.post(
    "https://app.jecheck.io/api/ext/v1/checklists/move",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"ids":[12,14],"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('POST', 'checklists/move', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'ids' => [
            12,
            14,
        ],
        'folder_id' => 42,
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "checklists_move",
        "arguments": {
            "ids": [
                12,
                14
            ],
            "folder_id": 42
        }
    }
}
Response 200
{
  "data": {
    "moved": 3
  }
}

GETGet who can run a checklist

GET /checklists/{id}/access

Rules of "who can run" the checklist in the mobile app: employees (user), positions (position), locations (department) and teams (team). An empty list means everyone; administrators can always run any checklist.

Token scoperead
Permission checklists.view
MCP toolchecklists_access_get · read-only

Path parameters

id integer Required
Checklist id.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks checklists.view
404not_found — The record does not exist or is not visible to the token
422validation_failed — Invalid parameters — see error.fields
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl 'https://app.jecheck.io/api/ext/v1/checklists/42/access' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/checklists/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/checklists/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', 'checklists/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": "checklists_access_get",
        "arguments": {
            "id": 42
        }
    }
}
Response 200
{
  "data": {
    "rules": [
      {
        "type": "position",
        "id": 14
      },
      {
        "type": "user",
        "id": 311
      }
    ]
  }
}

PUTSet who can run a checklist

PUT /checklists/{id}/access

Replaces the access rules. Subjects of another company are ignored. An empty rules list makes the checklist available to everyone. The planner only lets you assign audits of a checklist to people who can run it.

Token scopewrite
Permission checklists.edit
MCP toolchecklists_access_set

Path parameters

id integer Required
Checklist id.

Request body

rules array<object> Required
Rules; empty — available to everyone. Maximum items 500.
type string Required
Subject type.
userpositiondepartmentteam
id integer Required
Id of the employee, position, location or team.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks checklists.edit, is read-only
404not_found — The record does not exist or is not visible to the token
422validation_failed — Invalid parameters — see error.fields
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl -X PUT 'https://app.jecheck.io/api/ext/v1/checklists/42/access' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "rules": [
        {
            "type": "user",
            "id": 42
        }
    ]
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/checklists/42/access', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "rules": [
          {
              "type": "user",
              "id": 42
          }
      ]
  }),
});
const { data } = await res.json();
import os, requests

res = requests.put(
    "https://app.jecheck.io/api/ext/v1/checklists/42/access",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"rules":[{"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', 'checklists/42/access', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'rules' => [
            [
                'type' => 'user',
                'id' => 42,
            ],
        ],
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "checklists_access_set",
        "arguments": {
            "id": 42,
            "rules": [
                {
                    "type": "user",
                    "id": 42
                }
            ]
        }
    }
}
Response 200
{
  "data": {
    "rules": [
      {
        "type": "position",
        "id": 14
      }
    ]
  }
}

PUTSet who fixes violations of a section or question

PUT /checklists/{id}/responsible

"Who fixes" a violation: managers — location managers, role — employees of a position (position_id), team — a team queue (team_id), user — a specific employee (user_id). null — default (a question inherits its section, a section — location managers). Automation scenarios and auto-tasks assign violations by this setting.

Token scopewrite
Permission checklists.edit
MCP toolchecklists_responsible_set

Path parameters

id integer Required
Checklist id.

Request body

target string Required
What to configure.
sectionquestion
target_id integer Required
Section or question id of this checklist.
responsible object | null Required
Target, or null to reset to the default.
to string
Who fixes: managers, role, team or user.
managersroleteamuser
position_id integer
team_id integer
user_id integer

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks checklists.edit, is read-only
404not_found — The record does not exist or is not visible to the token
422validation_failed — Invalid parameters — see error.fields
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl -X PUT 'https://app.jecheck.io/api/ext/v1/checklists/42/responsible' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "target": "section",
    "target_id": 42,
    "responsible": {
        "to": "managers",
        "position_id": 42,
        "team_id": 42
    }
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/checklists/42/responsible', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "target": "section",
      "target_id": 42,
      "responsible": {
          "to": "managers",
          "position_id": 42,
          "team_id": 42
      }
  }),
});
const { data } = await res.json();
import os, requests

res = requests.put(
    "https://app.jecheck.io/api/ext/v1/checklists/42/responsible",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"target":"section","target_id":42,"responsible":{"to":"managers","position_id":42,"team_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', 'checklists/42/responsible', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'target' => 'section',
        'target_id' => 42,
        'responsible' => [
            'to' => 'managers',
            'position_id' => 42,
            'team_id' => 42,
        ],
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "checklists_responsible_set",
        "arguments": {
            "id": 42,
            "target": "section",
            "target_id": 42,
            "responsible": {
                "to": "managers",
                "position_id": 42,
                "team_id": 42
            }
        }
    }
}
Response 200
{
  "data": {
    "target": "question",
    "target_id": 197426,
    "responsible": {
      "to": "role",
      "position_id": 14
    }
  }
}

POSTUpload a reference photo

POST /checklists/{id}/media

Uploads a reference image ("how it should look") and returns its public URL. Put the URL into settings.media of a question with checklists.structure.update (up to 5 per question).

Token scopewrite
Permission checklists.edit
MCP toolchecklists_media_upload
Content typemultipart/form-data application/json

Path parameters

id integer Required
Checklist id.

Request body

image file Required
Image file, up to 10 MB.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks checklists.edit, is read-only
404not_found — The record does not exist or is not visible to the token
422validation_failed — Invalid parameters — see error.fields
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl -X POST 'https://app.jecheck.io/api/ext/v1/checklists/42/media' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -F '[email protected]'
const form = new FormData();
form.append('image', fileInput.files[0]);

const res = await fetch('https://app.jecheck.io/api/ext/v1/checklists/42/media', {
  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/checklists/42/media",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    data=[],
    files=[("image", 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', 'checklists/42/media', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'multipart' => [
        ['name' => 'image', 'contents' => fopen('photo.jpg', 'r')],
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "checklists_media_upload",
        "arguments": {
            "id": 42
        }
    }
}
Response 200
{
  "data": {
    "url": "https://jecheck.s3.eu-west-1.amazonaws.com/checklists/761/reference/9f1c2b.jpg"
  }
}

GETList checklist folders

GET /checklists/folders

Folders are flat and shared with the mobile app.

Token scoperead
Permission checklists.view
MCP toolchecklists_folders_list · read-only

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks checklists.view
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl 'https://app.jecheck.io/api/ext/v1/checklists/folders' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/checklists/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/checklists/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', 'checklists/folders', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "checklists_folders_list",
        "arguments": {}
    }
}
Response 200
{
  "data": [
    {
      "id": 31,
      "name": "Front of house",
      "color": "blue",
      "checklists_count": 7
    }
  ]
}

POSTCreate a checklist folder

POST /checklists/folders
Token scopewrite
Permission checklists.edit
MCP toolchecklists_folders_create

Request body

name string Required
Folder name, unique in the company. Length 1–100.
color string | null
Color label.
bluegreenamberredviolettealgray
checklist_ids array<integer>
Checklists to move into the new folder. Maximum items 500.

Responses

StatusDescription
201Created
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks checklists.edit, is read-only
422validation_failed — Invalid parameters — see error.fields
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl -X POST 'https://app.jecheck.io/api/ext/v1/checklists/folders' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Replace the broken fridge seal",
    "color": "blue",
    "checklist_ids": [
        12,
        14
    ]
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/checklists/folders', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "Replace the broken fridge seal",
      "color": "blue",
      "checklist_ids": [
          12,
          14
      ]
  }),
});
const { data } = await res.json();
import os, requests

res = requests.post(
    "https://app.jecheck.io/api/ext/v1/checklists/folders",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"name":"Replace the broken fridge seal","color":"blue","checklist_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', 'checklists/folders', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'name' => 'Replace the broken fridge seal',
        'color' => 'blue',
        'checklist_ids' => [
            12,
            14,
        ],
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "checklists_folders_create",
        "arguments": {
            "name": "Replace the broken fridge seal",
            "color": "blue",
            "checklist_ids": [
                12,
                14
            ]
        }
    }
}
Response 201
{
  "data": {
    "id": 31,
    "name": "Front of house",
    "color": "blue",
    "checklists_count": 7
  }
}

PATCHRename or recolor a checklist folder

PATCH /checklists/folders/{id}
Token scopewrite
Permission checklists.edit
MCP toolchecklists_folders_update

Path parameters

id integer Required
Folder id.

Request body

name string
New name. Length 1–100.
color string | null
Color label.
bluegreenamberredviolettealgray

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks checklists.edit, is read-only
404not_found — The record does not exist or is not visible to the token
422validation_failed — Invalid parameters — see error.fields
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl -X PATCH 'https://app.jecheck.io/api/ext/v1/checklists/folders/42' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Replace the broken fridge seal",
    "color": "blue"
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/checklists/folders/42', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "Replace the broken fridge seal",
      "color": "blue"
  }),
});
const { data } = await res.json();
import os, requests

res = requests.patch(
    "https://app.jecheck.io/api/ext/v1/checklists/folders/42",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"name":"Replace the broken fridge seal","color":"blue"},
)
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', 'checklists/folders/42', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'name' => 'Replace the broken fridge seal',
        'color' => 'blue',
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "checklists_folders_update",
        "arguments": {
            "id": 42,
            "name": "Replace the broken fridge seal",
            "color": "blue"
        }
    }
}
Response 200
{
  "data": {
    "id": 31,
    "name": "Front of house",
    "color": "blue",
    "checklists_count": 7
  }
}

DELDelete a checklist folder

DELETE /checklists/folders/{id}

Deletes the folder; its checklists are not deleted and move to "no folder".

Token scopewrite
Permission checklists.edit
MCP toolchecklists_folders_delete · destructive

Path parameters

id integer Required
Folder id.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks checklists.edit, is read-only
404not_found — The record does not exist or is not visible to the token
422validation_failed — Invalid parameters — see error.fields
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl -X DELETE 'https://app.jecheck.io/api/ext/v1/checklists/folders/42' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/checklists/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/checklists/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', 'checklists/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": "checklists_folders_delete",
        "arguments": {
            "id": 42
        }
    }
}
Response 200
{
  "data": {
    "deleted": true
  }
}