jeCheckDevelopers
Get an API key

HR

Employee HR records: the HR card, personal data, HR documents, hiring with onboarding checklists, transfers, dismissal and absences (vacations, sick leave). Permissions apply to the employee's locations; personal data, documents and pay rates are returned only with their own permissions and every view is written to the access log.

Operations
GET/hr/employees/{uuid}Retrieve an employee HR card PATCH/hr/employees/{uuid}/profileUpdate personal data PATCH/hr/employees/{uuid}/workUpdate work data POST/hr/hireHire an employee POST/hr/employees/{uuid}/transferTransfer an employee POST/hr/employees/{uuid}/dismissDismiss an employee POST/hr/employees/{uuid}/cancel-dismissalCancel a dismissal POST/hr/employees/{uuid}/rehireRehire a former employee POST/hr/employees/{uuid}/checklistsStart a checklist for an employee POST/hr/employees/{uuid}/notesAdd a note to the HR history DELETE/hr/employees/{uuid}/notes/{id}Delete a note from the HR history GET/hr/employees/{uuid}/documentsList HR documents of an employee POST/hr/employees/{uuid}/documentsAdd an HR document PATCH/hr/employees/{uuid}/documents/{id}Update an HR document DELETE/hr/employees/{uuid}/documents/{id}Delete an HR document GET/hr/employees/{uuid}/documents/{id}/fileDownload an HR document file GET/hr/absencesList absences GET/hr/absences/balancesGet vacation balances POST/hr/absencesAdd an absence PATCH/hr/absences/{uuid}Update an absence POST/hr/absences/{uuid}/decideApprove or reject an absence request POST/hr/absences/{uuid}/cancelCancel an absence GET/hr/checklistsList onboarding and offboarding checklists GET/hr/checklists/{uuid}Retrieve a checklist POST/hr/checklists/{uuid}/itemsAdd a checklist item PATCH/hr/checklist-items/{id}Update a checklist item POST/hr/checklist-items/{id}/statusComplete, skip or reopen a checklist item DELETE/hr/checklist-items/{id}Delete a checklist item POST/hr/checklists/{uuid}/cancelCancel a checklist POST/hr/checklists/{uuid}/rescheduleMove the start date of a checklist GET/hr/templatesList checklist templates GET/hr/templates/{id}Retrieve a checklist template POST/hr/templatesCreate a checklist template PUT/hr/templates/{id}Replace a checklist template POST/hr/templates/{id}/duplicateDuplicate a checklist template DELETE/hr/templates/{id}Delete a checklist template GET/hr/settingsGet HR settings PATCH/hr/settingsUpdate HR settings

GETRetrieve an employee HR card

GET /hr/employees/{uuid}

Work data, HR history, vacation balance, absences, documents and onboarding / offboarding checklists of an employee. Sections the token has no permission for are empty or null on the employee's locations: HR data — hr.card, personal data — hr.personal, documents — hr.documents, pay — pay.rates.view, contacts — users.contacts. Each view of sensitive data is written to the access log.

Token scoperead
Permission users.view
MCP toolhr_employees_get · read-only

Path parameters

uuid uuid Required
Employee UUID.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks users.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/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
  },
});
const { data } = await res.json();
import os, requests

res = requests.get(
    "https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
)
res.raise_for_status()
data = res.json()["data"]
$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);

$res = $client->request('GET', 'hr/employees/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": "hr_employees_get",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
        }
    }
}
Response 200
{
  "data": {
    "employee": {
      "id": 311,
      "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
      "name": "Aigerim",
      "lastname": "Sadykova",
      "email": "[email protected]",
      "phone": "+7 701 111 22 33",
      "is_admin": false,
      "deleted": false,
      "deleted_at": null,
      "web_access": false,
      "position": {
        "id": 7,
        "name": "Barista"
      },
      "locations": [
        {
          "id": 12,
          "name": "Abay Ave",
          "kind": "home"
        }
      ],
      "home_location_id": 12,
      "work_anywhere": false,
      "teams": [
        {
          "id": 3,
          "name": "Bar",
          "is_head": false
        }
      ],
      "created_at": "2026-03-01T09:00:00+05:00",
      "last_seen_at": "2026-11-03T08:12:00+05:00",
      "url": "https://app.jecheck.io/ui/users/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b"
    },
    "status": {
      "status": "probation",
      "until": "2026-12-01",
      "absence_type": null,
      "hired_at": "2026-09-01",
      "fired_at": null,
      "personnel_no": "0114",
      "onboarding": {
        "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
        "kind": "onboarding",
        "done": 3,
        "total": 9,
        "overdue": 1
      }
    },
    "profile": {
      "middle_name": "Nurlanovna",
      "gender": "female",
      "birth_date": "1998-04-12",
      "birth_place": null,
      "citizenship": null,
      "marital_status": null,
      "children": null,
      "work_phone": null,
      "personal_phone": "+7 701 000 00 00",
      "personal_email": null,
      "address_actual": null,
      "address_registered": null,
      "tax_id": null,
      "insurance_no": null,
      "id_doc_type": null,
      "id_doc_number": null,
      "id_doc_issuer": null,
      "id_doc_issued_at": null,
      "id_doc_expires_at": null,
      "emergency_name": null,
      "emergency_relation": null,
      "emergency_phone": null,
      "bank_name": null,
      "bank_account": null,
      "education": null,
      "languages": null,
      "clothing_size": null,
      "shoe_size": null,
      "note": null,
      "custom": {}
    },
    "work": {
      "hired_at": "2026-09-01",
      "fired_at": null,
      "personnel_no": "0114",
      "employment": "full",
      "probation_until": "2026-12-01",
      "contract_type": "permanent",
      "contract_number": "TD-2026/114",
      "contract_date": "2026-09-01",
      "contract_until": null,
      "vacation_days": null,
      "vacation_adjust": 0,
      "manager": {
        "id": 120,
        "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
        "name": "Daniyar Omarov"
      },
      "team_managers": [],
      "reports": []
    },
    "pay": {
      "pay_type": "hourly",
      "rate": 1500,
      "kpi_bonus": null,
      "kpi_bonus_type": "fixed",
      "currency": "KZT",
      "history": [
        {
          "from": "2026-09-01",
          "pay_type": "hourly",
          "rate": 1500
        }
      ]
    },
    "vacation": {
      "per_year": 24,
      "accrued": 4.1,
      "adjust": 0,
      "used": 0,
      "planned": 0,
      "pending": 0,
      "balance": 4.1,
      "available": 4.1
    },
    "absences": [
      {
        "uuid": "2b3c4d5e-6f70-4a81-92b3-c4d5e6f7a8b9",
        "user": {
          "id": 311,
          "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
          "name": "Aigerim Sadykova"
        },
        "type": "vacation",
        "date_from": "2026-12-01",
        "date_to": "2026-12-14",
        "days": 14,
        "status": "approved",
        "paid": true,
        "comment": null,
        "decision_note": null,
        "decided_by": {
          "id": 120,
          "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
          "name": "Daniyar Omarov"
        },
        "decided_at": "2026-11-03T10:00:00+05:00",
        "has_file": false,
        "created_at": "2026-11-03T09:55:00+05:00"
      }
    ],
    "events": [
      {
        "id": 501,
        "type": "hire",
        "date": "2026-09-01",
        "data": {
          "position": "Barista"
        },
        "comment": null,
        "created_by": "Daniyar Omarov",
        "created_at": "2026-08-28T10:00:00+05:00"
      }
    ],
    "documents": [
      {
        "id": 88,
        "type": "contract",
        "title": "Employment contract",
        "number": "TD-2026/114",
        "issued_at": "2026-03-01",
        "expires_at": null,
        "note": null,
        "source": "hr",
        "file": {
          "name": "contract.pdf",
          "download_url": "https://app.jecheck.io/api/ext/v1/hr/employees/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b/documents/88/file"
        }
      }
    ],
    "checklists": [
      {
        "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
        "kind": "onboarding",
        "title": "Onboarding: Aigerim Sadykova",
        "start_date": "2026-11-04",
        "status": "active",
        "employee": {
          "id": 311,
          "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
          "name": "Aigerim Sadykova"
        },
        "sections": [
          {
            "key": "s1",
            "title": "Before the first day"
          }
        ],
        "progress": {
          "done": 3,
          "total": 9,
          "overdue": 1
        },
        "items": [
          {
            "id": 7001,
            "section_key": "s1",
            "title": "Prepare a uniform",
            "description": null,
            "assignee": {
              "id": 120,
              "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
              "name": "Daniyar Omarov"
            },
            "due_date": "2026-11-03",
            "overdue": true,
            "status": "open",
            "requires": "none",
            "required": true,
            "comment": null,
            "has_file": false,
            "done_by": null,
            "done_at": null,
            "task_uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
          }
        ],
        "created_at": "2026-10-30T12:00:00+05:00",
        "completed_at": null
      }
    ],
    "can": {
      "contacts": true,
      "edit": true,
      "card": true,
      "personal": true,
      "documents": true,
      "hire": true,
      "absences": true,
      "pay_view": true,
      "pay_edit": false
    }
  }
}

PATCHUpdate personal data

PATCH /hr/employees/{uuid}/profile

Partial update of the employee profile. Name and other fields require users.edit, phone — users.contacts, personal data (documents, addresses, tax id, bank, emergency contact, family, custom fields) — hr.personal, all on the employee's locations.

Token scopewrite
Permission users.view
MCP toolhr_employees_profile_update

Path parameters

uuid uuid Required
Employee UUID.

Request body

name string
First name (users.edit). Length 2–255.
lastname string
Last name (users.edit). Length 2–512.
phone string | null
Phone (users.contacts). Maximum length 64.
middle_name string | null
Maximum length 120.
work_phone string | null
Maximum length 64.
education string | null
Maximum length 500.
languages string | null
Maximum length 255.
clothing_size string | null
Maximum length 16.
shoe_size string | null
Maximum length 8.
note string | null
Maximum length 5000.
gender string | null
Personal data (hr.personal).
malefemale
birth_date date | null
Personal data (hr.personal).
birth_place string | null
Maximum length 255.
citizenship string | null
Maximum length 120.
marital_status string | null
singlemarrieddivorcedwidowed
children integer | null
Value 0–30.
personal_phone string | null
Maximum length 64.
personal_email string | null
Maximum length 255.
address_actual string | null
Maximum length 500.
address_registered string | null
Maximum length 500.
tax_id string | null
Maximum length 64.
insurance_no string | null
Maximum length 64.
id_doc_type string | null
id_cardpassportforeignresidence
id_doc_number string | null
Maximum length 64.
id_doc_issuer string | null
Maximum length 255.
id_doc_issued_at date | null
id_doc_expires_at date | null
emergency_name string | null
Maximum length 255.
emergency_relation string | null
Maximum length 64.
emergency_phone string | null
Maximum length 64.
bank_name string | null
Maximum length 255.
bank_account string | null
Maximum length 64.
custom object | null
Company custom fields: {key: value} (see hr.settings.get).

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks users.view, 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/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/profile' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Replace the broken fridge seal",
    "lastname": "string",
    "phone": "+77010000000",
    "middle_name": "string"
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/profile', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "Replace the broken fridge seal",
      "lastname": "string",
      "phone": "+77010000000",
      "middle_name": "string"
  }),
});
const { data } = await res.json();
import os, requests

res = requests.patch(
    "https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/profile",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"name":"Replace the broken fridge seal","lastname":"string","phone":"+77010000000","middle_name":"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', 'hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/profile', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'name' => 'Replace the broken fridge seal',
        'lastname' => 'string',
        'phone' => '+77010000000',
        'middle_name' => 'string',
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_employees_profile_update",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
            "name": "Replace the broken fridge seal",
            "lastname": "string",
            "phone": "+77010000000",
            "middle_name": "string"
        }
    }
}
Response 200
{
  "data": {
    "employee": {
      "id": 311,
      "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
      "name": "Aigerim",
      "lastname": "Sadykova",
      "email": "[email protected]",
      "phone": "+7 701 111 22 33",
      "is_admin": false,
      "deleted": false,
      "deleted_at": null,
      "web_access": false,
      "position": {
        "id": 7,
        "name": "Barista"
      },
      "locations": [
        {
          "id": 12,
          "name": "Abay Ave",
          "kind": "home"
        }
      ],
      "home_location_id": 12,
      "work_anywhere": false,
      "teams": [
        {
          "id": 3,
          "name": "Bar",
          "is_head": false
        }
      ],
      "created_at": "2026-03-01T09:00:00+05:00",
      "last_seen_at": "2026-11-03T08:12:00+05:00",
      "url": "https://app.jecheck.io/ui/users/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b"
    },
    "status": {
      "status": "probation",
      "until": "2026-12-01",
      "absence_type": null,
      "hired_at": "2026-09-01",
      "fired_at": null,
      "personnel_no": "0114",
      "onboarding": {
        "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
        "kind": "onboarding",
        "done": 3,
        "total": 9,
        "overdue": 1
      }
    },
    "profile": {
      "middle_name": "Nurlanovna",
      "gender": "female",
      "birth_date": "1998-04-12",
      "birth_place": null,
      "citizenship": null,
      "marital_status": null,
      "children": null,
      "work_phone": null,
      "personal_phone": "+7 701 000 00 00",
      "personal_email": null,
      "address_actual": null,
      "address_registered": null,
      "tax_id": null,
      "insurance_no": null,
      "id_doc_type": null,
      "id_doc_number": null,
      "id_doc_issuer": null,
      "id_doc_issued_at": null,
      "id_doc_expires_at": null,
      "emergency_name": null,
      "emergency_relation": null,
      "emergency_phone": null,
      "bank_name": null,
      "bank_account": null,
      "education": null,
      "languages": null,
      "clothing_size": null,
      "shoe_size": null,
      "note": null,
      "custom": {}
    },
    "work": {
      "hired_at": "2026-09-01",
      "fired_at": null,
      "personnel_no": "0114",
      "employment": "full",
      "probation_until": "2026-12-01",
      "contract_type": "permanent",
      "contract_number": "TD-2026/114",
      "contract_date": "2026-09-01",
      "contract_until": null,
      "vacation_days": null,
      "vacation_adjust": 0,
      "manager": {
        "id": 120,
        "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
        "name": "Daniyar Omarov"
      },
      "team_managers": [],
      "reports": []
    },
    "pay": {
      "pay_type": "hourly",
      "rate": 1500,
      "kpi_bonus": null,
      "kpi_bonus_type": "fixed",
      "currency": "KZT",
      "history": [
        {
          "from": "2026-09-01",
          "pay_type": "hourly",
          "rate": 1500
        }
      ]
    },
    "vacation": {
      "per_year": 24,
      "accrued": 4.1,
      "adjust": 0,
      "used": 0,
      "planned": 0,
      "pending": 0,
      "balance": 4.1,
      "available": 4.1
    },
    "absences": [
      {
        "uuid": "2b3c4d5e-6f70-4a81-92b3-c4d5e6f7a8b9",
        "user": {
          "id": 311,
          "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
          "name": "Aigerim Sadykova"
        },
        "type": "vacation",
        "date_from": "2026-12-01",
        "date_to": "2026-12-14",
        "days": 14,
        "status": "approved",
        "paid": true,
        "comment": null,
        "decision_note": null,
        "decided_by": {
          "id": 120,
          "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
          "name": "Daniyar Omarov"
        },
        "decided_at": "2026-11-03T10:00:00+05:00",
        "has_file": false,
        "created_at": "2026-11-03T09:55:00+05:00"
      }
    ],
    "events": [
      {
        "id": 501,
        "type": "hire",
        "date": "2026-09-01",
        "data": {
          "position": "Barista"
        },
        "comment": null,
        "created_by": "Daniyar Omarov",
        "created_at": "2026-08-28T10:00:00+05:00"
      }
    ],
    "documents": [
      {
        "id": 88,
        "type": "contract",
        "title": "Employment contract",
        "number": "TD-2026/114",
        "issued_at": "2026-03-01",
        "expires_at": null,
        "note": null,
        "source": "hr",
        "file": {
          "name": "contract.pdf",
          "download_url": "https://app.jecheck.io/api/ext/v1/hr/employees/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b/documents/88/file"
        }
      }
    ],
    "checklists": [
      {
        "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
        "kind": "onboarding",
        "title": "Onboarding: Aigerim Sadykova",
        "start_date": "2026-11-04",
        "status": "active",
        "employee": {
          "id": 311,
          "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
          "name": "Aigerim Sadykova"
        },
        "sections": [
          {
            "key": "s1",
            "title": "Before the first day"
          }
        ],
        "progress": {
          "done": 3,
          "total": 9,
          "overdue": 1
        },
        "items": [
          {
            "id": 7001,
            "section_key": "s1",
            "title": "Prepare a uniform",
            "description": null,
            "assignee": {
              "id": 120,
              "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
              "name": "Daniyar Omarov"
            },
            "due_date": "2026-11-03",
            "overdue": true,
            "status": "open",
            "requires": "none",
            "required": true,
            "comment": null,
            "has_file": false,
            "done_by": null,
            "done_at": null,
            "task_uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
          }
        ],
        "created_at": "2026-10-30T12:00:00+05:00",
        "completed_at": null
      }
    ],
    "can": {
      "contacts": true,
      "edit": true,
      "card": true,
      "personal": true,
      "documents": true,
      "hire": true,
      "absences": true,
      "pay_view": true,
      "pay_edit": false
    }
  }
}

PATCHUpdate work data

PATCH /hr/employees/{uuid}/work

Hire date, personnel number, employment type, probation, manager, contract, vacation entitlement (hr.hire) and pay (pay.rates.edit; a new rate with rate_from goes to the rate history used by payroll).

Token scopewrite
Permission hr.hire or pay.rates.edit
MCP toolhr_employees_work_update

Path parameters

uuid uuid Required
Employee UUID.

Request body

hired_at date | null
personnel_no string | null
Maximum length 32.
employment string | null
fullpartcontractintern
probation_until date | null
manager_id integer | null
Line manager (user id).
contract_type string | null
permanentfixedcivilself
contract_number string | null
Maximum length 64.
contract_date date | null
contract_until date | null
vacation_days integer | null
Personal annual vacation days (null — company default). Value 0–120.
vacation_adjust number | null
Manual vacation balance correction, days. Value -365–365.
pay_type string
hourlysalaryshift
rate number | null
Value 0–100000000.
rate_from date | null
Rate effective from.
kpi_bonus number | null
Value 0–100000000.
kpi_bonus_type string
fixedpercent

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.hire / pay.rates.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/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/work' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "hired_at": "2026-11-01",
    "personnel_no": "string",
    "employment": "full",
    "probation_until": "2026-11-01"
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/work', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "hired_at": "2026-11-01",
      "personnel_no": "string",
      "employment": "full",
      "probation_until": "2026-11-01"
  }),
});
const { data } = await res.json();
import os, requests

res = requests.patch(
    "https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/work",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"hired_at":"2026-11-01","personnel_no":"string","employment":"full","probation_until":"2026-11-01"},
)
res.raise_for_status()
data = res.json()["data"]
$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);

$res = $client->request('PATCH', 'hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/work', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'hired_at' => '2026-11-01',
        'personnel_no' => 'string',
        'employment' => 'full',
        'probation_until' => '2026-11-01',
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_employees_work_update",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
            "hired_at": "2026-11-01",
            "personnel_no": "string",
            "employment": "full",
            "probation_until": "2026-11-01"
        }
    }
}
Response 200
{
  "data": {
    "employee": {
      "id": 311,
      "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
      "name": "Aigerim",
      "lastname": "Sadykova",
      "email": "[email protected]",
      "phone": "+7 701 111 22 33",
      "is_admin": false,
      "deleted": false,
      "deleted_at": null,
      "web_access": false,
      "position": {
        "id": 7,
        "name": "Barista"
      },
      "locations": [
        {
          "id": 12,
          "name": "Abay Ave",
          "kind": "home"
        }
      ],
      "home_location_id": 12,
      "work_anywhere": false,
      "teams": [
        {
          "id": 3,
          "name": "Bar",
          "is_head": false
        }
      ],
      "created_at": "2026-03-01T09:00:00+05:00",
      "last_seen_at": "2026-11-03T08:12:00+05:00",
      "url": "https://app.jecheck.io/ui/users/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b"
    },
    "status": {
      "status": "probation",
      "until": "2026-12-01",
      "absence_type": null,
      "hired_at": "2026-09-01",
      "fired_at": null,
      "personnel_no": "0114",
      "onboarding": {
        "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
        "kind": "onboarding",
        "done": 3,
        "total": 9,
        "overdue": 1
      }
    },
    "profile": {
      "middle_name": "Nurlanovna",
      "gender": "female",
      "birth_date": "1998-04-12",
      "birth_place": null,
      "citizenship": null,
      "marital_status": null,
      "children": null,
      "work_phone": null,
      "personal_phone": "+7 701 000 00 00",
      "personal_email": null,
      "address_actual": null,
      "address_registered": null,
      "tax_id": null,
      "insurance_no": null,
      "id_doc_type": null,
      "id_doc_number": null,
      "id_doc_issuer": null,
      "id_doc_issued_at": null,
      "id_doc_expires_at": null,
      "emergency_name": null,
      "emergency_relation": null,
      "emergency_phone": null,
      "bank_name": null,
      "bank_account": null,
      "education": null,
      "languages": null,
      "clothing_size": null,
      "shoe_size": null,
      "note": null,
      "custom": {}
    },
    "work": {
      "hired_at": "2026-09-01",
      "fired_at": null,
      "personnel_no": "0114",
      "employment": "full",
      "probation_until": "2026-12-01",
      "contract_type": "permanent",
      "contract_number": "TD-2026/114",
      "contract_date": "2026-09-01",
      "contract_until": null,
      "vacation_days": null,
      "vacation_adjust": 0,
      "manager": {
        "id": 120,
        "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
        "name": "Daniyar Omarov"
      },
      "team_managers": [],
      "reports": []
    },
    "pay": {
      "pay_type": "hourly",
      "rate": 1500,
      "kpi_bonus": null,
      "kpi_bonus_type": "fixed",
      "currency": "KZT",
      "history": [
        {
          "from": "2026-09-01",
          "pay_type": "hourly",
          "rate": 1500
        }
      ]
    },
    "vacation": {
      "per_year": 24,
      "accrued": 4.1,
      "adjust": 0,
      "used": 0,
      "planned": 0,
      "pending": 0,
      "balance": 4.1,
      "available": 4.1
    },
    "absences": [
      {
        "uuid": "2b3c4d5e-6f70-4a81-92b3-c4d5e6f7a8b9",
        "user": {
          "id": 311,
          "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
          "name": "Aigerim Sadykova"
        },
        "type": "vacation",
        "date_from": "2026-12-01",
        "date_to": "2026-12-14",
        "days": 14,
        "status": "approved",
        "paid": true,
        "comment": null,
        "decision_note": null,
        "decided_by": {
          "id": 120,
          "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
          "name": "Daniyar Omarov"
        },
        "decided_at": "2026-11-03T10:00:00+05:00",
        "has_file": false,
        "created_at": "2026-11-03T09:55:00+05:00"
      }
    ],
    "events": [
      {
        "id": 501,
        "type": "hire",
        "date": "2026-09-01",
        "data": {
          "position": "Barista"
        },
        "comment": null,
        "created_by": "Daniyar Omarov",
        "created_at": "2026-08-28T10:00:00+05:00"
      }
    ],
    "documents": [
      {
        "id": 88,
        "type": "contract",
        "title": "Employment contract",
        "number": "TD-2026/114",
        "issued_at": "2026-03-01",
        "expires_at": null,
        "note": null,
        "source": "hr",
        "file": {
          "name": "contract.pdf",
          "download_url": "https://app.jecheck.io/api/ext/v1/hr/employees/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b/documents/88/file"
        }
      }
    ],
    "checklists": [
      {
        "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
        "kind": "onboarding",
        "title": "Onboarding: Aigerim Sadykova",
        "start_date": "2026-11-04",
        "status": "active",
        "employee": {
          "id": 311,
          "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
          "name": "Aigerim Sadykova"
        },
        "sections": [
          {
            "key": "s1",
            "title": "Before the first day"
          }
        ],
        "progress": {
          "done": 3,
          "total": 9,
          "overdue": 1
        },
        "items": [
          {
            "id": 7001,
            "section_key": "s1",
            "title": "Prepare a uniform",
            "description": null,
            "assignee": {
              "id": 120,
              "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
              "name": "Daniyar Omarov"
            },
            "due_date": "2026-11-03",
            "overdue": true,
            "status": "open",
            "requires": "none",
            "required": true,
            "comment": null,
            "has_file": false,
            "done_by": null,
            "done_at": null,
            "task_uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
          }
        ],
        "created_at": "2026-10-30T12:00:00+05:00",
        "completed_at": null
      }
    ],
    "can": {
      "contacts": true,
      "edit": true,
      "card": true,
      "personal": true,
      "documents": true,
      "hire": true,
      "absences": true,
      "pay_view": true,
      "pay_edit": false
    }
  }
}

POSTHire an employee

POST /hr/hire

Creates the employee account (or hires an existing user by uuid), sets position, locations, manager and work data, and starts an onboarding checklist (template_id; default — the template for the position, 0 — none). Requires hr.hire and, for a new account, users.create; with a location-scoped hr.hire only your locations can be chosen.

Token scopewrite
Permission hr.hire
MCP toolhr_hire

Request body

uuid uuid
Existing user of the company to hire (instead of creating a new account).
name string
First name (new account). Maximum length 255.
lastname string
Last name (new account). Maximum length 512.
email string
Login email (new account). Maximum length 255.
phone string | null
Maximum length 64.
middle_name string | null
Maximum length 120.
gender string | null
malefemale
birth_date date | null
personal_phone string | null
Maximum length 64.
position_id integer | null
home_location_id integer | null
Main location.
location_ids array<integer>
Additional locations.
work_anywhere boolean
Works at all locations (requires hr.hire for all locations).
team_id integer | null
manager_id integer | null
hired_at date Required
First working day.
probation_until date | null
employment string | null
fullpartcontractintern
personnel_no string | null
Maximum length 32.
contract_type string | null
permanentfixedcivilself
contract_number string | null
Maximum length 64.
contract_until date | null
web_access boolean
Access to the web cabinet (requires users.access).
role_ids array<integer>
Access roles for the new account (only roles you may assign).
invite string
Send the invitation now, on the first working day or never (default now).
nowstartnone
template_id integer | null
Onboarding checklist template; 0 — no checklist.
comment string | null
Maximum length 1000.

Responses

StatusDescription
201Created
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.hire, 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/hr/hire' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
    "name": "Replace the broken fridge seal",
    "lastname": "string",
    "email": "[email protected]",
    "hired_at": "2026-11-01"
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/hire', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
      "name": "Replace the broken fridge seal",
      "lastname": "string",
      "email": "[email protected]",
      "hired_at": "2026-11-01"
  }),
});
const { data } = await res.json();
import os, requests

res = requests.post(
    "https://app.jecheck.io/api/ext/v1/hr/hire",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"uuid":"3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b","name":"Replace the broken fridge seal","lastname":"string","email":"[email protected]","hired_at":"2026-11-01"},
)
res.raise_for_status()
data = res.json()["data"]
$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);

$res = $client->request('POST', 'hr/hire', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'uuid' => '3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b',
        'name' => 'Replace the broken fridge seal',
        'lastname' => 'string',
        'email' => '[email protected]',
        'hired_at' => '2026-11-01',
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_hire",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
            "name": "Replace the broken fridge seal",
            "lastname": "string",
            "email": "[email protected]",
            "hired_at": "2026-11-01"
        }
    }
}
Response 201
{
  "data": {
    "employee": {
      "id": 311,
      "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
      "name": "Aigerim",
      "lastname": "Sadykova",
      "email": "[email protected]",
      "phone": "+7 701 111 22 33",
      "is_admin": false,
      "deleted": false,
      "deleted_at": null,
      "web_access": false,
      "position": {
        "id": 7,
        "name": "Barista"
      },
      "locations": [
        {
          "id": 12,
          "name": "Abay Ave",
          "kind": "home"
        }
      ],
      "home_location_id": 12,
      "work_anywhere": false,
      "teams": [
        {
          "id": 3,
          "name": "Bar",
          "is_head": false
        }
      ],
      "created_at": "2026-03-01T09:00:00+05:00",
      "last_seen_at": "2026-11-03T08:12:00+05:00",
      "url": "https://app.jecheck.io/ui/users/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b"
    },
    "status": {
      "status": "probation",
      "until": "2026-12-01",
      "absence_type": null,
      "hired_at": "2026-09-01",
      "fired_at": null,
      "personnel_no": "0114",
      "onboarding": {
        "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
        "kind": "onboarding",
        "done": 3,
        "total": 9,
        "overdue": 1
      }
    },
    "profile": {
      "middle_name": "Nurlanovna",
      "gender": "female",
      "birth_date": "1998-04-12",
      "birth_place": null,
      "citizenship": null,
      "marital_status": null,
      "children": null,
      "work_phone": null,
      "personal_phone": "+7 701 000 00 00",
      "personal_email": null,
      "address_actual": null,
      "address_registered": null,
      "tax_id": null,
      "insurance_no": null,
      "id_doc_type": null,
      "id_doc_number": null,
      "id_doc_issuer": null,
      "id_doc_issued_at": null,
      "id_doc_expires_at": null,
      "emergency_name": null,
      "emergency_relation": null,
      "emergency_phone": null,
      "bank_name": null,
      "bank_account": null,
      "education": null,
      "languages": null,
      "clothing_size": null,
      "shoe_size": null,
      "note": null,
      "custom": {}
    },
    "work": {
      "hired_at": "2026-09-01",
      "fired_at": null,
      "personnel_no": "0114",
      "employment": "full",
      "probation_until": "2026-12-01",
      "contract_type": "permanent",
      "contract_number": "TD-2026/114",
      "contract_date": "2026-09-01",
      "contract_until": null,
      "vacation_days": null,
      "vacation_adjust": 0,
      "manager": {
        "id": 120,
        "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
        "name": "Daniyar Omarov"
      },
      "team_managers": [],
      "reports": []
    },
    "pay": {
      "pay_type": "hourly",
      "rate": 1500,
      "kpi_bonus": null,
      "kpi_bonus_type": "fixed",
      "currency": "KZT",
      "history": [
        {
          "from": "2026-09-01",
          "pay_type": "hourly",
          "rate": 1500
        }
      ]
    },
    "vacation": {
      "per_year": 24,
      "accrued": 4.1,
      "adjust": 0,
      "used": 0,
      "planned": 0,
      "pending": 0,
      "balance": 4.1,
      "available": 4.1
    },
    "absences": [
      {
        "uuid": "2b3c4d5e-6f70-4a81-92b3-c4d5e6f7a8b9",
        "user": {
          "id": 311,
          "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
          "name": "Aigerim Sadykova"
        },
        "type": "vacation",
        "date_from": "2026-12-01",
        "date_to": "2026-12-14",
        "days": 14,
        "status": "approved",
        "paid": true,
        "comment": null,
        "decision_note": null,
        "decided_by": {
          "id": 120,
          "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
          "name": "Daniyar Omarov"
        },
        "decided_at": "2026-11-03T10:00:00+05:00",
        "has_file": false,
        "created_at": "2026-11-03T09:55:00+05:00"
      }
    ],
    "events": [
      {
        "id": 501,
        "type": "hire",
        "date": "2026-09-01",
        "data": {
          "position": "Barista"
        },
        "comment": null,
        "created_by": "Daniyar Omarov",
        "created_at": "2026-08-28T10:00:00+05:00"
      }
    ],
    "documents": [
      {
        "id": 88,
        "type": "contract",
        "title": "Employment contract",
        "number": "TD-2026/114",
        "issued_at": "2026-03-01",
        "expires_at": null,
        "note": null,
        "source": "hr",
        "file": {
          "name": "contract.pdf",
          "download_url": "https://app.jecheck.io/api/ext/v1/hr/employees/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b/documents/88/file"
        }
      }
    ],
    "checklists": [
      {
        "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
        "kind": "onboarding",
        "title": "Onboarding: Aigerim Sadykova",
        "start_date": "2026-11-04",
        "status": "active",
        "employee": {
          "id": 311,
          "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
          "name": "Aigerim Sadykova"
        },
        "sections": [
          {
            "key": "s1",
            "title": "Before the first day"
          }
        ],
        "progress": {
          "done": 3,
          "total": 9,
          "overdue": 1
        },
        "items": [
          {
            "id": 7001,
            "section_key": "s1",
            "title": "Prepare a uniform",
            "description": null,
            "assignee": {
              "id": 120,
              "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
              "name": "Daniyar Omarov"
            },
            "due_date": "2026-11-03",
            "overdue": true,
            "status": "open",
            "requires": "none",
            "required": true,
            "comment": null,
            "has_file": false,
            "done_by": null,
            "done_at": null,
            "task_uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
          }
        ],
        "created_at": "2026-10-30T12:00:00+05:00",
        "completed_at": null
      }
    ],
    "can": {
      "contacts": true,
      "edit": true,
      "card": true,
      "personal": true,
      "documents": true,
      "hire": true,
      "absences": true,
      "pay_view": true,
      "pay_edit": false
    }
  }
}

POSTTransfer an employee

POST /hr/employees/{uuid}/transfer

Changes position, locations or manager; the change is recorded in the HR history with the before/after values.

Token scopewrite
Permission hr.hire
MCP toolhr_employees_transfer

Path parameters

uuid uuid Required
Employee UUID.

Request body

date date Required
Effective date.
position_id integer | null
home_location_id integer | null
location_ids array<integer>
work_anywhere boolean
manager_id integer | null
comment string | null
Maximum length 1000.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.hire, 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/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/transfer' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "date": "2026-11-01",
    "position_id": 42,
    "home_location_id": 12,
    "location_ids": [
        12,
        14
    ]
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/transfer', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "date": "2026-11-01",
      "position_id": 42,
      "home_location_id": 12,
      "location_ids": [
          12,
          14
      ]
  }),
});
const { data } = await res.json();
import os, requests

res = requests.post(
    "https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/transfer",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"date":"2026-11-01","position_id":42,"home_location_id":12,"location_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', 'hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/transfer', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'date' => '2026-11-01',
        'position_id' => 42,
        'home_location_id' => 12,
        'location_ids' => [
            12,
            14,
        ],
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_employees_transfer",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
            "date": "2026-11-01",
            "position_id": 42,
            "home_location_id": 12,
            "location_ids": [
                12,
                14
            ]
        }
    }
}
Response 200
{
  "data": {
    "employee": {
      "id": 311,
      "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
      "name": "Aigerim",
      "lastname": "Sadykova",
      "email": "[email protected]",
      "phone": "+7 701 111 22 33",
      "is_admin": false,
      "deleted": false,
      "deleted_at": null,
      "web_access": false,
      "position": {
        "id": 7,
        "name": "Barista"
      },
      "locations": [
        {
          "id": 12,
          "name": "Abay Ave",
          "kind": "home"
        }
      ],
      "home_location_id": 12,
      "work_anywhere": false,
      "teams": [
        {
          "id": 3,
          "name": "Bar",
          "is_head": false
        }
      ],
      "created_at": "2026-03-01T09:00:00+05:00",
      "last_seen_at": "2026-11-03T08:12:00+05:00",
      "url": "https://app.jecheck.io/ui/users/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b"
    },
    "status": {
      "status": "probation",
      "until": "2026-12-01",
      "absence_type": null,
      "hired_at": "2026-09-01",
      "fired_at": null,
      "personnel_no": "0114",
      "onboarding": {
        "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
        "kind": "onboarding",
        "done": 3,
        "total": 9,
        "overdue": 1
      }
    },
    "profile": {
      "middle_name": "Nurlanovna",
      "gender": "female",
      "birth_date": "1998-04-12",
      "birth_place": null,
      "citizenship": null,
      "marital_status": null,
      "children": null,
      "work_phone": null,
      "personal_phone": "+7 701 000 00 00",
      "personal_email": null,
      "address_actual": null,
      "address_registered": null,
      "tax_id": null,
      "insurance_no": null,
      "id_doc_type": null,
      "id_doc_number": null,
      "id_doc_issuer": null,
      "id_doc_issued_at": null,
      "id_doc_expires_at": null,
      "emergency_name": null,
      "emergency_relation": null,
      "emergency_phone": null,
      "bank_name": null,
      "bank_account": null,
      "education": null,
      "languages": null,
      "clothing_size": null,
      "shoe_size": null,
      "note": null,
      "custom": {}
    },
    "work": {
      "hired_at": "2026-09-01",
      "fired_at": null,
      "personnel_no": "0114",
      "employment": "full",
      "probation_until": "2026-12-01",
      "contract_type": "permanent",
      "contract_number": "TD-2026/114",
      "contract_date": "2026-09-01",
      "contract_until": null,
      "vacation_days": null,
      "vacation_adjust": 0,
      "manager": {
        "id": 120,
        "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
        "name": "Daniyar Omarov"
      },
      "team_managers": [],
      "reports": []
    },
    "pay": {
      "pay_type": "hourly",
      "rate": 1500,
      "kpi_bonus": null,
      "kpi_bonus_type": "fixed",
      "currency": "KZT",
      "history": [
        {
          "from": "2026-09-01",
          "pay_type": "hourly",
          "rate": 1500
        }
      ]
    },
    "vacation": {
      "per_year": 24,
      "accrued": 4.1,
      "adjust": 0,
      "used": 0,
      "planned": 0,
      "pending": 0,
      "balance": 4.1,
      "available": 4.1
    },
    "absences": [
      {
        "uuid": "2b3c4d5e-6f70-4a81-92b3-c4d5e6f7a8b9",
        "user": {
          "id": 311,
          "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
          "name": "Aigerim Sadykova"
        },
        "type": "vacation",
        "date_from": "2026-12-01",
        "date_to": "2026-12-14",
        "days": 14,
        "status": "approved",
        "paid": true,
        "comment": null,
        "decision_note": null,
        "decided_by": {
          "id": 120,
          "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
          "name": "Daniyar Omarov"
        },
        "decided_at": "2026-11-03T10:00:00+05:00",
        "has_file": false,
        "created_at": "2026-11-03T09:55:00+05:00"
      }
    ],
    "events": [
      {
        "id": 501,
        "type": "hire",
        "date": "2026-09-01",
        "data": {
          "position": "Barista"
        },
        "comment": null,
        "created_by": "Daniyar Omarov",
        "created_at": "2026-08-28T10:00:00+05:00"
      }
    ],
    "documents": [
      {
        "id": 88,
        "type": "contract",
        "title": "Employment contract",
        "number": "TD-2026/114",
        "issued_at": "2026-03-01",
        "expires_at": null,
        "note": null,
        "source": "hr",
        "file": {
          "name": "contract.pdf",
          "download_url": "https://app.jecheck.io/api/ext/v1/hr/employees/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b/documents/88/file"
        }
      }
    ],
    "checklists": [
      {
        "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
        "kind": "onboarding",
        "title": "Onboarding: Aigerim Sadykova",
        "start_date": "2026-11-04",
        "status": "active",
        "employee": {
          "id": 311,
          "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
          "name": "Aigerim Sadykova"
        },
        "sections": [
          {
            "key": "s1",
            "title": "Before the first day"
          }
        ],
        "progress": {
          "done": 3,
          "total": 9,
          "overdue": 1
        },
        "items": [
          {
            "id": 7001,
            "section_key": "s1",
            "title": "Prepare a uniform",
            "description": null,
            "assignee": {
              "id": 120,
              "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
              "name": "Daniyar Omarov"
            },
            "due_date": "2026-11-03",
            "overdue": true,
            "status": "open",
            "requires": "none",
            "required": true,
            "comment": null,
            "has_file": false,
            "done_by": null,
            "done_at": null,
            "task_uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
          }
        ],
        "created_at": "2026-10-30T12:00:00+05:00",
        "completed_at": null
      }
    ],
    "can": {
      "contacts": true,
      "edit": true,
      "card": true,
      "personal": true,
      "documents": true,
      "hire": true,
      "absences": true,
      "pay_view": true,
      "pay_edit": false
    }
  }
}

POSTDismiss an employee

POST /hr/employees/{uuid}/dismiss

Registers the dismissal with the last working day and reason, cancels future absences and the active onboarding, starts the offboarding checklist. The account is closed the day after the last day (or now with block_now).

Token scopewrite
Permission hr.hire
MCP toolhr_employees_dismiss

Path parameters

uuid uuid Required
Employee UUID.

Request body

last_day date Required
reason string Required
ownagreementcontract_endemployerprobationdisciplinerelocationother
comment string | null
Maximum length 1000.
rehire boolean
Can be hired again, default true.
template_id integer | null
Offboarding template; 0 — no checklist.
block_now boolean
Close the account immediately.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.hire, 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/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/dismiss' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "last_day": "2026-11-01",
    "reason": "own",
    "comment": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
    "rehire": true
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/dismiss', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "last_day": "2026-11-01",
      "reason": "own",
      "comment": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
      "rehire": true
  }),
});
const { data } = await res.json();
import os, requests

res = requests.post(
    "https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/dismiss",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"last_day":"2026-11-01","reason":"own","comment":"Seal on fridge #2 is torn, temperature rises to +9 °C.","rehire":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', 'hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/dismiss', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'last_day' => '2026-11-01',
        'reason' => 'own',
        'comment' => 'Seal on fridge #2 is torn, temperature rises to +9 °C.',
        'rehire' => true,
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_employees_dismiss",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
            "last_day": "2026-11-01",
            "reason": "own",
            "comment": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
            "rehire": true
        }
    }
}
Response 200
{
  "data": {
    "employee": {
      "id": 311,
      "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
      "name": "Aigerim",
      "lastname": "Sadykova",
      "email": "[email protected]",
      "phone": "+7 701 111 22 33",
      "is_admin": false,
      "deleted": false,
      "deleted_at": null,
      "web_access": false,
      "position": {
        "id": 7,
        "name": "Barista"
      },
      "locations": [
        {
          "id": 12,
          "name": "Abay Ave",
          "kind": "home"
        }
      ],
      "home_location_id": 12,
      "work_anywhere": false,
      "teams": [
        {
          "id": 3,
          "name": "Bar",
          "is_head": false
        }
      ],
      "created_at": "2026-03-01T09:00:00+05:00",
      "last_seen_at": "2026-11-03T08:12:00+05:00",
      "url": "https://app.jecheck.io/ui/users/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b"
    },
    "status": {
      "status": "probation",
      "until": "2026-12-01",
      "absence_type": null,
      "hired_at": "2026-09-01",
      "fired_at": null,
      "personnel_no": "0114",
      "onboarding": {
        "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
        "kind": "onboarding",
        "done": 3,
        "total": 9,
        "overdue": 1
      }
    },
    "profile": {
      "middle_name": "Nurlanovna",
      "gender": "female",
      "birth_date": "1998-04-12",
      "birth_place": null,
      "citizenship": null,
      "marital_status": null,
      "children": null,
      "work_phone": null,
      "personal_phone": "+7 701 000 00 00",
      "personal_email": null,
      "address_actual": null,
      "address_registered": null,
      "tax_id": null,
      "insurance_no": null,
      "id_doc_type": null,
      "id_doc_number": null,
      "id_doc_issuer": null,
      "id_doc_issued_at": null,
      "id_doc_expires_at": null,
      "emergency_name": null,
      "emergency_relation": null,
      "emergency_phone": null,
      "bank_name": null,
      "bank_account": null,
      "education": null,
      "languages": null,
      "clothing_size": null,
      "shoe_size": null,
      "note": null,
      "custom": {}
    },
    "work": {
      "hired_at": "2026-09-01",
      "fired_at": null,
      "personnel_no": "0114",
      "employment": "full",
      "probation_until": "2026-12-01",
      "contract_type": "permanent",
      "contract_number": "TD-2026/114",
      "contract_date": "2026-09-01",
      "contract_until": null,
      "vacation_days": null,
      "vacation_adjust": 0,
      "manager": {
        "id": 120,
        "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
        "name": "Daniyar Omarov"
      },
      "team_managers": [],
      "reports": []
    },
    "pay": {
      "pay_type": "hourly",
      "rate": 1500,
      "kpi_bonus": null,
      "kpi_bonus_type": "fixed",
      "currency": "KZT",
      "history": [
        {
          "from": "2026-09-01",
          "pay_type": "hourly",
          "rate": 1500
        }
      ]
    },
    "vacation": {
      "per_year": 24,
      "accrued": 4.1,
      "adjust": 0,
      "used": 0,
      "planned": 0,
      "pending": 0,
      "balance": 4.1,
      "available": 4.1
    },
    "absences": [
      {
        "uuid": "2b3c4d5e-6f70-4a81-92b3-c4d5e6f7a8b9",
        "user": {
          "id": 311,
          "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
          "name": "Aigerim Sadykova"
        },
        "type": "vacation",
        "date_from": "2026-12-01",
        "date_to": "2026-12-14",
        "days": 14,
        "status": "approved",
        "paid": true,
        "comment": null,
        "decision_note": null,
        "decided_by": {
          "id": 120,
          "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
          "name": "Daniyar Omarov"
        },
        "decided_at": "2026-11-03T10:00:00+05:00",
        "has_file": false,
        "created_at": "2026-11-03T09:55:00+05:00"
      }
    ],
    "events": [
      {
        "id": 501,
        "type": "hire",
        "date": "2026-09-01",
        "data": {
          "position": "Barista"
        },
        "comment": null,
        "created_by": "Daniyar Omarov",
        "created_at": "2026-08-28T10:00:00+05:00"
      }
    ],
    "documents": [
      {
        "id": 88,
        "type": "contract",
        "title": "Employment contract",
        "number": "TD-2026/114",
        "issued_at": "2026-03-01",
        "expires_at": null,
        "note": null,
        "source": "hr",
        "file": {
          "name": "contract.pdf",
          "download_url": "https://app.jecheck.io/api/ext/v1/hr/employees/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b/documents/88/file"
        }
      }
    ],
    "checklists": [
      {
        "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
        "kind": "onboarding",
        "title": "Onboarding: Aigerim Sadykova",
        "start_date": "2026-11-04",
        "status": "active",
        "employee": {
          "id": 311,
          "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
          "name": "Aigerim Sadykova"
        },
        "sections": [
          {
            "key": "s1",
            "title": "Before the first day"
          }
        ],
        "progress": {
          "done": 3,
          "total": 9,
          "overdue": 1
        },
        "items": [
          {
            "id": 7001,
            "section_key": "s1",
            "title": "Prepare a uniform",
            "description": null,
            "assignee": {
              "id": 120,
              "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
              "name": "Daniyar Omarov"
            },
            "due_date": "2026-11-03",
            "overdue": true,
            "status": "open",
            "requires": "none",
            "required": true,
            "comment": null,
            "has_file": false,
            "done_by": null,
            "done_at": null,
            "task_uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
          }
        ],
        "created_at": "2026-10-30T12:00:00+05:00",
        "completed_at": null
      }
    ],
    "can": {
      "contacts": true,
      "edit": true,
      "card": true,
      "personal": true,
      "documents": true,
      "hire": true,
      "absences": true,
      "pay_view": true,
      "pay_edit": false
    }
  }
}

POSTCancel a dismissal

POST /hr/employees/{uuid}/cancel-dismissal

The employee stays: dismissal dates and the offboarding checklist are removed, access is restored.

Token scopewrite
Permission hr.hire
MCP toolhr_employees_cancel_dismissal

Path parameters

uuid uuid Required
Employee UUID.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.hire, 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/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/cancel-dismissal' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/cancel-dismissal', {
  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/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/cancel-dismissal",
    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', 'hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/cancel-dismissal', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_employees_cancel_dismissal",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
        }
    }
}
Response 200
{
  "data": {
    "employee": {
      "id": 311,
      "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
      "name": "Aigerim",
      "lastname": "Sadykova",
      "email": "[email protected]",
      "phone": "+7 701 111 22 33",
      "is_admin": false,
      "deleted": false,
      "deleted_at": null,
      "web_access": false,
      "position": {
        "id": 7,
        "name": "Barista"
      },
      "locations": [
        {
          "id": 12,
          "name": "Abay Ave",
          "kind": "home"
        }
      ],
      "home_location_id": 12,
      "work_anywhere": false,
      "teams": [
        {
          "id": 3,
          "name": "Bar",
          "is_head": false
        }
      ],
      "created_at": "2026-03-01T09:00:00+05:00",
      "last_seen_at": "2026-11-03T08:12:00+05:00",
      "url": "https://app.jecheck.io/ui/users/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b"
    },
    "status": {
      "status": "probation",
      "until": "2026-12-01",
      "absence_type": null,
      "hired_at": "2026-09-01",
      "fired_at": null,
      "personnel_no": "0114",
      "onboarding": {
        "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
        "kind": "onboarding",
        "done": 3,
        "total": 9,
        "overdue": 1
      }
    },
    "profile": {
      "middle_name": "Nurlanovna",
      "gender": "female",
      "birth_date": "1998-04-12",
      "birth_place": null,
      "citizenship": null,
      "marital_status": null,
      "children": null,
      "work_phone": null,
      "personal_phone": "+7 701 000 00 00",
      "personal_email": null,
      "address_actual": null,
      "address_registered": null,
      "tax_id": null,
      "insurance_no": null,
      "id_doc_type": null,
      "id_doc_number": null,
      "id_doc_issuer": null,
      "id_doc_issued_at": null,
      "id_doc_expires_at": null,
      "emergency_name": null,
      "emergency_relation": null,
      "emergency_phone": null,
      "bank_name": null,
      "bank_account": null,
      "education": null,
      "languages": null,
      "clothing_size": null,
      "shoe_size": null,
      "note": null,
      "custom": {}
    },
    "work": {
      "hired_at": "2026-09-01",
      "fired_at": null,
      "personnel_no": "0114",
      "employment": "full",
      "probation_until": "2026-12-01",
      "contract_type": "permanent",
      "contract_number": "TD-2026/114",
      "contract_date": "2026-09-01",
      "contract_until": null,
      "vacation_days": null,
      "vacation_adjust": 0,
      "manager": {
        "id": 120,
        "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
        "name": "Daniyar Omarov"
      },
      "team_managers": [],
      "reports": []
    },
    "pay": {
      "pay_type": "hourly",
      "rate": 1500,
      "kpi_bonus": null,
      "kpi_bonus_type": "fixed",
      "currency": "KZT",
      "history": [
        {
          "from": "2026-09-01",
          "pay_type": "hourly",
          "rate": 1500
        }
      ]
    },
    "vacation": {
      "per_year": 24,
      "accrued": 4.1,
      "adjust": 0,
      "used": 0,
      "planned": 0,
      "pending": 0,
      "balance": 4.1,
      "available": 4.1
    },
    "absences": [
      {
        "uuid": "2b3c4d5e-6f70-4a81-92b3-c4d5e6f7a8b9",
        "user": {
          "id": 311,
          "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
          "name": "Aigerim Sadykova"
        },
        "type": "vacation",
        "date_from": "2026-12-01",
        "date_to": "2026-12-14",
        "days": 14,
        "status": "approved",
        "paid": true,
        "comment": null,
        "decision_note": null,
        "decided_by": {
          "id": 120,
          "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
          "name": "Daniyar Omarov"
        },
        "decided_at": "2026-11-03T10:00:00+05:00",
        "has_file": false,
        "created_at": "2026-11-03T09:55:00+05:00"
      }
    ],
    "events": [
      {
        "id": 501,
        "type": "hire",
        "date": "2026-09-01",
        "data": {
          "position": "Barista"
        },
        "comment": null,
        "created_by": "Daniyar Omarov",
        "created_at": "2026-08-28T10:00:00+05:00"
      }
    ],
    "documents": [
      {
        "id": 88,
        "type": "contract",
        "title": "Employment contract",
        "number": "TD-2026/114",
        "issued_at": "2026-03-01",
        "expires_at": null,
        "note": null,
        "source": "hr",
        "file": {
          "name": "contract.pdf",
          "download_url": "https://app.jecheck.io/api/ext/v1/hr/employees/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b/documents/88/file"
        }
      }
    ],
    "checklists": [
      {
        "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
        "kind": "onboarding",
        "title": "Onboarding: Aigerim Sadykova",
        "start_date": "2026-11-04",
        "status": "active",
        "employee": {
          "id": 311,
          "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
          "name": "Aigerim Sadykova"
        },
        "sections": [
          {
            "key": "s1",
            "title": "Before the first day"
          }
        ],
        "progress": {
          "done": 3,
          "total": 9,
          "overdue": 1
        },
        "items": [
          {
            "id": 7001,
            "section_key": "s1",
            "title": "Prepare a uniform",
            "description": null,
            "assignee": {
              "id": 120,
              "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
              "name": "Daniyar Omarov"
            },
            "due_date": "2026-11-03",
            "overdue": true,
            "status": "open",
            "requires": "none",
            "required": true,
            "comment": null,
            "has_file": false,
            "done_by": null,
            "done_at": null,
            "task_uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
          }
        ],
        "created_at": "2026-10-30T12:00:00+05:00",
        "completed_at": null
      }
    ],
    "can": {
      "contacts": true,
      "edit": true,
      "card": true,
      "personal": true,
      "documents": true,
      "hire": true,
      "absences": true,
      "pay_view": true,
      "pay_edit": false
    }
  }
}

POSTRehire a former employee

POST /hr/employees/{uuid}/rehire
Token scopewrite
Permission hr.hire
MCP toolhr_employees_rehire

Path parameters

uuid uuid Required
Employee UUID.

Request body

hired_at date Required
position_id integer | null
home_location_id integer | null
location_ids array<integer>
work_anywhere boolean
manager_id integer | null
template_id integer | null
comment string | null
Maximum length 1000.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.hire, 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/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/rehire' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "hired_at": "2026-11-01",
    "position_id": 42,
    "home_location_id": 12,
    "location_ids": [
        12,
        14
    ]
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/rehire', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "hired_at": "2026-11-01",
      "position_id": 42,
      "home_location_id": 12,
      "location_ids": [
          12,
          14
      ]
  }),
});
const { data } = await res.json();
import os, requests

res = requests.post(
    "https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/rehire",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"hired_at":"2026-11-01","position_id":42,"home_location_id":12,"location_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', 'hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/rehire', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'hired_at' => '2026-11-01',
        'position_id' => 42,
        'home_location_id' => 12,
        'location_ids' => [
            12,
            14,
        ],
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_employees_rehire",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
            "hired_at": "2026-11-01",
            "position_id": 42,
            "home_location_id": 12,
            "location_ids": [
                12,
                14
            ]
        }
    }
}
Response 200
{
  "data": {
    "employee": {
      "id": 311,
      "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
      "name": "Aigerim",
      "lastname": "Sadykova",
      "email": "[email protected]",
      "phone": "+7 701 111 22 33",
      "is_admin": false,
      "deleted": false,
      "deleted_at": null,
      "web_access": false,
      "position": {
        "id": 7,
        "name": "Barista"
      },
      "locations": [
        {
          "id": 12,
          "name": "Abay Ave",
          "kind": "home"
        }
      ],
      "home_location_id": 12,
      "work_anywhere": false,
      "teams": [
        {
          "id": 3,
          "name": "Bar",
          "is_head": false
        }
      ],
      "created_at": "2026-03-01T09:00:00+05:00",
      "last_seen_at": "2026-11-03T08:12:00+05:00",
      "url": "https://app.jecheck.io/ui/users/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b"
    },
    "status": {
      "status": "probation",
      "until": "2026-12-01",
      "absence_type": null,
      "hired_at": "2026-09-01",
      "fired_at": null,
      "personnel_no": "0114",
      "onboarding": {
        "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
        "kind": "onboarding",
        "done": 3,
        "total": 9,
        "overdue": 1
      }
    },
    "profile": {
      "middle_name": "Nurlanovna",
      "gender": "female",
      "birth_date": "1998-04-12",
      "birth_place": null,
      "citizenship": null,
      "marital_status": null,
      "children": null,
      "work_phone": null,
      "personal_phone": "+7 701 000 00 00",
      "personal_email": null,
      "address_actual": null,
      "address_registered": null,
      "tax_id": null,
      "insurance_no": null,
      "id_doc_type": null,
      "id_doc_number": null,
      "id_doc_issuer": null,
      "id_doc_issued_at": null,
      "id_doc_expires_at": null,
      "emergency_name": null,
      "emergency_relation": null,
      "emergency_phone": null,
      "bank_name": null,
      "bank_account": null,
      "education": null,
      "languages": null,
      "clothing_size": null,
      "shoe_size": null,
      "note": null,
      "custom": {}
    },
    "work": {
      "hired_at": "2026-09-01",
      "fired_at": null,
      "personnel_no": "0114",
      "employment": "full",
      "probation_until": "2026-12-01",
      "contract_type": "permanent",
      "contract_number": "TD-2026/114",
      "contract_date": "2026-09-01",
      "contract_until": null,
      "vacation_days": null,
      "vacation_adjust": 0,
      "manager": {
        "id": 120,
        "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
        "name": "Daniyar Omarov"
      },
      "team_managers": [],
      "reports": []
    },
    "pay": {
      "pay_type": "hourly",
      "rate": 1500,
      "kpi_bonus": null,
      "kpi_bonus_type": "fixed",
      "currency": "KZT",
      "history": [
        {
          "from": "2026-09-01",
          "pay_type": "hourly",
          "rate": 1500
        }
      ]
    },
    "vacation": {
      "per_year": 24,
      "accrued": 4.1,
      "adjust": 0,
      "used": 0,
      "planned": 0,
      "pending": 0,
      "balance": 4.1,
      "available": 4.1
    },
    "absences": [
      {
        "uuid": "2b3c4d5e-6f70-4a81-92b3-c4d5e6f7a8b9",
        "user": {
          "id": 311,
          "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
          "name": "Aigerim Sadykova"
        },
        "type": "vacation",
        "date_from": "2026-12-01",
        "date_to": "2026-12-14",
        "days": 14,
        "status": "approved",
        "paid": true,
        "comment": null,
        "decision_note": null,
        "decided_by": {
          "id": 120,
          "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
          "name": "Daniyar Omarov"
        },
        "decided_at": "2026-11-03T10:00:00+05:00",
        "has_file": false,
        "created_at": "2026-11-03T09:55:00+05:00"
      }
    ],
    "events": [
      {
        "id": 501,
        "type": "hire",
        "date": "2026-09-01",
        "data": {
          "position": "Barista"
        },
        "comment": null,
        "created_by": "Daniyar Omarov",
        "created_at": "2026-08-28T10:00:00+05:00"
      }
    ],
    "documents": [
      {
        "id": 88,
        "type": "contract",
        "title": "Employment contract",
        "number": "TD-2026/114",
        "issued_at": "2026-03-01",
        "expires_at": null,
        "note": null,
        "source": "hr",
        "file": {
          "name": "contract.pdf",
          "download_url": "https://app.jecheck.io/api/ext/v1/hr/employees/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b/documents/88/file"
        }
      }
    ],
    "checklists": [
      {
        "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
        "kind": "onboarding",
        "title": "Onboarding: Aigerim Sadykova",
        "start_date": "2026-11-04",
        "status": "active",
        "employee": {
          "id": 311,
          "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
          "name": "Aigerim Sadykova"
        },
        "sections": [
          {
            "key": "s1",
            "title": "Before the first day"
          }
        ],
        "progress": {
          "done": 3,
          "total": 9,
          "overdue": 1
        },
        "items": [
          {
            "id": 7001,
            "section_key": "s1",
            "title": "Prepare a uniform",
            "description": null,
            "assignee": {
              "id": 120,
              "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
              "name": "Daniyar Omarov"
            },
            "due_date": "2026-11-03",
            "overdue": true,
            "status": "open",
            "requires": "none",
            "required": true,
            "comment": null,
            "has_file": false,
            "done_by": null,
            "done_at": null,
            "task_uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
          }
        ],
        "created_at": "2026-10-30T12:00:00+05:00",
        "completed_at": null
      }
    ],
    "can": {
      "contacts": true,
      "edit": true,
      "card": true,
      "personal": true,
      "documents": true,
      "hire": true,
      "absences": true,
      "pay_view": true,
      "pay_edit": false
    }
  }
}

POSTStart a checklist for an employee

POST /hr/employees/{uuid}/checklists

Starts an onboarding or offboarding checklist from a template manually (tasks are created for the responsible people).

Token scopewrite
Permission hr.hire
MCP toolhr_employees_checklists_start

Path parameters

uuid uuid Required
Employee UUID.

Request body

template_id integer Required
date date Required
First working day / last day.

Responses

StatusDescription
201Created
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.hire, 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/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/checklists' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "template_id": 42,
    "date": "2026-11-01"
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/checklists', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "template_id": 42,
      "date": "2026-11-01"
  }),
});
const { data } = await res.json();
import os, requests

res = requests.post(
    "https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/checklists",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"template_id":42,"date":"2026-11-01"},
)
res.raise_for_status()
data = res.json()["data"]
$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);

$res = $client->request('POST', 'hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/checklists', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'template_id' => 42,
        'date' => '2026-11-01',
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_employees_checklists_start",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
            "template_id": 42,
            "date": "2026-11-01"
        }
    }
}
Response 201
{
  "data": {
    "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
    "kind": "onboarding",
    "title": "Onboarding: Aigerim Sadykova",
    "start_date": "2026-11-04",
    "status": "active",
    "employee": {
      "id": 311,
      "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
      "name": "Aigerim Sadykova"
    },
    "sections": [
      {
        "key": "s1",
        "title": "Before the first day"
      }
    ],
    "progress": {
      "done": 3,
      "total": 9,
      "overdue": 1
    },
    "items": [
      {
        "id": 7001,
        "section_key": "s1",
        "title": "Prepare a uniform",
        "description": null,
        "assignee": {
          "id": 120,
          "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
          "name": "Daniyar Omarov"
        },
        "due_date": "2026-11-03",
        "overdue": true,
        "status": "open",
        "requires": "none",
        "required": true,
        "comment": null,
        "has_file": false,
        "done_by": null,
        "done_at": null,
        "task_uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
      }
    ],
    "created_at": "2026-10-30T12:00:00+05:00",
    "completed_at": null
  }
}

POSTAdd a note to the HR history

POST /hr/employees/{uuid}/notes
Token scopewrite
Permission hr.hire
MCP toolhr_employees_notes_create

Path parameters

uuid uuid Required
Employee UUID.

Request body

date date Required
comment string Required
Length 1–1000.
title string | null
Maximum length 120.

Responses

StatusDescription
201Created
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.hire, 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/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/notes' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "date": "2026-11-01",
    "comment": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
    "title": "Replace the broken fridge seal"
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/notes', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "date": "2026-11-01",
      "comment": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
      "title": "Replace the broken fridge seal"
  }),
});
const { data } = await res.json();
import os, requests

res = requests.post(
    "https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/notes",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"date":"2026-11-01","comment":"Seal on fridge #2 is torn, temperature rises to +9 °C.","title":"Replace the broken fridge seal"},
)
res.raise_for_status()
data = res.json()["data"]
$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);

$res = $client->request('POST', 'hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/notes', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'date' => '2026-11-01',
        'comment' => 'Seal on fridge #2 is torn, temperature rises to +9 °C.',
        'title' => 'Replace the broken fridge seal',
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_employees_notes_create",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
            "date": "2026-11-01",
            "comment": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
            "title": "Replace the broken fridge seal"
        }
    }
}
Response 201
{
  "data": {
    "id": 502,
    "type": "note",
    "date": "2026-11-03",
    "data": {
      "title": "Warning"
    },
    "comment": "Late three times this month",
    "created_by": "Daniyar Omarov",
    "created_at": "2026-11-03T10:00:00+05:00"
  }
}

DELDelete a note from the HR history

DELETE /hr/employees/{uuid}/notes/{id}

Only notes can be deleted; hiring and dismissal are undone by their own operations.

Token scopewrite
Permission hr.hire
MCP toolhr_employees_notes_delete · destructive

Path parameters

uuid uuid Required
Employee UUID.
id integer Required
Event id.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.hire, 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/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/notes/42' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/notes/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/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/notes/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', 'hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/notes/42', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_employees_notes_delete",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
            "id": 42
        }
    }
}
Response 200
{
  "data": {
    "deleted": true
  }
}

GETList HR documents of an employee

GET /hr/employees/{uuid}/documents

Contracts, orders, IDs, certificates (plus medical books from HACCP, read-only). Each view is written to the access log.

Token scoperead
Permission hr.documents
MCP toolhr_documents_list · read-only

Path parameters

uuid uuid Required
Employee UUID.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.documents
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/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/documents' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/documents', {
  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/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/documents",
    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', 'hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/documents', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_documents_list",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
        }
    }
}
Response 200
{
  "data": [
    {
      "id": 88,
      "type": "contract",
      "title": "Employment contract",
      "number": "TD-2026/114",
      "issued_at": "2026-03-01",
      "expires_at": null,
      "note": null,
      "source": "hr",
      "file": {
        "name": "contract.pdf",
        "download_url": "https://app.jecheck.io/api/ext/v1/hr/employees/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b/documents/88/file"
      }
    }
  ]
}

POSTAdd an HR document

POST /hr/employees/{uuid}/documents
Token scopewrite
Permission hr.documents
MCP toolhr_documents_create
Content typemultipart/form-data application/json

Path parameters

uuid uuid Required
Employee UUID.

Request body

type string Required
contractaddendumorderidmedicalcertificatediplomandaconsentother
title string | null
Maximum length 255.
number string | null
Maximum length 120.
issued_at date | null
expires_at date | null
note string | null
Maximum length 500.
file file
Scan: PDF, image, Office or TXT, up to 20 MB.

Responses

StatusDescription
201Created
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.documents, 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/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/documents' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "contract",
    "title": "Replace the broken fridge seal",
    "number": "string",
    "issued_at": "2026-11-01"
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/documents', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "type": "contract",
      "title": "Replace the broken fridge seal",
      "number": "string",
      "issued_at": "2026-11-01"
  }),
});
const { data } = await res.json();
import os, requests

res = requests.post(
    "https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/documents",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"type":"contract","title":"Replace the broken fridge seal","number":"string","issued_at":"2026-11-01"},
)
res.raise_for_status()
data = res.json()["data"]
$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);

$res = $client->request('POST', 'hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/documents', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'type' => 'contract',
        'title' => 'Replace the broken fridge seal',
        'number' => 'string',
        'issued_at' => '2026-11-01',
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_documents_create",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
            "type": "contract",
            "title": "Replace the broken fridge seal",
            "number": "string",
            "issued_at": "2026-11-01"
        }
    }
}
Response 201
{
  "data": {
    "id": 88,
    "type": "contract",
    "title": "Employment contract",
    "number": "TD-2026/114",
    "issued_at": "2026-03-01",
    "expires_at": null,
    "note": null,
    "source": "hr",
    "file": {
      "name": "contract.pdf",
      "download_url": "https://app.jecheck.io/api/ext/v1/hr/employees/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b/documents/88/file"
    }
  }
}

PATCHUpdate an HR document

PATCH /hr/employees/{uuid}/documents/{id}
Token scopewrite
Permission hr.documents
MCP toolhr_documents_update
Content typemultipart/form-data application/json

Path parameters

uuid uuid Required
Employee UUID.
id integer Required
Document id.

Request body

type string
contractaddendumorderidmedicalcertificatediplomandaconsentother
title string | null
Maximum length 255.
number string | null
Maximum length 120.
issued_at date | null
expires_at date | null
note string | null
Maximum length 500.
file file
Replace the scan.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.documents, 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/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/documents/42' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "contract",
    "title": "Replace the broken fridge seal",
    "number": "string",
    "issued_at": "2026-11-01"
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/documents/42', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "type": "contract",
      "title": "Replace the broken fridge seal",
      "number": "string",
      "issued_at": "2026-11-01"
  }),
});
const { data } = await res.json();
import os, requests

res = requests.patch(
    "https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/documents/42",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"type":"contract","title":"Replace the broken fridge seal","number":"string","issued_at":"2026-11-01"},
)
res.raise_for_status()
data = res.json()["data"]
$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);

$res = $client->request('PATCH', 'hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/documents/42', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'type' => 'contract',
        'title' => 'Replace the broken fridge seal',
        'number' => 'string',
        'issued_at' => '2026-11-01',
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_documents_update",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
            "id": 42,
            "type": "contract",
            "title": "Replace the broken fridge seal",
            "number": "string",
            "issued_at": "2026-11-01"
        }
    }
}
Response 200
{
  "data": {
    "id": 88,
    "type": "contract",
    "title": "Employment contract",
    "number": "TD-2026/114",
    "issued_at": "2026-03-01",
    "expires_at": null,
    "note": null,
    "source": "hr",
    "file": {
      "name": "contract.pdf",
      "download_url": "https://app.jecheck.io/api/ext/v1/hr/employees/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b/documents/88/file"
    }
  }
}

DELDelete an HR document

DELETE /hr/employees/{uuid}/documents/{id}
Token scopewrite
Permission hr.documents
MCP toolhr_documents_delete · destructive

Path parameters

uuid uuid Required
Employee UUID.
id integer Required
Document id.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.documents, 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/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/documents/42' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/documents/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/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/documents/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', 'hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/documents/42', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_documents_delete",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
            "id": 42
        }
    }
}
Response 200
{
  "data": {
    "deleted": true
  }
}

GETDownload an HR document file

GET /hr/employees/{uuid}/documents/{id}/file

Returns the file itself (REST only, not available as an MCP tool). The download is written to the access log.

Token scoperead
Permission hr.documents
MCP toolNot available over MCP

Path parameters

uuid uuid Required
Employee UUID.
id integer Required
Document id.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.documents
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/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/documents/42/file' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/documents/42/file', {
  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/hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/documents/42/file",
    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', 'hr/employees/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/documents/42/file', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
Response 200
{
  "data": {
    "file": "binary"
  }
}

GETList absences

GET /hr/absences

Vacations, sick leave and other absences of employees of the locations of hr.absences (the same records as in the shift schedule). Overlapping the period when date_from/date_to are given.

Token scoperead
Permission hr.absences
MCP toolhr_absences_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.
date_from date
Period start.
date_to date
Period end.
status array<string>
pending, approved, rejected, cancelled (default — pending and approved).
type array<string>
Absence types: vacation, sick, day_off, unpaid, business_trip, study, maternity, truancy, other.
user_id integer
Only this employee.
location_ids array<integer>
Only employees of these locations.
updated_since date-time
Only records changed after this moment.

Responses

StatusDescription
200OK — a page of results with meta
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.absences
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/hr/absences?date_from=2026-11-01' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/absences?date_from=2026-11-01', {
  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/hr/absences",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    params={"date_from":"2026-11-01"},
)
res.raise_for_status()
data = res.json()["data"]
$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);

$res = $client->request('GET', 'hr/absences', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'query' => [
        'date_from' => '2026-11-01',
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_absences_list",
        "arguments": {
            "date_from": "2026-11-01"
        }
    }
}
Response 200
{
  "data": [
    {
      "uuid": "2b3c4d5e-6f70-4a81-92b3-c4d5e6f7a8b9",
      "user": {
        "id": 311,
        "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
        "name": "Aigerim Sadykova"
      },
      "type": "vacation",
      "date_from": "2026-12-01",
      "date_to": "2026-12-14",
      "days": 14,
      "status": "approved",
      "paid": true,
      "comment": null,
      "decision_note": null,
      "decided_by": {
        "id": 120,
        "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
        "name": "Daniyar Omarov"
      },
      "decided_at": "2026-11-03T10:00:00+05:00",
      "has_file": false,
      "created_at": "2026-11-03T09:55:00+05:00"
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 25,
    "total": 1,
    "has_more": false
  }
}

GETGet vacation balances

GET /hr/absences/balances

Annual vacation balance of each active employee of the locations of hr.absences: accrued since the hire date, used, planned, pending and available days.

Token scoperead
Permission hr.absences
MCP toolhr_absences_balances · 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.
location_ids array<integer>
Only employees of these locations.

Responses

StatusDescription
200OK — a page of results with meta
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.absences
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/hr/absences/balances' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/absences/balances', {
  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/hr/absences/balances",
    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', 'hr/absences/balances', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_absences_balances",
        "arguments": {}
    }
}
Response 200
{
  "data": [
    {
      "user": {
        "id": 311,
        "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
        "name": "Aigerim Sadykova"
      },
      "hired_at": "2026-03-01",
      "per_year": 24,
      "accrued": 16.4,
      "adjust": 0,
      "used": 7,
      "planned": 14,
      "pending": 0,
      "balance": 9.4,
      "available": -4.6
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 25,
    "total": 1,
    "has_more": false
  }
}

POSTAdd an absence

POST /hr/absences

Records a vacation, sick leave etc. for an employee — approved immediately (requires hr.absences and schedule.requests on the employee's locations). With release_shifts the employee's shifts on those days become open shifts.

Token scopewrite
Permission hr.absences
MCP toolhr_absences_create
Content typemultipart/form-data application/json

Request body

user_id integer Required
Employee.
type string Required
vacationsickday_offunpaidbusiness_tripstudymaternitytruancyother
date_from date Required
date_to date Required
paid boolean
Default — depends on the type.
comment string | null
Maximum length 1000.
release_shifts boolean
file file
Sick note or order: PDF or image up to 10 MB.

Responses

StatusDescription
201Created
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.absences, 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/hr/absences' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "user_id": 42,
    "type": "vacation",
    "date_from": "2026-11-01",
    "date_to": "2026-11-30"
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/absences', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "user_id": 42,
      "type": "vacation",
      "date_from": "2026-11-01",
      "date_to": "2026-11-30"
  }),
});
const { data } = await res.json();
import os, requests

res = requests.post(
    "https://app.jecheck.io/api/ext/v1/hr/absences",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"user_id":42,"type":"vacation","date_from":"2026-11-01","date_to":"2026-11-30"},
)
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', 'hr/absences', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'user_id' => 42,
        'type' => 'vacation',
        'date_from' => '2026-11-01',
        'date_to' => '2026-11-30',
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_absences_create",
        "arguments": {
            "user_id": 42,
            "type": "vacation",
            "date_from": "2026-11-01",
            "date_to": "2026-11-30"
        }
    }
}
Response 201
{
  "data": {
    "uuid": "2b3c4d5e-6f70-4a81-92b3-c4d5e6f7a8b9",
    "user": {
      "id": 311,
      "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
      "name": "Aigerim Sadykova"
    },
    "type": "vacation",
    "date_from": "2026-12-01",
    "date_to": "2026-12-14",
    "days": 14,
    "status": "approved",
    "paid": true,
    "comment": null,
    "decision_note": null,
    "decided_by": {
      "id": 120,
      "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
      "name": "Daniyar Omarov"
    },
    "decided_at": "2026-11-03T10:00:00+05:00",
    "has_file": false,
    "created_at": "2026-11-03T09:55:00+05:00"
  }
}

PATCHUpdate an absence

PATCH /hr/absences/{uuid}
Token scopewrite
Permission hr.absences
MCP toolhr_absences_update
Content typemultipart/form-data application/json

Path parameters

uuid uuid Required
Absence UUID.

Request body

type string
vacationsickday_offunpaidbusiness_tripstudymaternitytruancyother
date_from date
date_to date
paid boolean
comment string | null
Maximum length 1000.
release_shifts boolean
file file

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.absences, 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/hr/absences/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "vacation",
    "date_from": "2026-11-01",
    "date_to": "2026-11-30",
    "paid": true
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/absences/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "type": "vacation",
      "date_from": "2026-11-01",
      "date_to": "2026-11-30",
      "paid": true
  }),
});
const { data } = await res.json();
import os, requests

res = requests.patch(
    "https://app.jecheck.io/api/ext/v1/hr/absences/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"type":"vacation","date_from":"2026-11-01","date_to":"2026-11-30","paid":True},
)
res.raise_for_status()
data = res.json()["data"]
$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);

$res = $client->request('PATCH', 'hr/absences/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'type' => 'vacation',
        'date_from' => '2026-11-01',
        'date_to' => '2026-11-30',
        'paid' => true,
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_absences_update",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
            "type": "vacation",
            "date_from": "2026-11-01",
            "date_to": "2026-11-30",
            "paid": true
        }
    }
}
Response 200
{
  "data": {
    "uuid": "2b3c4d5e-6f70-4a81-92b3-c4d5e6f7a8b9",
    "user": {
      "id": 311,
      "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
      "name": "Aigerim Sadykova"
    },
    "type": "vacation",
    "date_from": "2026-12-01",
    "date_to": "2026-12-14",
    "days": 14,
    "status": "approved",
    "paid": true,
    "comment": null,
    "decision_note": null,
    "decided_by": {
      "id": 120,
      "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
      "name": "Daniyar Omarov"
    },
    "decided_at": "2026-11-03T10:00:00+05:00",
    "has_file": false,
    "created_at": "2026-11-03T09:55:00+05:00"
  }
}

POSTApprove or reject an absence request

POST /hr/absences/{uuid}/decide

Decision on a pending request submitted by an employee; the employee is notified.

Token scopewrite
Permission hr.absences
MCP toolhr_absences_decide

Path parameters

uuid uuid Required
Absence UUID.

Request body

approve boolean Required
note string | null
Maximum length 500.
release_shifts boolean
Open the employee's shifts on those days.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.absences, 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/hr/absences/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/decide' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "approve": true,
    "note": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
    "release_shifts": true
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/absences/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/decide', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "approve": true,
      "note": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
      "release_shifts": true
  }),
});
const { data } = await res.json();
import os, requests

res = requests.post(
    "https://app.jecheck.io/api/ext/v1/hr/absences/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/decide",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"approve":True,"note":"Seal on fridge #2 is torn, temperature rises to +9 °C.","release_shifts":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', 'hr/absences/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/decide', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'approve' => true,
        'note' => 'Seal on fridge #2 is torn, temperature rises to +9 °C.',
        'release_shifts' => true,
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_absences_decide",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
            "approve": true,
            "note": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
            "release_shifts": true
        }
    }
}
Response 200
{
  "data": {
    "uuid": "2b3c4d5e-6f70-4a81-92b3-c4d5e6f7a8b9",
    "user": {
      "id": 311,
      "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
      "name": "Aigerim Sadykova"
    },
    "type": "vacation",
    "date_from": "2026-12-01",
    "date_to": "2026-12-14",
    "days": 14,
    "status": "approved",
    "paid": true,
    "comment": null,
    "decision_note": null,
    "decided_by": {
      "id": 120,
      "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
      "name": "Daniyar Omarov"
    },
    "decided_at": "2026-11-03T10:00:00+05:00",
    "has_file": false,
    "created_at": "2026-11-03T09:55:00+05:00"
  }
}

POSTCancel an absence

POST /hr/absences/{uuid}/cancel
Token scopewrite
Permission hr.absences
MCP toolhr_absences_cancel

Path parameters

uuid uuid Required
Absence UUID.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.absences, 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/hr/absences/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/cancel' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/absences/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/cancel', {
  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/hr/absences/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/cancel",
    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', 'hr/absences/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/cancel', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_absences_cancel",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
        }
    }
}
Response 200
{
  "data": {
    "uuid": "2b3c4d5e-6f70-4a81-92b3-c4d5e6f7a8b9",
    "user": {
      "id": 311,
      "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
      "name": "Aigerim Sadykova"
    },
    "type": "vacation",
    "date_from": "2026-12-01",
    "date_to": "2026-12-14",
    "days": 14,
    "status": "approved",
    "paid": true,
    "comment": null,
    "decision_note": null,
    "decided_by": {
      "id": 120,
      "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
      "name": "Daniyar Omarov"
    },
    "decided_at": "2026-11-03T10:00:00+05:00",
    "has_file": false,
    "created_at": "2026-11-03T09:55:00+05:00"
  }
}

GETList onboarding and offboarding checklists

GET /hr/checklists

Active checklists and those finished in the last 90 days, for employees of the locations of hr.hire.

Token scoperead
Permission hr.hire
MCP toolhr_checklists_list · read-only

Query parameters

kind string
onboardingoffboarding
status string
activecompletedcancelled

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.hire
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/hr/checklists?kind=onboarding' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/checklists?kind=onboarding', {
  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/hr/checklists",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    params={"kind":"onboarding"},
)
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', 'hr/checklists', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'query' => [
        'kind' => 'onboarding',
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_checklists_list",
        "arguments": {
            "kind": "onboarding"
        }
    }
}
Response 200
{
  "data": [
    {
      "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
      "kind": "onboarding",
      "title": "Onboarding: Aigerim Sadykova",
      "start_date": "2026-11-04",
      "status": "active",
      "employee": {
        "id": 311,
        "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
        "name": "Aigerim Sadykova"
      },
      "sections": [
        {
          "key": "s1",
          "title": "Before the first day"
        }
      ],
      "progress": {
        "done": 3,
        "total": 9,
        "overdue": 1
      },
      "items": [
        {
          "id": 7001,
          "section_key": "s1",
          "title": "Prepare a uniform",
          "description": null,
          "assignee": {
            "id": 120,
            "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
            "name": "Daniyar Omarov"
          },
          "due_date": "2026-11-03",
          "overdue": true,
          "status": "open",
          "requires": "none",
          "required": true,
          "comment": null,
          "has_file": false,
          "done_by": null,
          "done_at": null,
          "task_uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
        }
      ],
      "created_at": "2026-10-30T12:00:00+05:00",
      "completed_at": null
    }
  ]
}

GETRetrieve a checklist

GET /hr/checklists/{uuid}
Token scoperead
Permission hr.hire
MCP toolhr_checklists_get · read-only

Path parameters

uuid uuid Required
Checklist UUID.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.hire
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/hr/checklists/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/checklists/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
  },
});
const { data } = await res.json();
import os, requests

res = requests.get(
    "https://app.jecheck.io/api/ext/v1/hr/checklists/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
)
res.raise_for_status()
data = res.json()["data"]
$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);

$res = $client->request('GET', 'hr/checklists/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": "hr_checklists_get",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
        }
    }
}
Response 200
{
  "data": {
    "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
    "kind": "onboarding",
    "title": "Onboarding: Aigerim Sadykova",
    "start_date": "2026-11-04",
    "status": "active",
    "employee": {
      "id": 311,
      "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
      "name": "Aigerim Sadykova"
    },
    "sections": [
      {
        "key": "s1",
        "title": "Before the first day"
      }
    ],
    "progress": {
      "done": 3,
      "total": 9,
      "overdue": 1
    },
    "items": [
      {
        "id": 7001,
        "section_key": "s1",
        "title": "Prepare a uniform",
        "description": null,
        "assignee": {
          "id": 120,
          "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
          "name": "Daniyar Omarov"
        },
        "due_date": "2026-11-03",
        "overdue": true,
        "status": "open",
        "requires": "none",
        "required": true,
        "comment": null,
        "has_file": false,
        "done_by": null,
        "done_at": null,
        "task_uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
      }
    ],
    "created_at": "2026-10-30T12:00:00+05:00",
    "completed_at": null
  }
}

POSTAdd a checklist item

POST /hr/checklists/{uuid}/items
Token scopewrite
Permission hr.hire
MCP toolhr_checklists_items_create

Path parameters

uuid uuid Required
Checklist UUID.

Request body

title string Required
Maximum length 255.
description string | null
Maximum length 2000.
assignee_id integer | null
due_date date | null
section_key string | null
Maximum length 16.
requires string
What is required to complete the item.
nonecommentfile
create_task boolean
Create a task for the assignee.

Responses

StatusDescription
201Created
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.hire, 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/hr/checklists/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/items' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "title": "Replace the broken fridge seal",
    "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
    "assignee_id": 42,
    "due_date": "2026-11-01"
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/checklists/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/items', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "title": "Replace the broken fridge seal",
      "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
      "assignee_id": 42,
      "due_date": "2026-11-01"
  }),
});
const { data } = await res.json();
import os, requests

res = requests.post(
    "https://app.jecheck.io/api/ext/v1/hr/checklists/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/items",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"title":"Replace the broken fridge seal","description":"Seal on fridge #2 is torn, temperature rises to +9 °C.","assignee_id":42,"due_date":"2026-11-01"},
)
res.raise_for_status()
data = res.json()["data"]
$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);

$res = $client->request('POST', 'hr/checklists/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/items', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'title' => 'Replace the broken fridge seal',
        'description' => 'Seal on fridge #2 is torn, temperature rises to +9 °C.',
        'assignee_id' => 42,
        'due_date' => '2026-11-01',
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_checklists_items_create",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
            "title": "Replace the broken fridge seal",
            "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
            "assignee_id": 42,
            "due_date": "2026-11-01"
        }
    }
}
Response 201
{
  "data": {
    "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
    "kind": "onboarding",
    "title": "Onboarding: Aigerim Sadykova",
    "start_date": "2026-11-04",
    "status": "active",
    "employee": {
      "id": 311,
      "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
      "name": "Aigerim Sadykova"
    },
    "sections": [
      {
        "key": "s1",
        "title": "Before the first day"
      }
    ],
    "progress": {
      "done": 3,
      "total": 9,
      "overdue": 1
    },
    "items": [
      {
        "id": 7001,
        "section_key": "s1",
        "title": "Prepare a uniform",
        "description": null,
        "assignee": {
          "id": 120,
          "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
          "name": "Daniyar Omarov"
        },
        "due_date": "2026-11-03",
        "overdue": true,
        "status": "open",
        "requires": "none",
        "required": true,
        "comment": null,
        "has_file": false,
        "done_by": null,
        "done_at": null,
        "task_uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
      }
    ],
    "created_at": "2026-10-30T12:00:00+05:00",
    "completed_at": null
  }
}

PATCHUpdate a checklist item

PATCH /hr/checklist-items/{id}
Token scopewrite
Permission hr.hire
MCP toolhr_checklists_items_update

Path parameters

id integer Required
Item id.

Request body

title string
Maximum length 255.
description string | null
Maximum length 2000.
assignee_id integer | null
due_date date | null
section_key string
Maximum length 16.
requires string
nonecommentfile

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.hire, 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/hr/checklist-items/42' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "title": "Replace the broken fridge seal",
    "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
    "assignee_id": 42,
    "due_date": "2026-11-01"
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/checklist-items/42', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "title": "Replace the broken fridge seal",
      "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
      "assignee_id": 42,
      "due_date": "2026-11-01"
  }),
});
const { data } = await res.json();
import os, requests

res = requests.patch(
    "https://app.jecheck.io/api/ext/v1/hr/checklist-items/42",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"title":"Replace the broken fridge seal","description":"Seal on fridge #2 is torn, temperature rises to +9 °C.","assignee_id":42,"due_date":"2026-11-01"},
)
res.raise_for_status()
data = res.json()["data"]
$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);

$res = $client->request('PATCH', 'hr/checklist-items/42', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'title' => 'Replace the broken fridge seal',
        'description' => 'Seal on fridge #2 is torn, temperature rises to +9 °C.',
        'assignee_id' => 42,
        'due_date' => '2026-11-01',
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_checklists_items_update",
        "arguments": {
            "id": 42,
            "title": "Replace the broken fridge seal",
            "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
            "assignee_id": 42,
            "due_date": "2026-11-01"
        }
    }
}
Response 200
{
  "data": {
    "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
    "kind": "onboarding",
    "title": "Onboarding: Aigerim Sadykova",
    "start_date": "2026-11-04",
    "status": "active",
    "employee": {
      "id": 311,
      "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
      "name": "Aigerim Sadykova"
    },
    "sections": [
      {
        "key": "s1",
        "title": "Before the first day"
      }
    ],
    "progress": {
      "done": 3,
      "total": 9,
      "overdue": 1
    },
    "items": [
      {
        "id": 7001,
        "section_key": "s1",
        "title": "Prepare a uniform",
        "description": null,
        "assignee": {
          "id": 120,
          "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
          "name": "Daniyar Omarov"
        },
        "due_date": "2026-11-03",
        "overdue": true,
        "status": "open",
        "requires": "none",
        "required": true,
        "comment": null,
        "has_file": false,
        "done_by": null,
        "done_at": null,
        "task_uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
      }
    ],
    "created_at": "2026-10-30T12:00:00+05:00",
    "completed_at": null
  }
}

POSTComplete, skip or reopen a checklist item

POST /hr/checklist-items/{id}/status
Token scopewrite
Permission hr.hire
MCP toolhr_checklists_items_status
Content typemultipart/form-data application/json

Path parameters

id integer Required
Item id.

Request body

action string Required
completeskipreopen
comment string | null
Maximum length 2000.
file file
Attachment when completing (if the item requires a file).

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.hire, 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/hr/checklist-items/42/status' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "action": "complete",
    "comment": "Seal on fridge #2 is torn, temperature rises to +9 °C."
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/checklist-items/42/status', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "action": "complete",
      "comment": "Seal on fridge #2 is torn, temperature rises to +9 °C."
  }),
});
const { data } = await res.json();
import os, requests

res = requests.post(
    "https://app.jecheck.io/api/ext/v1/hr/checklist-items/42/status",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"action":"complete","comment":"Seal on fridge #2 is torn, temperature rises to +9 °C."},
)
res.raise_for_status()
data = res.json()["data"]
$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);

$res = $client->request('POST', 'hr/checklist-items/42/status', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'action' => 'complete',
        'comment' => '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": "hr_checklists_items_status",
        "arguments": {
            "id": 42,
            "action": "complete",
            "comment": "Seal on fridge #2 is torn, temperature rises to +9 °C."
        }
    }
}
Response 200
{
  "data": {
    "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
    "kind": "onboarding",
    "title": "Onboarding: Aigerim Sadykova",
    "start_date": "2026-11-04",
    "status": "active",
    "employee": {
      "id": 311,
      "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
      "name": "Aigerim Sadykova"
    },
    "sections": [
      {
        "key": "s1",
        "title": "Before the first day"
      }
    ],
    "progress": {
      "done": 3,
      "total": 9,
      "overdue": 1
    },
    "items": [
      {
        "id": 7001,
        "section_key": "s1",
        "title": "Prepare a uniform",
        "description": null,
        "assignee": {
          "id": 120,
          "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
          "name": "Daniyar Omarov"
        },
        "due_date": "2026-11-03",
        "overdue": true,
        "status": "open",
        "requires": "none",
        "required": true,
        "comment": null,
        "has_file": false,
        "done_by": null,
        "done_at": null,
        "task_uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
      }
    ],
    "created_at": "2026-10-30T12:00:00+05:00",
    "completed_at": null
  }
}

DELDelete a checklist item

DELETE /hr/checklist-items/{id}
Token scopewrite
Permission hr.hire
MCP toolhr_checklists_items_delete · destructive

Path parameters

id integer Required
Item id.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.hire, 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/hr/checklist-items/42' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/checklist-items/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/hr/checklist-items/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', 'hr/checklist-items/42', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_checklists_items_delete",
        "arguments": {
            "id": 42
        }
    }
}
Response 200
{
  "data": {
    "deleted": true
  }
}

POSTCancel a checklist

POST /hr/checklists/{uuid}/cancel
Token scopewrite
Permission hr.hire
MCP toolhr_checklists_cancel

Path parameters

uuid uuid Required
Checklist UUID.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.hire, 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/hr/checklists/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/cancel' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/checklists/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/cancel', {
  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/hr/checklists/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/cancel",
    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', 'hr/checklists/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/cancel', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_checklists_cancel",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
        }
    }
}
Response 200
{
  "data": {
    "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
    "kind": "onboarding",
    "title": "Onboarding: Aigerim Sadykova",
    "start_date": "2026-11-04",
    "status": "active",
    "employee": {
      "id": 311,
      "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
      "name": "Aigerim Sadykova"
    },
    "sections": [
      {
        "key": "s1",
        "title": "Before the first day"
      }
    ],
    "progress": {
      "done": 3,
      "total": 9,
      "overdue": 1
    },
    "items": [
      {
        "id": 7001,
        "section_key": "s1",
        "title": "Prepare a uniform",
        "description": null,
        "assignee": {
          "id": 120,
          "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
          "name": "Daniyar Omarov"
        },
        "due_date": "2026-11-03",
        "overdue": true,
        "status": "open",
        "requires": "none",
        "required": true,
        "comment": null,
        "has_file": false,
        "done_by": null,
        "done_at": null,
        "task_uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
      }
    ],
    "created_at": "2026-10-30T12:00:00+05:00",
    "completed_at": null
  }
}

POSTMove the start date of a checklist

POST /hr/checklists/{uuid}/reschedule

Moves the first working day / last day; due dates of open items shift by the same number of days.

Token scopewrite
Permission hr.hire
MCP toolhr_checklists_reschedule

Path parameters

uuid uuid Required
Checklist UUID.

Request body

date date Required

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.hire, 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/hr/checklists/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/reschedule' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "date": "2026-11-01"
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/checklists/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/reschedule', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "date": "2026-11-01"
  }),
});
const { data } = await res.json();
import os, requests

res = requests.post(
    "https://app.jecheck.io/api/ext/v1/hr/checklists/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/reschedule",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"date":"2026-11-01"},
)
res.raise_for_status()
data = res.json()["data"]
$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);

$res = $client->request('POST', 'hr/checklists/3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b/reschedule', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'date' => '2026-11-01',
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_checklists_reschedule",
        "arguments": {
            "uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b",
            "date": "2026-11-01"
        }
    }
}
Response 200
{
  "data": {
    "uuid": "4d5e6f70-8192-4a3b-8c4d-5e6f708192a3",
    "kind": "onboarding",
    "title": "Onboarding: Aigerim Sadykova",
    "start_date": "2026-11-04",
    "status": "active",
    "employee": {
      "id": 311,
      "uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
      "name": "Aigerim Sadykova"
    },
    "sections": [
      {
        "key": "s1",
        "title": "Before the first day"
      }
    ],
    "progress": {
      "done": 3,
      "total": 9,
      "overdue": 1
    },
    "items": [
      {
        "id": 7001,
        "section_key": "s1",
        "title": "Prepare a uniform",
        "description": null,
        "assignee": {
          "id": 120,
          "uuid": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
          "name": "Daniyar Omarov"
        },
        "due_date": "2026-11-03",
        "overdue": true,
        "status": "open",
        "requires": "none",
        "required": true,
        "comment": null,
        "has_file": false,
        "done_by": null,
        "done_at": null,
        "task_uuid": "3f2b8c1e-7a4d-4e2f-9b1a-6c5d4e3f2a1b"
      }
    ],
    "created_at": "2026-10-30T12:00:00+05:00",
    "completed_at": null
  }
}

GETList checklist templates

GET /hr/templates
Token scoperead
Permission hr.hire or hr.onboarding
MCP toolhr_templates_list · read-only

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.hire / hr.onboarding
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl 'https://app.jecheck.io/api/ext/v1/hr/templates' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/templates', {
  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/hr/templates",
    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', 'hr/templates', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_templates_list",
        "arguments": {}
    }
}
Response 200
{
  "data": [
    {
      "id": 4,
      "kind": "onboarding",
      "name": "Barista onboarding",
      "description": null,
      "color": "#1f9d63",
      "position_ids": [
        7
      ],
      "is_default": true,
      "sections": [
        {
          "key": "s1",
          "title": "Before the first day"
        }
      ],
      "items": [],
      "items_count": 9,
      "used": 14
    }
  ]
}

GETRetrieve a checklist template

GET /hr/templates/{id}
Token scoperead
Permission hr.onboarding
MCP toolhr_templates_get · read-only

Path parameters

id integer Required
Template id.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.onboarding
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/hr/templates/42' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/templates/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/hr/templates/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', 'hr/templates/42', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_templates_get",
        "arguments": {
            "id": 42
        }
    }
}
Response 200
{
  "data": {
    "id": 4,
    "kind": "onboarding",
    "name": "Barista onboarding",
    "description": null,
    "color": "#1f9d63",
    "position_ids": [
      7
    ],
    "is_default": true,
    "sections": [
      {
        "key": "s1",
        "title": "Before the first day"
      }
    ],
    "items": [
      {
        "id": 31,
        "section_key": "s1",
        "title": "Prepare a uniform",
        "description": null,
        "assignee_type": "location_manager",
        "assignee_id": null,
        "due_offset": -1,
        "requires": "none",
        "required": true,
        "create_task": true,
        "position_ids": []
      }
    ],
    "items_count": 1,
    "used": 14
  }
}

POSTCreate a checklist template

POST /hr/templates

Sections are stages ("Before the first day", "First week"…); items reference a section by section_key. Assignee types: user (assignee_id — user id), position (assignee_id — position id), manager (line manager), location_manager, employee (the employee themselves), initiator (who starts the checklist); due_offset — days from the start date (negative — before).

Token scopewrite
Permission hr.onboarding
MCP toolhr_templates_create

Request body

name string Required
Maximum length 160.
kind string Required
onboardingoffboarding
description string | null
Maximum length 1000.
color string | null
Maximum length 9.
position_ids array<integer>
Used by default for these positions.
is_default boolean
Default template of its kind.
sections array<object> Required
Items 1–20.
key string Required
Maximum length 16.
title string Required
Maximum length 120.
items array<object>
Maximum items 200.
section_key string Required
Maximum length 16.
title string Required
Maximum length 255.
description string | null
Maximum length 2000.
assignee_type string
userpositionmanagerlocation_manageremployeeinitiator
assignee_id integer | null
due_offset integer
Value -365–365.
requires string
nonecommentfile
required boolean
create_task boolean
position_ids array<integer>

Responses

StatusDescription
201Created
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.onboarding, 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/hr/templates' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Replace the broken fridge seal",
    "kind": "onboarding",
    "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
    "color": "string",
    "sections": [
        {
            "key": "string",
            "title": "Replace the broken fridge seal"
        }
    ]
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/templates', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "Replace the broken fridge seal",
      "kind": "onboarding",
      "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
      "color": "string",
      "sections": [
          {
              "key": "string",
              "title": "Replace the broken fridge seal"
          }
      ]
  }),
});
const { data } = await res.json();
import os, requests

res = requests.post(
    "https://app.jecheck.io/api/ext/v1/hr/templates",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"name":"Replace the broken fridge seal","kind":"onboarding","description":"Seal on fridge #2 is torn, temperature rises to +9 °C.","color":"string","sections":[{"key":"string","title":"Replace the broken fridge seal"}]},
)
res.raise_for_status()
data = res.json()["data"]
$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);

$res = $client->request('POST', 'hr/templates', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'name' => 'Replace the broken fridge seal',
        'kind' => 'onboarding',
        'description' => 'Seal on fridge #2 is torn, temperature rises to +9 °C.',
        'color' => 'string',
        'sections' => [
            [
                'key' => 'string',
                'title' => 'Replace the broken fridge seal',
            ],
        ],
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_templates_create",
        "arguments": {
            "name": "Replace the broken fridge seal",
            "kind": "onboarding",
            "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
            "color": "string",
            "sections": [
                {
                    "key": "string",
                    "title": "Replace the broken fridge seal"
                }
            ]
        }
    }
}
Response 201
{
  "data": {
    "id": 4,
    "kind": "onboarding",
    "name": "Barista onboarding",
    "description": null,
    "color": "#1f9d63",
    "position_ids": [
      7
    ],
    "is_default": true,
    "sections": [
      {
        "key": "s1",
        "title": "Before the first day"
      }
    ],
    "items": [
      {
        "id": 31,
        "section_key": "s1",
        "title": "Prepare a uniform",
        "description": null,
        "assignee_type": "location_manager",
        "assignee_id": null,
        "due_offset": -1,
        "requires": "none",
        "required": true,
        "create_task": true,
        "position_ids": []
      }
    ],
    "items_count": 1,
    "used": 14
  }
}

PUTReplace a checklist template

PUT /hr/templates/{id}

Saves the whole template (sections and all items). Running checklists keep their own copy of items.

Token scopewrite
Permission hr.onboarding
MCP toolhr_templates_update

Path parameters

id integer Required
Template id.

Request body

name string Required
Maximum length 160.
kind string Required
onboardingoffboarding
description string | null
Maximum length 1000.
color string | null
Maximum length 9.
position_ids array<integer>
Used by default for these positions.
is_default boolean
Default template of its kind.
sections array<object> Required
Items 1–20.
key string Required
Maximum length 16.
title string Required
Maximum length 120.
items array<object>
Maximum items 200.
section_key string Required
Maximum length 16.
title string Required
Maximum length 255.
description string | null
Maximum length 2000.
assignee_type string
userpositionmanagerlocation_manageremployeeinitiator
assignee_id integer | null
due_offset integer
Value -365–365.
requires string
nonecommentfile
required boolean
create_task boolean
position_ids array<integer>

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.onboarding, 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/hr/templates/42' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Replace the broken fridge seal",
    "kind": "onboarding",
    "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
    "color": "string",
    "sections": [
        {
            "key": "string",
            "title": "Replace the broken fridge seal"
        }
    ]
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/templates/42', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "name": "Replace the broken fridge seal",
      "kind": "onboarding",
      "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
      "color": "string",
      "sections": [
          {
              "key": "string",
              "title": "Replace the broken fridge seal"
          }
      ]
  }),
});
const { data } = await res.json();
import os, requests

res = requests.put(
    "https://app.jecheck.io/api/ext/v1/hr/templates/42",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"name":"Replace the broken fridge seal","kind":"onboarding","description":"Seal on fridge #2 is torn, temperature rises to +9 °C.","color":"string","sections":[{"key":"string","title":"Replace the broken fridge seal"}]},
)
res.raise_for_status()
data = res.json()["data"]
$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);

$res = $client->request('PUT', 'hr/templates/42', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'name' => 'Replace the broken fridge seal',
        'kind' => 'onboarding',
        'description' => 'Seal on fridge #2 is torn, temperature rises to +9 °C.',
        'color' => 'string',
        'sections' => [
            [
                'key' => 'string',
                'title' => 'Replace the broken fridge seal',
            ],
        ],
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_templates_update",
        "arguments": {
            "id": 42,
            "name": "Replace the broken fridge seal",
            "kind": "onboarding",
            "description": "Seal on fridge #2 is torn, temperature rises to +9 °C.",
            "color": "string",
            "sections": [
                {
                    "key": "string",
                    "title": "Replace the broken fridge seal"
                }
            ]
        }
    }
}
Response 200
{
  "data": {
    "id": 4,
    "kind": "onboarding",
    "name": "Barista onboarding",
    "description": null,
    "color": "#1f9d63",
    "position_ids": [
      7
    ],
    "is_default": true,
    "sections": [
      {
        "key": "s1",
        "title": "Before the first day"
      }
    ],
    "items": [
      {
        "id": 31,
        "section_key": "s1",
        "title": "Prepare a uniform",
        "description": null,
        "assignee_type": "location_manager",
        "assignee_id": null,
        "due_offset": -1,
        "requires": "none",
        "required": true,
        "create_task": true,
        "position_ids": []
      }
    ],
    "items_count": 1,
    "used": 14
  }
}

POSTDuplicate a checklist template

POST /hr/templates/{id}/duplicate
Token scopewrite
Permission hr.onboarding
MCP toolhr_templates_duplicate

Path parameters

id integer Required
Template id.

Responses

StatusDescription
201Created
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.onboarding, 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/hr/templates/42/duplicate' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/templates/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/hr/templates/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', 'hr/templates/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": "hr_templates_duplicate",
        "arguments": {
            "id": 42
        }
    }
}
Response 201
{
  "data": {
    "id": 4,
    "kind": "onboarding",
    "name": "Barista onboarding",
    "description": null,
    "color": "#1f9d63",
    "position_ids": [
      7
    ],
    "is_default": true,
    "sections": [
      {
        "key": "s1",
        "title": "Before the first day"
      }
    ],
    "items": [
      {
        "id": 31,
        "section_key": "s1",
        "title": "Prepare a uniform",
        "description": null,
        "assignee_type": "location_manager",
        "assignee_id": null,
        "due_offset": -1,
        "requires": "none",
        "required": true,
        "create_task": true,
        "position_ids": []
      }
    ],
    "items_count": 1,
    "used": 14
  }
}

DELDelete a checklist template

DELETE /hr/templates/{id}
Token scopewrite
Permission hr.onboarding
MCP toolhr_templates_delete · destructive

Path parameters

id integer Required
Template id.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.onboarding, 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/hr/templates/42' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/templates/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/hr/templates/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', 'hr/templates/42', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_templates_delete",
        "arguments": {
            "id": 42
        }
    }
}
Response 200
{
  "data": {
    "deleted": true
  }
}

GETGet HR settings

GET /hr/settings

Company defaults: annual vacation days, probation months, closing the account on dismissal, custom profile fields.

Token scoperead
Permission hr.card or hr.onboarding
MCP toolhr_settings_get · read-only

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.card / hr.onboarding
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl 'https://app.jecheck.io/api/ext/v1/hr/settings' \
  -H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/settings', {
  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/hr/settings",
    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', 'hr/settings', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_settings_get",
        "arguments": {}
    }
}
Response 200
{
  "data": {
    "vacation_days": 24,
    "probation_months": 3,
    "block_on_dismissal": true,
    "custom_fields": [
      {
        "key": "locker",
        "label": "Locker no.",
        "type": "text",
        "options": []
      }
    ]
  }
}

PATCHUpdate HR settings

PATCH /hr/settings
Token scopewrite
Permission hr.onboarding
MCP toolhr_settings_update

Request body

vacation_days integer | null
Value 0–120.
probation_months integer | null
Value 0–12.
block_on_dismissal boolean
custom_fields array<object>
Replaces the custom field list. Maximum items 30.
key string
Maximum length 24.
label string Required
Maximum length 80.
type string Required
textdatenumberselect
options array<string>

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks hr.onboarding, is read-only
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/hr/settings' \
  -H 'Authorization: Bearer $JECHECK_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "vacation_days": 42,
    "probation_months": 42,
    "block_on_dismissal": true,
    "custom_fields": [
        {
            "key": "string",
            "label": "string",
            "type": "text"
        }
    ]
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/hr/settings', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "vacation_days": 42,
      "probation_months": 42,
      "block_on_dismissal": true,
      "custom_fields": [
          {
              "key": "string",
              "label": "string",
              "type": "text"
          }
      ]
  }),
});
const { data } = await res.json();
import os, requests

res = requests.patch(
    "https://app.jecheck.io/api/ext/v1/hr/settings",
    headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
    json={"vacation_days":42,"probation_months":42,"block_on_dismissal":True,"custom_fields":[{"key":"string","label":"string","type":"text"}]},
)
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', 'hr/settings', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
    'json' => [
        'vacation_days' => 42,
        'probation_months' => 42,
        'block_on_dismissal' => true,
        'custom_fields' => [
            [
                'key' => 'string',
                'label' => 'string',
                'type' => 'text',
            ],
        ],
    ],
]);
$data = json_decode($res->getBody(), true)['data'];
{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "hr_settings_update",
        "arguments": {
            "vacation_days": 42,
            "probation_months": 42,
            "block_on_dismissal": true,
            "custom_fields": [
                {
                    "key": "string",
                    "label": "string",
                    "type": "text"
                }
            ]
        }
    }
}
Response 200
{
  "data": {
    "vacation_days": 24,
    "probation_months": 3,
    "block_on_dismissal": true,
    "custom_fields": []
  }
}