Endpoint and authorization
Send the operations to the Kralis GraphQL API. Authenticate first and include the access token as described in Authentication. Every operation is evaluated against the authenticated user’s active school. The query requires the identifier view permission. Identifier mutations also require the corresponding add, change, or delete permission. Kralis Web currently exposes identifier management to authorized school administrators and deans; API clients should handle permission errors rather than assuming that a visible control grants access. Use GraphiQL to confirm the current schema, enum values, and generated filter argument names before shipping a client.Supported integrations
Theintegration value is a stable machine key:
The GraphQL enum is uppercase even though the stored key is lowercase. Use the enum value in GraphQL variables.
Identifier fields
externalName is retained as supplied by the partner. It is reference data, not a replacement for the Kralis name. metadata is an optional JSON object for integration-specific details.
Year behavior
yearId is optional in mutation input, and year_Id is the generated filter argument on the root connection.
- A null year creates a yearless identifier that can be reused across academic years.
- A year-specific identifier applies to one academic year.
- A student can have one identifier per integration and year scope.
- An external ID is unique within a school, integration, and year scope.
- A nested student query with
yearIdreturns the selected-year identifier first and can fall back to the yearless identifier. - The root
studentIntegrationIdentifiersquery filters the stored rows; it does not apply the nested fallback rule.
Query all identifiers
The root connection supports Relay pagination, generated Django-filter arguments, and a search that checks external IDs, external names, usernames, and student name fields.student_In accepts multiple student IDs. Use student when filtering for one student. The generated connection also exposes exact and text filter variants for supported fields, including id, externalId, externalName, student__user_ptr__id, and year_Id; confirm exact generated names in GraphiQL because Django-filter converts model lookups to GraphQL argument names.
Example response:
id and pk for identifier records. Use endCursor for the next page and merge pages by a stable identifier; see Errors and Pagination.
Query identifiers through a student
Use the nested field when loading a student together with the identifier needed by a workflow. Theintegration and yearId arguments narrow the result, while the resolver prefers a selected-year row and falls back to a yearless row.
userPtr_Id is the student filter used by the students connection. The student object exposes its Node id and database pk for follow-up operations.
Input objects
Create, update, and upsert useStudentIntegrationIdentifierInput:
metadata as an object. On update and upsert, omitting metadata preserves the existing metadata. Supplying it replaces the stored metadata object.
Create one identifier
Use create for a new mapping. It rejects invalid school relations, duplicate scoped mappings, unsupported integrations, and non-object metadata.Update one identifier
Update changes the selected identifier’s fields. It does not silently move a conflicting external identifier to another student; use the replacement mutation for reassignment.Upsert confirmed mappings in bulk
upsertStudentIntegrationIdentifiers is for confirmed mappings. It creates missing rows and updates an existing row for the same student, integration, and year scope. It returns separate counts.
Replace identifier assignments
UsereplaceStudentIntegrationIdentifiers after a user has confirmed a conflict. It atomically moves or changes the selected existing rows and prevents duplicate target assignments.
identifierId, the new studentId, and the external ID. The mutation preserves metadata unless a new metadata object is supplied. It is the safe path when an ESMOE registration number is already linked to Student A and a user confirms moving it to Student B.
Delete identifiers
Delete one row withdeleteStudentIntegrationIdentifier:
bulkDeleteStudentIntegrationIdentifiers:
ids is supplied, only those school-scoped rows are deleted. Without ids, the mutation deletes all rows in the supplied integration and optional year scope, so clients should require an explicit confirmation before calling it.
Recommended client flow
- Load only the active school’s students and paginate both student and identifier connections.
- Prefer an existing identifier over name matching.
- Treat suggested or fuzzy matches as reviewable, not automatically confirmed unless the workflow’s confidence rules allow it.
- Use upsert for new or unchanged confirmed mappings.
- Use replacement for an existing external ID that must move to another Kralis student.
- Refetch after mutations so the UI reflects the authoritative school-scoped state.

