Разработчикам

TrueHire API: проверка «тот же человек» в вашей ATS

Два способа: ссылка — кандидат проходит проверку на нашей странице, итог приходит в ваш вебхук (рекомендуется); прямой API — если у вас свой виджет камеры. Полный справочник схем — OpenAPI.

Ключ и окружение

Ключ интегратора передаётся в заголовке X-API-Key. Ключ выдаём при подключении пилота или вы выпускаете его в кабинете. Вместе с ключом из кабинета выдаётся секрет вебхуков whsec_… — он показывается один раз, им подписываются уведомления об итоге; потерянный секрет перевыпускается в кабинете.

Сценарий по ссылке

1. Онбординг — создать эталон

curl -X POST https://truhire.ru/v1/sessions \
  -H "X-API-Key: $TRUEHIRE_KEY" -H "Content-Type: application/json" \
  -d '{
    "subject_ref": "hf-applicant-777",
    "purpose": "enroll",
    "operator_name": "ООО «Ваша компания»",
    "display_name": "Иван Петров",
    "callback_url": "https://ats.example.com/truehire/hook"
  }'

{ "session_id": "vs_…", "verify_url": "https://truhire.ru/verify/…", "expires_at": 1790000000 }

Отправьте verify_url кандидату. Он даёт согласие (или отказывается), выполняет 2–3 случайных действия на камеру. Ссылка действует 72 часа, до трёх попыток.

2. Итог — в ваш вебхук

POST https://ats.example.com/truehire/hook
X-TrueHire-Event: session.completed
X-TrueHire-Signature: sha256=<HMAC-SHA256(тело, секрет вебхуков)>

{
  "event": "session.completed",
  "session": {
    "session_id": "vs_…", "subject_ref": "hf-applicant-777", "purpose": "enroll",
    "status": "completed",
    "result": { "outcome": "done",
                "checks": { "same_person": "not_checked", "liveness": "passed",
                            "document": "not_checked", "legal_identity": "not_verified" } },
    "anchor_blob": "tha1.…"
  }
}

Сохраните anchor_blob в карточке кандидата: это зашифрованный эталон, открыть его можно только вашим ключом. Мы эталон у себя не храним.

События: session.completed, session.manual_review (решить автоматически нельзя), session.declined (кандидат отказался от биометрии — нужна другая проверка), session.withdrawn (согласие отозвано — удалите anchor_blob). Если вебхук недоступен, итог всегда можно забрать через GET /v1/sessions/{id}.

3. Следующий этап и выход на работу — сверка

curl -X POST https://truhire.ru/v1/sessions -H "X-API-Key: $TRUEHIRE_KEY" \
  -d '{ "subject_ref": "hf-applicant-777", "purpose": "verify", "stage": "day_one",
        "anchor_blob": "tha1.…", "callback_url": "https://ats.example.com/truehire/hook" }'

В итоге — раздельные проверки и подписанный отчёт:

checks.*ЗначенияСмысл
same_personmatch · uncertain · mismatch · not_checkedТот же ли человек, что на эталоне
livenesspassed · failed · not_checkedЖивой человек, не фото и не повтор записи
documentnot_checked (опционально — проверки документа)Подлинность документа
legal_identitynot_verifiedЮридическую личность модуль не устанавливает

report.status = insufficient_data и overall_risk = unknown, если сверки личности и живости не было: отсутствие сигналов — не «низкий риск». recommendation всегда manual_review.

Проверка подписи вебхука

import hashlib, hmac

def valid(raw_body: bytes, header: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, header)

secret — секрет вебхуков вашего ключа (для ключа, выданного при подключении пилота без кабинета, — сам API-ключ). Если секрета нет, уведомление не отправляется: неподписанное опаснее. Вебхук принимается только по httpsи только на публичный адрес, перенаправления не выполняются. Повторы — до трёх попыток с паузой; ответ 2xx считается доставкой.

Виджет на странице вашей ATS

Один скрипт открывает проверку поверх вашей страницы — во всплывающем окне (работает везде) или в модальном окне с iframe (домен нужно добавить в разрешённые — напишите нам). Виджет сообщает только статус сессии; итог берите на сервере (вебхук илиGET /v1/sessions/{id}).

<script src="https://truhire.ru/widget/v1.js"></script>
<script>
  // verifyUrl — verify_url из POST /v1/sessions (создаётся на вашем бэкенде)
  TrueHire.open({
    url: verifyUrl,
    mode: "popup",            // или "modal"
    onEvent: (e) => console.log(e.status),
    onComplete: () => refreshCandidate(),
  });
</script>

Массовая проверка и учёт

curl -X POST https://truhire.ru/v1/sessions/batch -H "X-API-Key: $TRUEHIRE_KEY"   -d '{ "items": [ { "subject_ref": "hf-1", "purpose": "enroll", "display_name": "Анна" },
                   { "subject_ref": "hf-2", "purpose": "enroll" } ],
        "callback_url": "https://ats.example.com/truehire/hook" }'

{ "created": [ { "subject_ref": "hf-1", "session_id": "vs_…", "verify_url": "…" }, … ],
  "errors": [] }

Единица учёта — проверка: созданная ссылка или успешный enroll/detect. Повторный захват внутри одной проверки (плохой свет, камера) не тарифицируется. Расход — в GET /v1/usage; у ключа может быть месячная квота (402) и лимит запросов в минуту (429).

Прямой API (свой виджет камеры)

  1. POST /v1/challenges → { nonce, sequence, instructions, expires_in }. Покажите кандидату инструкции по порядку.
  2. Снимите 2–3 секунды видео как серию JPEG-кадров (8–10 кадров/с, ~480–640 px, не больше 30 кадров в запросе) с метками времени t_ms.
  3. POST /v1/enroll с challenge_nonce, кадрами и consent_confirmed: true (согласие собираете вы как оператор).

Геометрию лица считает только сервер; присланные клиентом «признаки движения» не принимаются. Nonce одноразовый и привязан к вашему ключу.

Эндпоинты

МетодПутьНазначение
POST/v1/sessionsСсылка для кандидата: enroll (эталон) или verify (сверка этапа)
POST/v1/sessions/batchМассовая проверка: до 200 ссылок одним запросом
GET/v1/usageВаш расход: проверки за месяц, квота, по дням
GET/v1/sessions/{id}Статус, итог, anchor_blob после enroll
GET/v1/sessions?subject_ref=Сессии по кандидату
POST/v1/challengesЗадание для своего виджета камеры: 2–3 действия + nonce (~90 с)
POST/v1/enrollЭталон по живому захвату с nonce → anchor_blob
POST/v1/detectСверка этапа по кадрам → подписанный вердикт
POST/v1/live-checkОдин кадр видеозвонка против эталона
GET/v1/public-keyПубличный ключ для проверки подписи вердиктов
GET/v1/healthСтатус и версии движков

Ошибки

КодКогда
401Нет или неверный X-API-Key
402Исчерпана месячная квота проверок по ключу
429Превышен лимит запросов в минуту (заголовок Retry-After)
409anchor_blob выпущен для другого subject_ref
413Слишком много кадров или слишком большой кадр
422Некорректные данные, нет согласия, живость не подтверждена, просроченный nonce, чужой/подделанный блоб
503На установке не подключена модель геометрии лица — живость проверить нельзя

Готовые модули ATS

Если ваша ATS есть в списке, писать код не нужно. Администратор открывает в кабинете «Администрирование → Подключение ATS», вставляет ключ доступа к ATS и отмечает этапы «эталон» и «сверка». Дальше смена этапа в ATS сама создаёт проверку, а ссылка для кандидата и итог приходят заметкой в карточку. Где ATS это позволяет, вебхук регистрируется автоматически. Ключи ATS хранятся зашифрованными, биометрия в ATS не передаётся.

«Бета» — модуль написан по официальной документации ATS и проверен на тестовых данных; первое подключение мы сопровождаем вместе с вашим администратором.

Загружаем список модулей…

Нужен ключ или помощь с интеграцией? Оставьте заявку · Безопасность и данные