Skip to main content
Upsert is a “create or update” operation. If a user with the given login (phone, email or domain, in that order of priority), Telegram ID (tgId) or external ID (extId) already exists, their data is updated. If there is no such user, one is created.

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.
Requires authentication and the “School User Management” permission (SchoolManageUsers).

Request parameters

To identify an existing user, pass at least one of the parameters below; otherwise a new user is created on every request.
If the user is found by the fields below, the user is only updated. If a user is created, the login and password are sent to the new user automatically (delivery channels are the same as in user/create). You cannot set your own password via upsert: the password field is supported only in user/create.
Only email, phone and domain are sign-in fields (logins). extId and tgId are used to look up an existing user, but you cannot sign in with them.
How an existing user is looked up. Only one of the logins is used for the lookup: the first non-empty one in the order phone → email → domain. If no user is found by it, the lookup continues by tgId, then by extId; the first match is the one updated. For example, if you pass phone and email, and the school only has a user with that email (with a different or empty phone), that user is not found by email: the upsert tries to create a new user and returns the EmailIsBusy error. The EmailIsBusy / PhoneIsBusy / TgIdIsBusy / ExtIdIsBusy errors on update also mean that the value you passed already belongs to another user of the school. For reliable synchronization, pass extId: a permanent identifier from your system.
string
User’s email address. Must be a valid email. An empty string is converted to null.
string
User’s phone number. Must be in international format (for example, +9876543210). An empty string is converted to null.
string
User’s domain login. Up to 65 characters: Latin letters, digits, _ and dots; a dot cannot be first/last and cannot be repeated consecutively (automatically converted to lower case). Must be unique within the school. If not passed on creation, it is generated automatically in the id12345 format. Used for sign-in along with email and phone.
integer
User’s Telegram ID. An integer or null. Not a login.
string
External user ID from your system (for example, a GUID from a CRM/1C). A string of up to 50 characters without / or whitespace, or null. Not a login: used only for linking and lookup.

Additional parameters

enum
Account status: Active, OnLeave, Banned, Blocked or Terminated. OnLeave is informational (does not block access; managed by the absences module); Banned, Blocked and Terminated revoke access: sign-in is denied, active sessions are terminated, enrollments are blocked. Terminated is managed automatically by the employments module; when a ban is lifted (Banned → Active), the actual status is recalculated automatically. The Deleted status is reserved by the system. See user/create and user/update for details.
The boolean banned request field has been removed: blocking is managed only via status. The response still includes the banned and active fields, derived from status.
The school owner is protected: if the upsert finds the owner, setting a blocking status (Banned/Blocked/Terminated) is forbidden and returns the ForbiddenModifySchoolOwner error.

Profile parameters

object
Object with the user’s profile data.
When a user is created, a linked profile with the given data is created automatically. If no profile is specified, an empty profile is created, and the user fills in firstName and lastName on first sign-in.

Additional aggregates (extra)

object
Container for related data applied together with the upsert. Currently it contains the staff.employments block: an array of employments (1 to 10) with department, position, employment kind and type. Available only for corporate schools. If the upsert creates a user, the block is required (an employee cannot exist without an employment). For an existing user, employments are applied idempotently: passing the same active department + position pair again does not create a duplicate.The fields of an employments item are the same as in user/create: extId, positionId/positionExtId, departmentId/departmentExtId, kind, type, startAt, rate.
Data that is not part of this schema (city, a custom status from your CRM, etc.) is passed via custom fields.

Permission requirements

Creating or updating a user requires the “School User Management” permission (SchoolManageUsers).
The service user must be authenticated with a token and have the appropriate access rights to the specified school.
When a blocking status (Banned/Blocked/Terminated) is set, all of the user’s active sessions are terminated automatically. This is done for security reasons.

Updated: 2026-09-25 14:33 UTC