Employees
Employees of the company: list with filters, employee cards, adding and editing employees, deactivation, passwords and invitations, the positions directory. Visibility follows users.view (employees of the locations where it applies); email and phone are returned only with users.contacts.
GET List employees
GET /users
Employees visible to the token (users.view: employees of the locations where the permission applies; employees without a location are visible only with the permission for all locations). Active employees by default; use status for deleted ones. email and phone are null without users.contacts for that employee.
Token scope read
Permission
users.view
MCP tool users_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.
status
string
Employment status.
Default active.
activedeletedall
location_ids
array<integer>
Only employees attached to these locations (primary or additional).
position_id
integer
Only employees with this position.
team_id
integer
Only members of this team.
is_admin
boolean
Only administrators (true) or only non-administrators (false).
search
string
Search in first name, last name and email.
Maximum length 200.
updated_since
date-time
Only employees changed after this moment — use for incremental sync.
sort
string
Default name.
namecreated_descupdated_desc
Responses
Status Description
200 OK — a page of results with meta
401 unauthorized — Missing, invalid, revoked or expired token
403 forbidden · insufficient_scope · plan_required — Token lacks users.view
422 validation_failed — Invalid parameters — see error.fields
429 rate_limited — Too many requests — retry after Retry-After seconds
Request
cURL
Node.js
Python
PHP
MCP
Copy
curl 'https://app.jecheck.io/api/ext/v1/users?status=active' \
-H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/users?status=active', {
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/users",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
params={"status":"active"},
)
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', 'users', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'query' => [
'status' => 'active',
],
]);
$data = json_decode($res->getBody(), true)['data'];
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "users_list",
"arguments": {
"status": "active"
}
}
}
{
"data": [
{
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"first_name": "Aigerim",
"last_name": "Sadykova",
"name": "Aigerim Sadykova",
"email": "[email protected] ",
"phone": "+77011234567",
"position": {
"id": 5,
"name": "Barista"
},
"status": "active",
"is_admin": false,
"is_owner": false,
"web_access": true,
"works_anywhere": false,
"locations": [
{
"id": 12,
"name": "Abay Ave",
"kind": "home",
"is_manager": false
}
],
"teams": [
{
"id": 4,
"name": "Kitchen",
"is_head": false
}
],
"locale": "ru",
"last_activity_at": "2026-11-03T09:40:00+05:00",
"created_at": "2025-02-11T10:00:00+05:00",
"updated_at": "2026-10-28T16:12:00+05:00",
"deleted_at": null,
"url": "https://app.jecheck.io/ui/users/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b"
}
],
"meta": {
"page": 1,
"per_page": 25,
"total": 1,
"has_more": false
}
}
GET Retrieve an employee
GET /users/{id}
Employee card: position, locations (primary/additional, manager flag), teams, administrator and web-cabinet flags, last activity, and what the token may do with this employee (can).
Token scope read
Permission
users.view
MCP tool users_get · read-only
Path parameters
id
integer
Required
Employee id.
Responses
Status Description
200 OK
401 unauthorized — Missing, invalid, revoked or expired token
403 forbidden · insufficient_scope · plan_required — Token lacks users.view
404 not_found — The record does not exist or is not visible to the token
422 validation_failed — Invalid parameters — see error.fields
429 rate_limited — Too many requests — retry after Retry-After seconds
Request
cURL
Node.js
Python
PHP
MCP
Copy
curl 'https://app.jecheck.io/api/ext/v1/users/42' \
-H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/users/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/users/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', 'users/42', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "users_get",
"arguments": {
"id": 42
}
}
}
{
"data": {
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"first_name": "Aigerim",
"last_name": "Sadykova",
"name": "Aigerim Sadykova",
"email": "[email protected] ",
"phone": "+77011234567",
"position": {
"id": 5,
"name": "Barista"
},
"status": "active",
"is_admin": false,
"is_owner": false,
"web_access": true,
"works_anywhere": false,
"locations": [
{
"id": 12,
"name": "Abay Ave",
"kind": "home",
"is_manager": false
}
],
"teams": [
{
"id": 4,
"name": "Kitchen",
"is_head": false
}
],
"locale": "ru",
"last_activity_at": "2026-11-03T09:40:00+05:00",
"created_at": "2025-02-11T10:00:00+05:00",
"updated_at": "2026-10-28T16:12:00+05:00",
"deleted_at": null,
"url": "https://app.jecheck.io/ui/users/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"can": {
"edit": true,
"see_contacts": true,
"manage_login": true,
"deactivate": true
}
}
}
POST Create an employee
POST /users
Adds an employee with access to the mobile app and the web cabinet. An invitation with a generated password is emailed to the employee. Email is the login and must be unique across jeCheck. Attach the employee to locations with locations_staff_set; administrator rights and app-only access are set with access_users_account_update.
Token scope write
Permission
users.create
MCP tool users_create
Request body
first_name
string
Required
First name.
Length 2–255.
last_name
string
Required
Last name.
Length 2–255.
email
string
Required
Email — the login.
Maximum length 255.
position_id
integer | null
Position id (see GET /users/positions).
Responses
Status Description
201 Created
401 unauthorized — Missing, invalid, revoked or expired token
403 forbidden · insufficient_scope · plan_required — Token lacks users.create, is read-only
422 validation_failed — Invalid parameters — see error.fields
429 rate_limited — Too many requests — retry after Retry-After seconds
Request
cURL
Node.js
Python
PHP
MCP
Copy
curl -X POST 'https://app.jecheck.io/api/ext/v1/users' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"first_name": "string",
"last_name": "string",
"email": "[email protected] ",
"position_id": 42
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/users', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"first_name": "string",
"last_name": "string",
"email": "[email protected] ",
"position_id": 42
}),
});
const { data } = await res.json();
import os, requests
res = requests.post(
"https://app.jecheck.io/api/ext/v1/users",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"first_name":"string","last_name":"string","email":"[email protected] ","position_id":42},
)
res.raise_for_status()
data = res.json()["data"]
$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('POST', 'users', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'first_name' => 'string',
'last_name' => 'string',
'email' => '[email protected] ',
'position_id' => 42,
],
]);
$data = json_decode($res->getBody(), true)['data'];
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "users_create",
"arguments": {
"first_name": "string",
"last_name": "string",
"email": "[email protected] ",
"position_id": 42
}
}
}
{
"data": {
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"first_name": "Aigerim",
"last_name": "Sadykova",
"name": "Aigerim Sadykova",
"email": "[email protected] ",
"phone": "+77011234567",
"position": {
"id": 5,
"name": "Barista"
},
"status": "active",
"is_admin": false,
"is_owner": false,
"web_access": true,
"works_anywhere": false,
"locations": [
{
"id": 12,
"name": "Abay Ave",
"kind": "home",
"is_manager": false
}
],
"teams": [
{
"id": 4,
"name": "Kitchen",
"is_head": false
}
],
"locale": "ru",
"last_activity_at": "2026-11-03T09:40:00+05:00",
"created_at": "2025-02-11T10:00:00+05:00",
"updated_at": "2026-10-28T16:12:00+05:00",
"deleted_at": null,
"url": "https://app.jecheck.io/ui/users/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"can": {
"edit": true,
"see_contacts": true,
"manage_login": true,
"deactivate": true
}
}
}
PATCH Update an employee
PATCH /users/{id}
Partial update of name, position and email. Changing the email (login) additionally requires users.access and users.contacts for the employee; the employee is notified at the new address. Only an administrator can change the login of an administrator.
Token scope write
Permission
users.edit
MCP tool users_update
Path parameters
id
integer
Required
Employee id.
Request body
first_name
string
First name.
Length 2–255.
last_name
string
Last name.
Length 2–255.
email
string
New email (login).
Maximum length 255.
position_id
integer | null
Position id; null clears the position.
Responses
Status Description
200 OK
401 unauthorized — Missing, invalid, revoked or expired token
403 forbidden · insufficient_scope · plan_required — Token lacks users.edit, is read-only
404 not_found — The record does not exist or is not visible to the token
422 validation_failed — Invalid parameters — see error.fields
429 rate_limited — Too many requests — retry after Retry-After seconds
Request
cURL
Node.js
Python
PHP
MCP
Copy
curl -X PATCH 'https://app.jecheck.io/api/ext/v1/users/42' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"first_name": "string",
"last_name": "string",
"email": "[email protected] ",
"position_id": 42
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/users/42', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"first_name": "string",
"last_name": "string",
"email": "[email protected] ",
"position_id": 42
}),
});
const { data } = await res.json();
import os, requests
res = requests.patch(
"https://app.jecheck.io/api/ext/v1/users/42",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"first_name":"string","last_name":"string","email":"[email protected] ","position_id":42},
)
res.raise_for_status()
data = res.json()["data"]
$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('PATCH', 'users/42', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'first_name' => 'string',
'last_name' => 'string',
'email' => '[email protected] ',
'position_id' => 42,
],
]);
$data = json_decode($res->getBody(), true)['data'];
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "users_update",
"arguments": {
"id": 42,
"first_name": "string",
"last_name": "string",
"email": "[email protected] ",
"position_id": 42
}
}
}
{
"data": {
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"first_name": "Aigerim",
"last_name": "Sadykova",
"name": "Aigerim Sadykova",
"email": "[email protected] ",
"phone": "+77011234567",
"position": {
"id": 5,
"name": "Barista"
},
"status": "active",
"is_admin": false,
"is_owner": false,
"web_access": true,
"works_anywhere": false,
"locations": [
{
"id": 12,
"name": "Abay Ave",
"kind": "home",
"is_manager": false
}
],
"teams": [
{
"id": 4,
"name": "Kitchen",
"is_head": false
}
],
"locale": "ru",
"last_activity_at": "2026-11-03T09:40:00+05:00",
"created_at": "2025-02-11T10:00:00+05:00",
"updated_at": "2026-10-28T16:12:00+05:00",
"deleted_at": null,
"url": "https://app.jecheck.io/ui/users/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"can": {
"edit": true,
"see_contacts": true,
"manage_login": true,
"deactivate": true
}
}
}
POST Deactivate an employee
POST /users/{id}/deactivate
Deletes the employee the same way as the web app: sign-in to the app and the cabinet is blocked immediately, mobile tokens are revoked, history stays. You cannot deactivate yourself or the company owner; only an administrator can deactivate an administrator.
Token scope write
Permission
users.delete
MCP tool users_deactivate · destructive
Path parameters
id
integer
Required
Employee id.
Responses
Status Description
200 OK
401 unauthorized — Missing, invalid, revoked or expired token
403 forbidden · insufficient_scope · plan_required — Token lacks users.delete, is read-only
404 not_found — The record does not exist or is not visible to the token
409 conflict — The employee is the acting user or the company owner, or is already deactivated
422 validation_failed — Invalid parameters — see error.fields
429 rate_limited — Too many requests — retry after Retry-After seconds
Request
cURL
Node.js
Python
PHP
MCP
Copy
curl -X POST 'https://app.jecheck.io/api/ext/v1/users/42/deactivate' \
-H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/users/42/deactivate', {
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/users/42/deactivate",
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', 'users/42/deactivate', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "users_deactivate",
"arguments": {
"id": 42
}
}
}
{
"data": {
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"first_name": "Aigerim",
"last_name": "Sadykova",
"name": "Aigerim Sadykova",
"email": "[email protected] ",
"phone": "+77011234567",
"position": {
"id": 5,
"name": "Barista"
},
"status": "deleted",
"is_admin": false,
"is_owner": false,
"web_access": true,
"works_anywhere": false,
"locations": [
{
"id": 12,
"name": "Abay Ave",
"kind": "home",
"is_manager": false
}
],
"teams": [
{
"id": 4,
"name": "Kitchen",
"is_head": false
}
],
"locale": "ru",
"last_activity_at": "2026-11-03T09:40:00+05:00",
"created_at": "2025-02-11T10:00:00+05:00",
"updated_at": "2026-10-28T16:12:00+05:00",
"deleted_at": "2026-11-03T12:00:00+05:00",
"url": "https://app.jecheck.io/ui/users/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"can": {
"edit": true,
"see_contacts": true,
"manage_login": true,
"deactivate": true
}
}
}
POST Restore a deactivated employee
POST /users/{id}/restore
Token scope write
Permission
users.delete
MCP tool users_restore
Path parameters
id
integer
Required
Employee id.
Responses
Status Description
200 OK
401 unauthorized — Missing, invalid, revoked or expired token
403 forbidden · insufficient_scope · plan_required — Token lacks users.delete, is read-only
404 not_found — The record does not exist or is not visible to the token
422 validation_failed — Invalid parameters — see error.fields
429 rate_limited — Too many requests — retry after Retry-After seconds
Request
cURL
Node.js
Python
PHP
MCP
Copy
curl -X POST 'https://app.jecheck.io/api/ext/v1/users/42/restore' \
-H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/users/42/restore', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
},
});
const { data } = await res.json();
import os, requests
res = requests.post(
"https://app.jecheck.io/api/ext/v1/users/42/restore",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
)
res.raise_for_status()
data = res.json()["data"]
$client = new GuzzleHttp\Client(['base_uri' => 'https://app.jecheck.io/api/ext/v1/']);
$res = $client->request('POST', 'users/42/restore', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "users_restore",
"arguments": {
"id": 42
}
}
}
{
"data": {
"id": 311,
"uuid": "1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"first_name": "Aigerim",
"last_name": "Sadykova",
"name": "Aigerim Sadykova",
"email": "[email protected] ",
"phone": "+77011234567",
"position": {
"id": 5,
"name": "Barista"
},
"status": "active",
"is_admin": false,
"is_owner": false,
"web_access": true,
"works_anywhere": false,
"locations": [
{
"id": 12,
"name": "Abay Ave",
"kind": "home",
"is_manager": false
}
],
"teams": [
{
"id": 4,
"name": "Kitchen",
"is_head": false
}
],
"locale": "ru",
"last_activity_at": "2026-11-03T09:40:00+05:00",
"created_at": "2025-02-11T10:00:00+05:00",
"updated_at": "2026-10-28T16:12:00+05:00",
"deleted_at": null,
"url": "https://app.jecheck.io/ui/users/1e2d3c4b-5a69-4788-9a0b-1c2d3e4f5a6b",
"can": {
"edit": true,
"see_contacts": true,
"manage_login": true,
"deactivate": true
}
}
}
POST Reset password by email
POST /users/{id}/reset-password
Generates a new password and emails it to the employee. Existing mobile sessions are signed out.
Token scope write
Permission
users.access
MCP tool users_reset_password
Path parameters
id
integer
Required
Employee id.
Responses
Status Description
200 OK
401 unauthorized — Missing, invalid, revoked or expired token
403 forbidden · insufficient_scope · plan_required — Token lacks users.access, is read-only
404 not_found — The record does not exist or is not visible to the token
422 validation_failed — Invalid parameters — see error.fields
429 rate_limited — Too many requests — retry after Retry-After seconds
Request
cURL
Node.js
Python
PHP
MCP
Copy
curl -X POST 'https://app.jecheck.io/api/ext/v1/users/42/reset-password' \
-H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/users/42/reset-password', {
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/users/42/reset-password",
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', 'users/42/reset-password', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "users_reset_password",
"arguments": {
"id": 42
}
}
}
POST Issue a temporary password
POST /users/{id}/temporary-password
For an employee without access to email: returns a one-time password to hand over in person. It is not emailed or stored in clear text; the employee must set their own password at the first sign-in. Written to the access log.
Token scope write
Permission
users.access
MCP tool users_temporary_password
Path parameters
id
integer
Required
Employee id.
Responses
Status Description
200 OK
401 unauthorized — Missing, invalid, revoked or expired token
403 forbidden · insufficient_scope · plan_required — Token lacks users.access, is read-only
404 not_found — The record does not exist or is not visible to the token
422 validation_failed — Invalid parameters — see error.fields
429 rate_limited — Too many requests — retry after Retry-After seconds
Request
cURL
Node.js
Python
PHP
MCP
Copy
curl -X POST 'https://app.jecheck.io/api/ext/v1/users/42/temporary-password' \
-H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/users/42/temporary-password', {
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/users/42/temporary-password",
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', 'users/42/temporary-password', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "users_temporary_password",
"arguments": {
"id": 42
}
}
}
{
"data": {
"password": "Kq7m-Xr4t",
"must_change": true
}
}
POST Resend the invitation
POST /users/{id}/invite
Emails the invitation again with a sign-in link and a new password (the old password stops working).
Token scope write
Permission
users.access
MCP tool users_invite
Path parameters
id
integer
Required
Employee id.
Responses
Status Description
200 OK
401 unauthorized — Missing, invalid, revoked or expired token
403 forbidden · insufficient_scope · plan_required — Token lacks users.access, is read-only
404 not_found — The record does not exist or is not visible to the token
422 validation_failed — Invalid parameters — see error.fields
429 rate_limited — Too many requests — retry after Retry-After seconds
Request
cURL
Node.js
Python
PHP
MCP
Copy
curl -X POST 'https://app.jecheck.io/api/ext/v1/users/42/invite' \
-H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/users/42/invite', {
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/users/42/invite",
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', 'users/42/invite', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "users_invite",
"arguments": {
"id": 42
}
}
}
GET List positions
GET /users/positions
The positions directory with the number of active employees in each. Positions are used to route corrective tasks, assign tests, instructions and HACCP logs.
Token scope read
Permission
users.view or users.positions
MCP tool users_positions_list · read-only
Responses
Status Description
200 OK
401 unauthorized — Missing, invalid, revoked or expired token
403 forbidden · insufficient_scope · plan_required — Token lacks users.view / users.positions
429 rate_limited — Too many requests — retry after Retry-After seconds
Request
cURL
Node.js
Python
PHP
MCP
Copy
curl 'https://app.jecheck.io/api/ext/v1/users/positions' \
-H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/users/positions', {
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/users/positions",
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', 'users/positions', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "users_positions_list",
"arguments": {}
}
}
{
"data": [
{
"id": 5,
"name": "Barista",
"employees_count": 23
}
]
}
POST Create a position
POST /users/positions
Token scope write
Permission
users.positions
MCP tool users_positions_create
Request body
name
string
Required
Position name.
Length 1–120.
Responses
Status Description
201 Created
401 unauthorized — Missing, invalid, revoked or expired token
403 forbidden · insufficient_scope · plan_required — Token lacks users.positions, is read-only
422 validation_failed — Invalid parameters — see error.fields
429 rate_limited — Too many requests — retry after Retry-After seconds
Request
cURL
Node.js
Python
PHP
MCP
Copy
curl -X POST 'https://app.jecheck.io/api/ext/v1/users/positions' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"name": "Replace the broken fridge seal"
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/users/positions', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Replace the broken fridge seal"
}),
});
const { data } = await res.json();
import os, requests
res = requests.post(
"https://app.jecheck.io/api/ext/v1/users/positions",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"name":"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', 'users/positions', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'name' => 'Replace the broken fridge seal',
],
]);
$data = json_decode($res->getBody(), true)['data'];
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "users_positions_create",
"arguments": {
"name": "Replace the broken fridge seal"
}
}
}
{
"data": {
"id": 6,
"name": "Shift lead",
"employees_count": 0
}
}
PATCH Rename a position
PATCH /users/positions/{id}
Token scope write
Permission
users.positions
MCP tool users_positions_update
Path parameters
id
integer
Required
Position id.
Request body
name
string
Required
New name.
Length 1–120.
Responses
Status Description
200 OK
401 unauthorized — Missing, invalid, revoked or expired token
403 forbidden · insufficient_scope · plan_required — Token lacks users.positions, is read-only
404 not_found — The record does not exist or is not visible to the token
422 validation_failed — Invalid parameters — see error.fields
429 rate_limited — Too many requests — retry after Retry-After seconds
Request
cURL
Node.js
Python
PHP
MCP
Copy
curl -X PATCH 'https://app.jecheck.io/api/ext/v1/users/positions/42' \
-H 'Authorization: Bearer $JECHECK_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"name": "Replace the broken fridge seal"
}'
const res = await fetch('https://app.jecheck.io/api/ext/v1/users/positions/42', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.JECHECK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Replace the broken fridge seal"
}),
});
const { data } = await res.json();
import os, requests
res = requests.patch(
"https://app.jecheck.io/api/ext/v1/users/positions/42",
headers={"Authorization": f"Bearer {os.environ['JECHECK_TOKEN']}"},
json={"name":"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('PATCH', 'users/positions/42', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
'json' => [
'name' => 'Replace the broken fridge seal',
],
]);
$data = json_decode($res->getBody(), true)['data'];
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "users_positions_update",
"arguments": {
"id": 42,
"name": "Replace the broken fridge seal"
}
}
}
{
"data": {
"id": 6,
"name": "Shift supervisor",
"employees_count": 3
}
}
DEL Delete a position
DELETE /users/positions/{id}
Employees with this position are left without a position.
Token scope write
Permission
users.positions
MCP tool users_positions_delete · destructive
Path parameters
id
integer
Required
Position id.
Responses
Status Description
200 OK
401 unauthorized — Missing, invalid, revoked or expired token
403 forbidden · insufficient_scope · plan_required — Token lacks users.positions, is read-only
404 not_found — The record does not exist or is not visible to the token
422 validation_failed — Invalid parameters — see error.fields
429 rate_limited — Too many requests — retry after Retry-After seconds
Request
cURL
Node.js
Python
PHP
MCP
Copy
curl -X DELETE 'https://app.jecheck.io/api/ext/v1/users/positions/42' \
-H 'Authorization: Bearer $JECHECK_TOKEN'
const res = await fetch('https://app.jecheck.io/api/ext/v1/users/positions/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/users/positions/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', 'users/positions/42', [
'headers' => ['Authorization' => 'Bearer ' . getenv('JECHECK_TOKEN')],
]);
$data = json_decode($res->getBody(), true)['data'];
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "users_positions_delete",
"arguments": {
"id": 42
}
}
}
{
"data": {
"deleted": true
}
}