Прокторинг: backend и frontend SDK
Полное руководство по подключению онлайн-прокторинга: регистрация пользователя и создание экзамена через API, запуск фронтенд-SDK на странице задания и получение отчёта о прохождении.
Порядок действий
Четыре шага от создания экзамена на вашем backend до готового отчёта. Подробности каждого шага — в разделах ниже.
Ваш backend отправляет данные о студенте и экзамене на TrustExam API.
В ответе вы получаете external_session.token, который необходимо вставить в SDK JS.
Фронт запускает через SDK метод с параметрами — Proctoring.initialize({ token: external_session.token }).
Результаты доступны через report_url.
Последовательность взаимодействия
finish_url и внешняя ссылка report_url.
Proctoring.start() сам вызовет
Proctoring.startNewAttempt() — отдельный шаг в схеме для этого не нужен.
Ключ и доступы
X-Authorization при создании экзамена
Создание экзамена и регистрация пользователя
Запрос предназначен для создания / регистрации одного пользователя. Данный запрос вы можете встроить перед
тем как пользователь откроет страницу экзамена, либо заранее, осуществить запрос на каждого пользователя и
хранить значения у себя. В ответе вы получите JSON, из которого нужно использовать только —
{"external_session": {"token": "…"}}.
external_id, либо скопируйте запрос как cURL и выполните его у себя.
X-Authorization подставляется из поля «API-ключ» в разделе
Ключ и доступы — пока вы не отредактируете заголовки вручную.
X-Authorization, а в примере cURL —
query-параметром ?api_token=…. Оба варианта приведены как в источнике; уточните
актуальный способ авторизации у команды TrustExam.
Ответ появится здесь после отправки запроса.
Пока запрос не отправлен, ниже приведён пример ответа из документации —
использовать нужно только external_session.token.
{
"session_url": "https://app.trustexam.ai/session/assignment/......",
"report_url": "https://app.trustexam.ai/report/........",
"access_token": "Bearer ...",
"wss_access_token": "...",
"student": {
"id": 2862000,
"school_id": 516,
"user_id": 2715144
},
"assignment": {
"id": 192588,
"external_id": 123,
"external_url": "https://example-ru.proxy.trustexam.ai/exam/123",
"class_id": 534744,
"owner_id": 2646720,
"type": "external",
"access_type": "free",
"status": "process",
"application": "browser",
"name": "Тест",
"description": "Тест",
"starting_at": "2025-02-27T10:04:42.000000Z",
"starting_at_type": "now",
"ending_at": "2025-02-27T10:04:42.000000Z",
"ending_at_type": "without",
"created_at": "2025-02-27T10:04:42.000000Z",
"updated_at": "2025-02-27T10:04:42.000000Z"
},
"external_session": {
"id": 134840,
"user_id": 2715144,
"type": "assignment",
"token": ".....",
"data": {
"query": {"foo": "bar", "some_token": "some_token"}
},
"is_revoked": false
}
}
Конструктор настроек прокторинга
Соберите конфигурацию переключателями — справа собирается готовый объект
proctoring_settings. Изменённые относительно значений по умолчанию параметры подсвечиваются.
Результат сразу подставляется в assignment.settings.proctoring_settings тела запроса
в разделе Создание экзамена.
Подключение
TrustExam Proctoring SDK предназначен для интеграции системы онлайн-прокторинга в сторонние веб-приложения. Он предоставляет методы для инициализации, запуска, завершения и повторного начала экзаменационных попыток, а также обратные вызовы для отслеживания состояния и ошибок.
Подключите скрипт SDK в HTML-страницу экзамена. После загрузки он создаёт глобальный объект Proctoring — через него вызываются все методы, описанные ниже.
<script src="https://cdn.trustexam.ai/extension/app.js"></script>
Инициализация
Proctoring.initialize('.wrapper', {
language: 'en', // en / ru / kz
token: 'YOUR_SESSION_TOKEN', // external_session.token from backend api response
protector: {
match: '.question-wrapper',
textColor: '#000'
},
onMounted: function () { ... },
onConfigured: function () { ... },
onStarted: function () { ... },
onFinished: function () { ... },
onAction: function (action) { ... },
onError: function (error) { ... }
})
selectorstring- контейнер для инициализации (например,
.wrapper) languagestring- язык интерфейса
tokenstring- токен, полученный при запросе к API, в ответе —
{"external_session": {"token": "…"}}
onMounted()- вызывается после инициализации
onConfigured()- SDK успешно сконфигурирован
onStarted()- экзамен начат
onFinished()- экзамен завершён
onAction(action)- вызывается при действиях
onError(error)- обработка ошибок
Методы
1. Proctoring.start()
Начать задание. Вы должны вызвать этот метод, после того как пользователь начал экзамен
на вашей платформе. Включает логику проверки завершенности задания. В случае если задание завершено,
создаст новую поптыку, метод startNewAttempt — вызовется автоматически.
Proctoring.start()
.then(() => console.log('started'))
.catch(err => console.log(err))
2. Proctoring.finish()
Завершить задание. Также завершает текущую поптыку. Вы должны вызвать этот метод, после того как пользователь завершил экзамен на вашей платформе.
Proctoring.finish()
.then(() => console.log('finished'))
.catch(err => console.log(err))
3. Proctoring.startNewAttempt()
Начать новую попытку. Данный метод вызывается автоматически при вызове start(), в случае
если текущая попытка завершена.
Proctoring.startNewAttempt()
.then(() => console.log('new attempt started'))
.catch(err => console.log('cannot start new attempt'))
Дополнительные вспомогательные методы
Proctoring.isStarted()- проверяет, начато ли задание
Proctoring.isFinished()- проверяет, завершено ли задание
Proctoring.isCanStartNewAttempt()- проверяет, можно ли создать новую попытку
Content Protect
Content Protect защищает содержимое одного контейнера на странице экзамена от скриншотов, записи экрана и программ удалённого управления. Функция включается с двух сторон: на backend — параметром content_protect: true в настройках прокторинга, на frontend — объектом protector в параметрах инициализации, где match задаёт защищаемый контейнер.
- От скриншотов
- Записи экрана
- Удаленного управления
- Screen Share — только запись окна (
displaySurface: window) - На старых ПК возможно не будет работать
- Защитить можно только один элемент на странице
- Backend — Передать
"content_protect: true", в параметрах прокторинга - Frontend — Требуется передать
protector(object) в параметрах ициниализации
{
...
protector: { match: '.question-wrapper', textColor: '#000' },
...
}
match- Это контейнер, который необходимо защитить
textColor- Цвет шрифта в вашем контейнрере
Пример текста
После инициализации попробуйте сделать скриншот следующего текста.
Демо-песочница
Кнопки вызывают реальные методы SDK на этой странице. Токен подставляется автоматически после успешного запроса в разделе Создание экзамена — либо укажите его вручную.
external_session.token
.wrapper для SDK — здесь появится интерфейс прокторинга.Отчет о прохождении экзамена
По завершении попытки система прокторинга формирует отчёт: фотографии пользователя и документа, видеозаписи экзамена, время начала и завершения, список нарушений, скоринг по шкале от 0 до 100, вердикт и комментарий проктора, а также AI-сводку. Получить его можно двумя способами — по внешней ссылке report_url или JSON-запросом на ваш webhook.finish_url.
Существует два вида отчета:
Прокторинговая система формирует ссылку на просмотр отчета об экзамене. Данную ссылку можно получить в ответе на запрос (создание экзамена).
{"report_url": "https://app.trustexam.ai/report/XXXXXX"}
По окончании экзамена, система прокторинга формирует отчет и отправляет POST-запрос на endpoint
указанный в параметрах экзамена (webhook.finish_url) в JSON-формате.
- Фотография пользователя
- Фотография документа
- Видеозаписи прохождения экзамена
- Дата и время начала и завершения экзамена
- Список нарушений
- Скоринг по шкале от 0 до 100
- Вердикт проктора
- Комментарий проктора
- AI-отчет. Сводка, информация об экзамене
- Внешняя ссылка на отчет
Поля отчёта
| Поле | Тип | Значение |
|---|---|---|
identification | Object | {“photo_url”: “https://storage.oqylyq.kz/document.jpg”, “document_url”: “https://storage.oqylyq.kz/document.jpg”} |
school_id | Int | Идентификатор организации |
assignment_id | Int | Идентификатор экзамена в системе прокторинга |
assignment_external_id | String | Идентификатор экзамена в вашей системе |
assignment_attempt_id | Int | Идентификатор попытки в системе прокторинга |
assignment_attempt_external_id | String | Идентификатор попытки в вашей системе |
user_id | Int | Идентификатор пользователя в системе прокторинга |
user_external_id | String | Идентификатор пользователя в вашей системе |
credibility | Int | Скоринг по 100 балльной шкале |
started_at | String (Datetime) | Время начала экзамена. Пример — 2026-06-15T15:30:00Z |
finished_at | String (Datetime) | Время завершения экзамена. Пример — 2026-06-15T15:30:00Z |
actions | Array | Список всех действий пользователя.
|
violations | Array | Список нарушений во время экзамена. Список нарушений перечислен в
следующей таблице.
|
videos | Array | Список видеозаписей. Типы видеозаписей:
|
proctor_review | Object | Комментарии и вердикт проктора. Где status:
{“status”: 1, “comment”: “Все отлично!”}
|
ai_report | Object | {“risk”: {"level":"low","score":0}, “summary_ru”: “Студент завершил задание за 12 минут. Обнаружено 3 события речи. Выявлено одно критическое нарушение.”, “summary_en”: “...”} |
report_url | String | Внешняя ссылка на отчет (упомянутая выше) |
Список нарушений
| Тип | Штрафной балл | Описание |
|---|---|---|
noise_detect | 1 | Обнаружен посторонний шум |
speech_detect | 1 | Распознан голос |
earphone_detected | 50 | Обнаружен микронаушник |
mic_muted | 0 | Микрофон отключен |
bluetooth_detected | 0 | Обнаружено Bluetooth-устройство |
bluetooth_off | 0 | Bluetooth отключен |
wifi_detected | 20 | Обнаружена подозрительная Wi-Fi активность |
wifi_off | 0 | Wi-Fi отключен |
copy_paste | 10 | Попытка скопировать / вставить текст |
connection_restored | 15 | Интернет соединение восстановлено, после потери соединения |
focus_down | 5 | Потерян фокус |
extension_detected | 50 | Обнаружено вспомогательное расширение |
fullscreen_closed | 2 | Отключен полноэкранный режим |
multiple_screen | 50 | Обнаружен второй монитор |
usb_device_detected | 0 | Обнаружено устройство |
task_process_detected | 0 | Обнаружено запрещенное программное обеспечение |
head_mismatch | 20 | Пользователь не идентифицирован |
head_empty | 5 | Пользователь исчез с видоискателя |
head_many | 5 | Обнаружено несколько лиц |
head_rotated | 1 | Пользователь повернул голову |
head_depth | 1 | Пользователь находился далеко от камеры |
eye_away | 1 | Отведен взгляд |
object_detected | 1 | Обнаружены запрещенные предметы |
Общие вопросы
Доступы и подключение
Что нужно получить перед началом интеграции?
Три вещи от менеджера интеграции: API-ключ организации, адреса стенда (API, CDN, приложение и отчёты, медиа-сервер, ИИ-отчёты) и подтверждённый состав полей студента. Адреса впишите в разделе «Адреса стенда» — все примеры на этой странице подставят их автоматически. API-ключ подставляется отдельно: введите его в поле api_token в шапке страницы, и он появится в примерах вместо YOUR_API_TOKEN.
Сколько запросов к API нужно на один экзамен?
Один. POST /api/external-session/assignment.json создаёт задание, регистрирует студента и возвращает токен. Запрос идемпотентный по assignment.external_id и student.external_id — повторный вызов обновляет данные, а не плодит дубликаты. Токены можно подготовить заранее, пачкой на всех участников, и сохранить у себя.
Где должен храниться API-ключ и можно ли создавать сессию из браузера?
Ключ живёт только на вашем backend и не должен попадать в JS-бандл, конфиг фронтенда, репозиторий и логи запросов. Создавать сессию из браузера нельзя: API-ключ даёт доступ к данным всей организации. Во фронтенд уходит исключительно external_session.token, привязанный к конкретной попытке. Передаётся ключ либо параметром ?api_token=YOUR_API_TOKEN, либо заголовком X-Authorization — см. «Создание экзамена».
Чем token отличается от access_token?
token — токен внешней сессии, рекомендуемый режим для внешних интеграций: SDK сам определит экзамен. access_token — Bearer-токен пользователя для внутренних интеграций, и он требует дополнительно передать assignment. Если не передано ни то, ни другое, initialize выбросит Access Token is required.
Нужно ли студенту что-то устанавливать?
В режиме assignment.application: browser — нет, всё работает в обычном браузере. Режимы desktop (защищённое приложение) и tray (фоновый агент) требуют отдельного дистрибутива — состав и порядок выдачи уточняйте у менеджера интеграции.
Можно ли сначала посмотреть форматы запросов, не имея доступов?
Да. Песочница возвращает заранее подготовленные ответы (в том числе 401 и 422) без обращения к сети, а конструктор собирает готовое тело запроса. Реальный стенд для тестов выдаёт менеджер.
Данные студента
Как передавать идентификатор студента и ФИО?
Идентификатор — обязательное поле student.external_id, ваш идентификатор пользователя. Именно по нему работает идемпотентность: повторный запрос обновляет того же студента, а не заводит нового.
Персональные данные (имя, фамилия, e-mail) передаются рядом с ним. Примеры запроса на этой странице собирают их плоскими полями объекта student:
{ "external_id": "user-10254", "firstname": "Иван", "lastname": "Иванов", "email": "ivan.ivanov@example.com" } student.external_id; состав и форма персональных полей фиксируются при выдаче доступов к вашему стенду. Выясните нужный состав до начала работы и не угадывайте. Какие данные студента уходят на платформу?
При создании сессии — обязательный student.external_id и персональные поля (имя, фамилия, e-mail), которые нужны для отчёта; см. вопрос выше.
Как связать отчёт со своей записью о попытке?
Передайте session_data.external_id при создании сессии — он вернётся в webhook типа Default полем assignment_attempt_external_id.
Где оказывается видеозапись?
На медиа-сервере платформы, по WebRTC, по мере записи. При включённой локальной записи после finish() открывается окно догрузки файлов — вкладку до конца загрузки закрывать нельзя, предупредите об этом студента в своём интерфейсе.
Результаты и отчёты
Как получить отчёт по экзамену?
Двумя способами, они дополняют друг друга:
report_url— готовая страница с видеозаписями, таймлайном событий и скриншотами. Приходит в ответе на создание сессии; сохраните её у себя сразу.- Webhook — платформа сама сообщит вашему серверу о старте и завершении, опрашивать API не нужно (Webhooks).
Отчёты живут на стороне платформы: report_url открывается по сохранённой ссылке, адрес приложения отчётов входит в адреса стенда, которые выдают при подключении.
Потеряли report_url — как восстановить?
Только повторным запросом создания сессии. Сохраняйте report_url в своей БД сразу, вместе с attempt.id, привязанными к попытке студента.
Как узнать о завершении экзамена, не опрашивая API?
Через webhooks: assignment.settings.webhook.start_url и finish_url. Туда же можно добавить свои поля в тело (post), заголовки (headers) и параметры строки запроса (query) — например авторизацию вашего эндпоинта.
Можно ли встроить отчёт в свой интерфейс?
Да, report_url открывается и отдельной вкладкой, и в <iframe>: это готовая страница с видеозаписями, таймлайном событий и скриншотами.
Нужен ли живой проктор?
Базовый сценарий — асинхронный: платформа пишет попытку, детекторы фиксируют события, по завершении доступны отчёт и ИИ-оценка риска (low / medium / high / critical) с текстовой сводкой и интервалами для просмотра. Нужен ли ручной разбор — решаете вы по уровню риска. Синхронный (живой) прокторинг эта документация не описывает — о нём разговаривайте с менеджером интеграции.
Требования к среде студента
Обязателен ли HTTPS?
Да. Без защищённого соединения браузер не отдаёт getUserMedia и getDisplayMedia — камера, микрофон и демонстрация экрана не запустятся.
Какие браузеры поддерживаются?
Параметр browser_type ограничивает, в каком браузере можно сдавать: * (любой), chrome, edge, opera, yandex. Это настройка допуска, а не матрица совместимости — минимальные версии браузеров в документации не зафиксированы, уточняйте их у менеджера интеграции. Проверьте интеграцию именно в тех браузерах, которые разрешаете студентам, — это отдельный пункт предстартового чек-листа.
Что открыть в закрытом сетевом контуре?
Домены CDN, API, медиа-сервера, приложения и ИИ-отчётов (см. «Куда обращается SDK»), а также WebRTC (STUN/TURN) и разрешения на камеру, микрофон и захват экрана в браузере пользователя.
Можно ли взять app.js с одного стенда, а API — с другого?
Нет. В загрузчике app.js зашит адрес основного бандла, подставленный при сборке стенда: бандл всегда загрузится с того же домена, откуда взят загрузчик. Смешивать стенды нельзя.
Настройки прокторинга
Нужно ли передавать весь proctoring_settings?
Нет — только то, что отличается от значений по умолчанию, остальное подставится само. Конструктор в режиме «Только изменённое» собирает минимальное тело запроса.
Как изменить настройки уже созданного экзамена?
Повторным POST с тем же assignment.external_id: запрос идемпотентный и обновит настройки, а не создаст второй экзамен.
Включили content_protect, но защиты нет.
Нужны обе части: content_protect: true в настройках экзамена на backend и protector.match с селектором защищаемого блока в initialize. Плюс ограничения: защитить можно только один элемент, демонстрация экрана возможна лишь в режиме записи окна, а на части устройств защита не активируется — предусмотрите запасной сценарий в onError.