jeCheckDevelopers
Get an API key

GETList 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 scoperead
Permission users.view
MCP toolusers_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

StatusDescription
200OK — a page of results with meta
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks users.view
422validation_failed — Invalid parameters — see error.fields
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl 'https://app.jecheck.io/api/ext/v1/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"
        }
    }
}
Response 200
{
  "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
  }
}

GETRetrieve 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 scoperead
Permission users.view
MCP toolusers_get · read-only

Path parameters

id integer Required
Employee id.

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/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
        }
    }
}
Response 200
{
  "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
    }
  }
}

POSTCreate 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 scopewrite
Permission users.create
MCP toolusers_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

StatusDescription
201Created
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks users.create, 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/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
        }
    }
}
Response 201
{
  "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
    }
  }
}

PATCHUpdate 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 scopewrite
Permission users.edit
MCP toolusers_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

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks users.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/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
        }
    }
}
Response 200
{
  "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
    }
  }
}

POSTDeactivate 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 scopewrite
Permission users.delete
MCP toolusers_deactivate · destructive

Path parameters

id integer Required
Employee id.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks users.delete, is read-only
404not_found — The record does not exist or is not visible to the token
409conflict — The employee is the acting user or the company owner, or is already deactivated
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/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
        }
    }
}
Response 200
{
  "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
    }
  }
}

POSTRestore a deactivated employee

POST /users/{id}/restore
Token scopewrite
Permission users.delete
MCP toolusers_restore

Path parameters

id integer Required
Employee id.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks users.delete, is read-only
404not_found — The record does not exist or is not visible to the token
422validation_failed — Invalid parameters — see error.fields
429rate_limited — Too many requests — retry after Retry-After seconds
Request
curl -X POST 'https://app.jecheck.io/api/ext/v1/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
        }
    }
}
Response 200
{
  "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
    }
  }
}

POSTReset 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 scopewrite
Permission users.access
MCP toolusers_reset_password

Path parameters

id integer Required
Employee id.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks users.access, 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/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
        }
    }
}
Response 200
{
  "data": {
    "sent_to": "[email protected]"
  }
}

POSTIssue 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 scopewrite
Permission users.access
MCP toolusers_temporary_password

Path parameters

id integer Required
Employee id.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks users.access, 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/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
        }
    }
}
Response 200
{
  "data": {
    "password": "Kq7m-Xr4t",
    "must_change": true
  }
}

POSTResend 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 scopewrite
Permission users.access
MCP toolusers_invite

Path parameters

id integer Required
Employee id.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks users.access, 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/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
        }
    }
}
Response 200
{
  "data": {
    "sent_to": "[email protected]"
  }
}

GETList 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 scoperead
Permission users.view or users.positions
MCP toolusers_positions_list · read-only

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks users.view / users.positions
429rate_limited — Too many requests — retry after Retry-After seconds
Request
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": {}
    }
}
Response 200
{
  "data": [
    {
      "id": 5,
      "name": "Barista",
      "employees_count": 23
    }
  ]
}

POSTCreate a position

POST /users/positions
Token scopewrite
Permission users.positions
MCP toolusers_positions_create

Request body

name string Required
Position name. Length 1–120.

Responses

StatusDescription
201Created
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks users.positions, 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/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"
        }
    }
}
Response 201
{
  "data": {
    "id": 6,
    "name": "Shift lead",
    "employees_count": 0
  }
}

PATCHRename a position

PATCH /users/positions/{id}
Token scopewrite
Permission users.positions
MCP toolusers_positions_update

Path parameters

id integer Required
Position id.

Request body

name string Required
New name. Length 1–120.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks users.positions, 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/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"
        }
    }
}
Response 200
{
  "data": {
    "id": 6,
    "name": "Shift supervisor",
    "employees_count": 3
  }
}

DELDelete a position

DELETE /users/positions/{id}

Employees with this position are left without a position.

Token scopewrite
Permission users.positions
MCP toolusers_positions_delete · destructive

Path parameters

id integer Required
Position id.

Responses

StatusDescription
200OK
401unauthorized — Missing, invalid, revoked or expired token
403forbidden · insufficient_scope · plan_required — Token lacks users.positions, 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/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
        }
    }
}
Response 200
{
  "data": {
    "deleted": true
  }
}