Request headers
string
required
The service user’s API token in the
Bearer YOUR_TOKEN format. The school owner issues the token in the admin panel:
Manage → School → For developers → API keys — see the “Authentication” section for details.integer
required
The numeric ID of the seller — the account the school belongs to. Copy it on the API keys page, in
the Integration data → Identifiers card. The token’s permissions are checked against this ID.
integer
required
The numeric ID of the school, found in the same place as
Seller-Id. The value must match the seller’s school — otherwise
a 400 error with cause: "ForbiddenSchoolMismatch" is returned.An employment (
employment) links a school user to a department and, optionally, a position.
An employee can have several employment records in their history, but only one active record for
a given department + position pair. You can omit the position — the employee is then listed in the
department without a position, and an active record of this kind is unique per department + user pair.
The record also stores the employment terms: kind (kind), type (type) and rate (rate).Besides a position, an employment can be given a grade (
gradeId) — a level
of the school’s career ladder. A grade is available when grades are enabled in the school, otherwise
StaffGradesDisabled is returned. If the position has a limited list of grades, only a grade from that list
can be assigned (StaffGradeNotForPosition). If the position is linked to departments,
it can be assigned only in one of them (StaffPositionNotInDepartment); a position without links is common to
the whole school and available in any department.Transfer (
transfer) and promotion (promote) do not modify the current record; they close it (finishAt, status
Terminated) and create a new active record in the target department or with the new position. The employment
terms (kind, type, rate) and the external identifier extId are carried over to the new record unchanged.
The response contains the new employment record — with a new id. Therefore, store the employment’s
extId in your system, not its id: the id changes with every transfer and promotion, the extId does not. A department
manager assignment moves to the new record automatically; previously created absences remain
linked to the closed record.An employment can have an external identifier
extId — the record’s ID in the client’s system (for example, an HR system).
From 1 to 50 characters, without / or whitespace. It is unique within the school among open (not finished)
employments: on transfer or promotion the extId moves to the new active record (the closed one keeps a
copy), and after termination it is released — you can pass it again when rehiring. Separate routes
ext/{extId}/transfer, ext/{extId}/promote and ext/{extId}/terminate work by extId; they only find
an open record, so for an already closed employment they return StaffEmploymentNotFound.Which operation to choose
The API has no employment deletion: a record is closed only through
terminate and stays in the history. Every
modifying operation comes in two variants: by employmentId in the request body and by extId in the path
(ext/{extId}/...). They work the same way; the extId variant is more convenient for synchronization — you don’t need to store
Exode’s internal IDs.
List employments
StaffView).
Request parameters
Array parameters are passed by repeating the parameter in the query string:
userIds=1&userIds=2&userIds=3.Pagination
integer
Number of records to skip. Defaults to
0.integer
Page number (an alternative to
skip). Starts at 1.integer
Number of records per page. Defaults to
100, maximum 1000.Filtering
integer[]
Filter by employment IDs. Up to 250 values.
string[]
Filter by employment external identifiers (
extId). Up to 250 values, each up to 50 characters.integer[]
Filter by user IDs. Up to 250 values.
integer[]
Filter by department IDs. Up to 250 values.
string[]
Filter by department external identifiers (
extId). Up to 250 values, each up to 50 characters.integer[]
Filter by position IDs. Up to 250 values.
string[]
Filter by position external identifiers (
extId). Up to 250 values, each up to 50 characters.boolean
true — only employees who have met every condition for moving to the next grade; false — only those who
have not met them yet.enum[]
Filter by employment status. Possible values:
Active, Terminated. Up to 250 values.boolean
If
true, returns only employments that are in effect right now: status Active and a startAt date
that has already passed. A hire with a future startAt is not included until that date — to get such
records as well, use statuses=Active.string
Search by employee: full name, login, user ID. Maximum 50 characters.
Sorting
enum
Sort direction by record creation date:
ASC or DESC. The id and updatedAt parameters work
the same way. Without sorting parameters, records of the same employee are listed together (grouped by userId).Response fields
object
Paginated list of employments.
Hire an employee
StaffManage).
Creates a new active employment record. The user, the department and the position (if specified) must
belong to the school. The employee cannot have an active duplicate with the same department + position pair, and when
hiring without a position — with the same department + user pair. If the user was previously terminated and has
the Terminated status, hiring automatically restores their Active status.
The department is required and is specified by ID or external identifier: pass exactly one parameter of the
departmentId / departmentExtId pair. The position is optional: pass exactly one parameter of the
positionId / positionExtId pair, or pass neither — the employee is then hired without a position. You cannot pass
both fields of the same pair at once. If the position is linked to departments, the hiring department must be
among them, otherwise StaffPositionNotInDepartment is returned.
The grade is optional and is set the same way — with one parameter of the gradeId / gradeExtId pair. It is
checked for belonging to the school (StaffGradeNotFound) and against the position’s list of grades
(StaffGradeNotForPosition); when grades are disabled in the school, StaffGradesDisabled is returned.
Request parameters
integer
required
ID of the user being hired. The user must already be registered in the school, otherwise
UserNotBelongsToSchool is returned. The ID is returned when the user is created; you can find it by your external
identifier with user/find. To create a user
and hire them in a single call, use extra.staff.employments in
user/create or user/upsert.string
External identifier of the employment from the client’s system. From 1 to 50 characters, without
/ or whitespace.
Must be unique within the school among open (not finished) employments. If the school has an org-structure
source app connected, a hire with an extId returns MiniappInstallationManagedEntity.integer
Position ID. The position must belong to the school and be available in the hiring department (a position
without department links is available everywhere). Optional: pass one parameter of the
positionId / positionExtId pair, or pass neither — the employee is hired without a position.string
External identifier (
extId) of the position — an alternative to positionId.integer
Grade ID. The grade must belong to the school and be in the position’s list of
grades (if the list is set). Optional: pass one parameter of the
gradeId / gradeExtId pair, or pass
neither — the employee is hired without a grade.string
External identifier (
extId) of the grade — an alternative to gradeId.integer
Department ID. The department must belong to the school. Pass exactly one parameter of the
departmentId / departmentExtId pair.string
External identifier (
extId) of the department — an alternative to departmentId.string
Employment start date in ISO 8601 format (for example,
2026-07-02T00:00:00.000Z). Defaults to the current
moment. You can specify a past date (history migration) or a future date (a scheduled hire): a future record
gets the Active status right away, but until startAt arrives it is not included in activeOnly=true results and cannot
be assigned as a department manager.enum
Employment kind:
Main (main job), InternalSecondary (internal secondary job),
ExternalSecondary (external secondary job). Defaults to Main.enum
Employment type:
FullTime (full-time) or PartTime (part-time). Defaults to FullTime.number
Rate — a fraction of the full rate, from
0.01 to 1. Defaults to 1.Transfer to another department
StaffManage).
Closes the current active employment record (finishAt, status Terminated) and creates a new active
record in the target department. The target department must belong to the school. If the employee already has
an open record with the same position in the target department, StaffEmploymentAlreadyExists is returned.
By default the position and the grade are kept; if the current position is linked to departments and the target
department is not among them, StaffPositionNotInDepartment is returned. To change the position and/or the grade
at the same time, pass toPositionId and/or toGradeId — a single operation instead of a transfer + promote
pair. The new position and grade are checked the same way as when changing the position, but
against the target department.
Request parameters
integer
required
ID of the active employment record being transferred.
integer
ID of the target department. The department must belong to the school. Pass exactly one parameter of the
toDepartmentId / toDepartmentExtId pair.string
External identifier (
extId) of the target department — an alternative to toDepartmentId.integer | null
ID of the new position in the target department. The value
null removes the position. Not passed — the
position is kept. Specified by ID only (there is no extId variant).integer | null
ID of the new grade. The value
null removes the grade. Specified by
ID only (there is no extId variant).string
Transfer date in ISO 8601 format. Must not be earlier than the current record’s
startAt, otherwise
StaffEmploymentInvalidTransitionDate is returned. Defaults to the current moment.Transfer by external identifier
StaffManage).
Same as transfer by employmentId, but the active employment record is looked up by the external identifier
extId within the school. The request body is the same as for a regular transfer, without the employmentId field:
pass toPositionId / toGradeId if needed to change the position and grade in the same operation.
Request parameters
string
required
External identifier of the active employment record. The value in the path must be URL-encoded.
integer
ID of the target department. The department must belong to the school. Pass exactly one parameter of the
toDepartmentId / toDepartmentExtId pair.string
External identifier (
extId) of the target department — an alternative to toDepartmentId.integer | null
ID of the new position in the target department. The value
null removes the position. Not passed — the
position is kept. Specified by ID only (there is no extId variant).integer | null
ID of the new grade. The value
null removes the grade. Specified by
ID only (there is no extId variant).string
Transfer date in ISO 8601 format. Must not be earlier than the current record’s
startAt, otherwise
StaffEmploymentInvalidTransitionDate is returned. Defaults to the current moment.Change position
StaffManage).
Closes the current active employment record (finishAt, status Terminated) and creates a new active
record with the new position and/or grade in the same department. The target position must belong to the school and
be available in the current department (StaffPositionNotInDepartment). If the employee already has an open record
with the new position in this department, StaffEmploymentAlreadyExists is returned.
The request must state the intent explicitly: pass a position (toPositionId or toPositionExtId) and/or a
grade (toGradeId or toGradeExtId) to assign them, or null to remove them (the employee stays in the
department without a position or without a grade). If you pass none of these fields, the
StaffEmploymentInputRequired error is returned.
The grade is checked the same way as on hire: StaffGradeNotFound, StaffGradeNotForPosition,
StaffGradesDisabled. If only the position changes, the current grade is kept when it is in the new position’s list
of grades, and is reset to null when it is not.
Request parameters
integer
required
ID of the active employment record being changed.
integer | null
ID of the target position. The position must belong to the school. Pass exactly one parameter of the
toPositionId / toPositionExtId pair. The value null removes the position — the employment stays in the
department without a position. You cannot pass both fields of the pair at once.string
External identifier (
extId) of the target position — an alternative to toPositionId.integer | null
ID of the target grade. Pass exactly one parameter of the
toGradeId / toGradeExtId pair. The value null removes the grade.string
External identifier (
extId) of the target grade — an alternative to toGradeId.string
Position change date in ISO 8601 format. Must not be earlier than the current record’s
startAt, otherwise
StaffEmploymentInvalidTransitionDate is returned. Defaults to the current moment.Change position by external identifier
StaffManage).
Same as changing the position by employmentId, but the active employment record is looked up by the external identifier
extId within the school. The request body is the same as for a regular position change, without the employmentId field: pass
a position and/or a grade to assign them, or null to remove them; if none of these fields is passed, the
StaffEmploymentInputRequired error is returned.
Request parameters
string
required
External identifier of the active employment record. The value in the path must be URL-encoded.
integer | null
ID of the target position. The position must belong to the school. Pass exactly one parameter of the
toPositionId / toPositionExtId pair. The value null removes the position — the employment stays in the
department without a position. You cannot pass both fields of the pair at once.string
External identifier (
extId) of the target position — an alternative to toPositionId.integer | null
ID of the target grade. Pass exactly one parameter of the
toGradeId / toGradeExtId pair. The value null removes the grade.string
External identifier (
extId) of the target grade — an alternative to toGradeId.string
Position change date in ISO 8601 format. Must not be earlier than the current record’s
startAt, otherwise
StaffEmploymentInvalidTransitionDate is returned. Defaults to the current moment.Terminate an employee
StaffManage).
Closes an active employment record: sets finishAt, changes the status to Terminated and removes
the employee as manager of any departments. The response contains the closed record.
Safeguards when terminating the last active employment: you cannot terminate yourself — the user
on whose behalf the request is made (
StaffCannotTerminateSelf) — or the school owner
(StaffCannotTerminateSchoolOwner). Skip these users when reconciling the full employee list.Termination takes effect at the moment of the call: the record gets the
Terminated status immediately, and when
terminating the last employment, access is closed immediately — even if finishAt is set in the future. There is no deferred
termination, so call terminate on the actual termination day.Request parameters
integer
required
ID of the active employment record being terminated.
string
Termination date in ISO 8601 format, stored in the record. Must not be earlier than the employment’s
startAt, otherwise
StaffEmploymentInvalidTransitionDate is returned. Defaults to the current moment.Terminate by external identifier
StaffManage).
Same as termination by employmentId, but the active employment record is looked up by the external identifier
extId within the school. The request body is the same as for a regular termination, without the employmentId field. The same
safeguards apply, as does the same logic of switching the user to the Terminated status when their last active
employment is terminated.
Request parameters
string
required
External identifier of the active employment record. The value in the path must be URL-encoded.
string
Termination date in ISO 8601 format, stored in the record. Must not be earlier than the employment’s
startAt, otherwise
StaffEmploymentInvalidTransitionDate is returned. Defaults to the current moment.Permission requirements
The staff module is available only to schools in the
Corporate segment. Reading the list requires the “Staff browsing” permission (StaffView);
hiring, transfer, promotion and termination require the “Staff Management” permission (StaffManage).Updated: 2026-10-16 13:24 UTC