API и интеграция с CRM
Полный цикл без ручной работы: ваша система сама выпускает код на съёмку, узнаёт о снятом материале и программно проверяет подлинность файла. Подходит для CRM, систем учёта заявок, 1С и no-code-платформ.
Доступ: один ключ на всё
API-ключ создаётся в личном кабинете, раздел «Интеграции и API» — самостоятельно, без обращения в поддержку. Ключ показывается один раз в момент создания; если потеряли — отзовите его там же и создайте новый.
Ключ передаётся в заголовке X-Api-Key в каждом запросе. Один и тот же ключ работает для всех операций ниже.
| База | Что там |
|---|---|
https://api.trustvisor.ru | Коды на съёмку, статусы, вебхуки — всё под /v1/business/… |
https://portal.trustvisor.ru | Проверка файлов — /v1/verify |
Типовой сценарий (страховая, СТО, логистика — любой)
2. Код уходит исполнителю (СМС, мессенджер — как вы обычно общаетесь).
3. Исполнитель вводит код в приложении TrustVisor и снимает.
4. В момент съёмки мы шлём вебхук на ваш адрес (или CRM опрашивает статус кода) → заявка двигается по воронке сама.
5. Полученный файл CRM отправляет на проверку — вердикт о подлинности возвращается за секунды и сам записывается в журнал панели.
Коды на съёмку
Выпустить код
POST https://api.trustvisor.ru/v1/business/case-codes
curl -X POST https://api.trustvisor.ru/v1/business/case-codes \ -H "X-Api-Key: ваш_ключ" \ -H "Content-Type: application/json" \ -d '{"case_id": "ОСАГО-4712", "max_videos": 2, "max_photos": 10}'
Поля запроса (обязателен только case_id — ваш номер заявки/сделки, до 64 символов):
| Поле | Описание |
|---|---|
case_id | Номер вашей заявки — по нему код виден в панели и в вебхуках |
object_name | Объект — адрес, номер точки или склада, до 120 символов. Виден в панели, в отчёте, акте, реестре и исполнителю на странице съёмки по ссылке |
template_id | Шаблон отчёта компании (см. ниже): поля, которых нет в запросе, — пункты, срок, требования к съёмке, объект — берутся из него |
assign_to | Постоянный ключ сотрудника вашей компании (TV-…). Код становится его заданием: сотрудник видит заявку в приложении в «Заданиях» и снимает без ввода кода. В ответе — assigned_to; ключ другой компании — 404, недействующий — 422 |
due_at или due_in_hours | Срок сдачи: момент в ISO 8601 (с поясом — приводится к UTC; без пояса — считается UTC) или «через N часов», от 1 до 720. Не раньше чем через 5 минут и не дальше 30 дней. Не сдано к сроку — заявка помечается «просрочено» и приходит вебхук overdue |
max_videos, max_photos | Лимиты съёмки. Не передали — подставляется потолок 10 видео / 30 фото; значение выше потолка молча уменьшается до него, «без лимита» не бывает |
quality, ratio | Требования к съёмке (качество, соотношение сторон) |
gps_mode | Требование геометки |
require_online | true — съёмка только при живой связи с сервером |
max_duration_seconds | Максимальная длительность видео |
Ответ: {"key": "TV-XXXX-XXXX", "case_id": "…", "object_name": "…", "due_at": "…", "expires_at": "…", …}. Код живёт 24 часа до первого ввода в приложение; дальше срок отсчитывается от активации. Если задан срок сдачи, код действует до него — но не меньше 24 часов от выдачи и от первого ввода.
Узнать статус
GET https://api.trustvisor.ru/v1/business/case-codes/TV-XXXX-XXXX — один код, или без ключа в пути — все коды разом.
{
"key": "TV-XXXX-XXXX",
"case_id": "ОСАГО-4712",
"state": "in_use", // unused | in_use | expired
"captured": true, // съёмка состоялась
"received": false, // вы отметили файл полученным
"object_name": "Склад №5",
"due_at": "2026-10-03T12:00:00", // UTC; null — срока нет
"due_state": null, // после срока: on_time | overdue
"overdue": false, // к сроку не снято, чек-лист не закрыт или висело «доснять»
"videos_used": 1, "max_videos": 2, …
}
Отметить, что файл дошёл до вас: POST /v1/business/case-codes/TV-XXXX-XXXX/mark-received.
Проверка файла
POST https://portal.trustvisor.ru/v1/verify — multipart/form-data, файл в поле package.
curl -X POST https://portal.trustvisor.ru/v1/verify \ -H "X-Api-Key: ваш_ключ" \ -F "package=@REC_20260622_0702.trustvisor"
Код 200 и JSON — если проверка вообще состоялась (в том числе если файл оказался поддельным — это тоже успешный результат проверки, не ошибка запроса). Каждая проверка автоматически попадает в журнал «Проверки» вашей панели.
momentSource): тогда момент известен точно при любой длительности без связи. Уровень доверия как у UNVERIFIED_DEVICE; письмо на почту — по тому же переключателю.moment — момент съёмки в миллисекундах UTC; momentSource — откуда он: anchor (привязка к серверному времени: приложение считает момент от последней связи по счётчику загрузки телефона, часы телефона не участвуют), token (часы телефона в границах серверного подтверждения) или device (только часы телефона). offlineHours — сколько часов телефон был без связи до съёмки (по привязке). deviceClockShiftMin — на сколько минут часы телефона расходились с сервером в момент съёмки (перевод часов виден здесь, на вердикт не влияет). locationMock — во время съёмки работало приложение подмены местоположения; его данные отброшены, координат в файле нет. checks.locationNet — второе мнение о месте (приложение 1.4): координаты по сотовой сети и Wi-Fi против спутниковых; расхождение больше суммы точностей и двух километров — признак подмены сигнала, вердикт UNVERIFIED_DEVICE с причиной location; без покрытия или без спутникового фикса — skip. checks.gnssPortrait — портрет спутникового сигнала (приложение 1.4): спутников в фиксе, созвездия, сила сигнала и её разброс, диапазоны, уровень усиления; сочетание двух и более признаков передатчика (одно созвездие при шести и более спутниках, разброс сигнала меньше 1,5 дБ, ровный и очень сильный сигнал) — причина location, вердикт UNVERIFIED_DEVICE; один признак — только пометка в отчёте. Файлы приложения до версии 1.4 привязки не несут: momentSource у них token или device.Загруженный файл не хранится на сервере дольше самой проверки. Бесплатный браузерный верификатор на trustvisor.ru остаётся доступен без ключа — он работает целиком в браузере и в журнал панели не пишет.
Вебхуки: события в вашу систему
Вместо опроса статусов мы сами отправим POST-запрос на ваш адрес. Вебхук создаётся в панели («Интеграции и API»). По API его создать нельзя: это настройка компании, ей нужен вход в кабинет — API-ключ её не открывает (ответ 403 api_key_not_allowed_here).
Ответ содержит secret — ключ подписи, показывается один раз.
| Событие | Когда приходит | Тело (JSON) |
|---|---|---|
captured | Первая завершённая съёмка по кейс-коду | {"event":"captured","at":"…","key":"TV-…","case_id":"…"} |
verified | Проверка пакета записана в журнал (из панели, по API, при загрузке по коду или при съёмке по ссылке; source: dashboard, api, upload, web-link) | {"event":"verified","at":"…","verdict":"TAMPERED","file_name":"…","source":"api"} |
accepted | Снимок принят в кабинете (при хранении фото для приёмки) | {"event":"accepted","at":"…","media_id":42,"key":"TV-…","case_id":"…","checklist_index":1,"checklist_item":"…","reason":null,"verdict":"TRUSTED_CAPTURE"} |
rework | Снимок отправлен на доснятие; в reason — что доснять словами сотрудника. Пересъёмка пункта закрывает «доснять» сама | {"event":"rework","at":"…","media_id":42,"key":"TV-…","case_id":"…","checklist_index":1,"checklist_item":"…","reason":"Номер не читается","verdict":"TRUSTED_CAPTURE"} |
overdue | Заявка не сдана к сроку due_at: к сроку не было съёмки, чек-лист не закрыт или висело «доснять». Один раз на код, в течение 15 минут после срока | {"event":"overdue","at":"…","key":"TV-…","case_id":"…","object_name":"…","due_at":"…","captured":false,"checklist_total":3,"checklist_done":1} |
schedule_paused | Расписание заданий встало на паузу: ключ сотрудника не действует или шаблон удалён. Задания по нему больше не выпускаются, пока расписание не включат снова | {"event":"schedule_paused","at":"…","schedule_id":7,"template_id":3,"template_name":"Уборка офиса","assign_to":"TV-…","assignee":"Иванов","reason":"assignee_inactive","reason_text":"ключ сотрудника не действует"} |
test | Только по кнопке «Тест» в панели; в список events его не включают — сервер такое значение отбрасывает | {"event":"test","at":"…"} |
Подпись и повторы
Каждый запрос несёт заголовки X-TrustVisor-Event, X-TrustVisor-Delivery (номер доставки) и X-TrustVisor-Signature: sha256=<hex> — HMAC-SHA256 сырого тела запроса вашим секретом. Проверка на Python:
import hashlib, hmac expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest() ok = hmac.compare_digest(expected, request.headers["X-TrustVisor-Signature"])
Ответьте любым кодом 2xx за 6 секунд. Не успели/упали — повторим до 6 раз с нарастающими интервалами (1 мин → 5 мин → 30 мин → 2 ч → 6 ч). Обрабатывайте события идемпотентно: при повторе X-TrustVisor-Delivery тот же.
Ограничения: до 5 вебхуков на компанию; адрес — только внешний https/http (локальные и внутренние адреса не принимаются).
Рецепты для CRM
Битрикс24
Без разработки: роботы Битрикс24 умеют слать исходящие вебхуки, но не умеют добавлять свой заголовок X-Api-Key — поэтому прямой вызов нашего API из робота не собрать. Рабочие пути:
- Через Albato / ApiX-Drive / n8n / Make (см. ниже): робот Битрикса дёргает сценарий связки, сценарий вызывает наш API с ключом и пишет код/вердикт обратно в сделку через REST Битрикса.
- Локальное приложение Битрикс24 (для вашего портала, бесплатно): небольшой скрипт на вашем хостинге, который принимает событие сделки, вызывает наш API и обновляет поле сделки. Наши вебхуки
captured/verifiedон же принимает и двигает стадию.
amoCRM
Salesbot / digital pipeline умеют шаг «отправить вебхук» — тоже без своих заголовков, поэтому схема та же: связка через no-code-платформу или свой мини-обработчик, который держит ключ и ходит в наш API.
1С
Из 1С наш API вызывается штатно, без посредников:
Соединение = Новый HTTPСоединение("api.trustvisor.ru",,,,, Новый ЗащищённоеСоединениеOpenSSL); Запрос = Новый HTTPЗапрос("/v1/business/case-codes"); Запрос.Заголовки.Вставить("X-Api-Key", Ключ); Запрос.Заголовки.Вставить("Content-Type", "application/json"); Запрос.УстановитьТелоИзСтроки("{""case_id"": ""ЗАКАЗ-1042""}"); Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Albato, ApiX-Drive, n8n, Make
Любая платформа связок с шагом «HTTP-запрос с заголовками» подключается за вечер: шаг 1 — триггер вашей CRM, шаг 2 — POST к нам с X-Api-Key, шаг 3 — записать key из ответа в поле сделки. Входящие вебхуки от нас эти платформы принимают штатным триггером «Webhook».
Свой сайт или внутренняя система
Просто HTTP: выпуск кода — один POST, проверка файла — один POST, события — вебхук. Примеры на curl и JavaScript выше подходят без изменений.
Шаблоны отчётов
Шаблон — запись компании: название, пункты чек-листа, срок «через N часов», качество, формат, GPS, лимиты, объект по умолчанию. Его видят все менеджеры компании в кабинете и ваша CRM по API.
| Запрос | Что делает |
|---|---|
GET /v1/business/templates | Список шаблонов компании |
POST /v1/business/templates | Создать: {"name": "Уборка офиса", "checklist": ["Общий вид", "Пол"], "due_in_hours": 24, "quality": "FHD", "object_name": "…"}; до 100 шаблонов |
PUT /v1/business/templates/{id} | Заменить поля шаблона |
DELETE /v1/business/templates/{id} | Убрать в архив — уже выпущенные по нему коды не меняются |
PUT /v1/business/keys/{key}/label | Имя ключа сотрудника: {"label": "Иванов, бригада 2"} — видно в кабинете, архиве, реестре и акте |
Выпуск по шаблону — POST /v1/business/case-codes с template_id; задание сотруднику — тот же запрос с assign_to. В архиве и списке кодов у такого кода — assigned_to, в архиве можно отобрать заявки одного исполнителя (?assignee=TV-…).
Задания по расписанию
Расписание выпускает задание по шаблону сотруднику само — в выбранные дни недели и время по местному часу. Одно задание на день; пропущенные дни не догоняются. Номер заявки — имя шаблона и дата («Уборка офиса · 01.10.2026»), у кода — schedule_id. Ключ сотрудника не действует или шаблон удалён — расписание встаёт на паузу, приходит вебхук schedule_paused и письмо.
| Запрос | Что делает |
|---|---|
GET /v1/business/schedules | Список расписаний: у каждого next_run (UTC) и next_run_local (по поясу расписания), last_issued_on, last_key, на паузе — paused_reason. Там же tz_choices — допустимые пояса |
POST /v1/business/schedules | Создать: {"template_id": 3, "assign_to": "TV-…", "weekdays": [1,2,3,4,5], "time": "08:00", "tz": "Europe/Moscow", "object_name": "…", "starts_on": "2026-10-01", "ends_on": null}. weekdays — 1 (пн) … 7 (вс); пояса — от Europe/Kaliningrad до Asia/Kamchatka; до 200 расписаний |
PUT /v1/business/schedules/{id} | Заменить поля; "active": false — пауза, true — включить (только с действующим ключом сотрудника и живым шаблоном) |
DELETE /v1/business/schedules/{id} | Убрать в архив — уже выпущенные задания не меняются |
Что ещё есть в API
Точки, которых раньше не было в этой документации. Хост у проверки файла — тот же, что у /v1/verify (портал), у остального — api.trustvisor.ru.
| Точка | Что делает | Доступ |
|---|---|---|
POST /v1/verify-by-code?code=TV-… | Проверка файла по коду заявки — без API-ключа и без входа. Файл в поле package, multipart. Удобно отдать исполнителю или подрядчику: страница /upload.html на портале делает то же самое из браузера | сам код заявки |
GET /v1/business/case-codes/{key}/report | Отчёт по заявке: состояние кода, съёмки, проверки. При хранении фото для приёмки — ещё media (снимки заявки: вердикт, время, пункт чек-листа, решение review_status и причина review_reason, пометки dup_case_id — этот же снимок уже сдавался в другой заявке, other_case_id — снят для другой заявки, before_issue — снят раньше, чем выдан код) и rework (пункты «доснять» с причинами). Самих снимков, координат и устройства по API-ключу нет — только в кабинете | API-ключ |
| Акт по заявке (PDF), реестр за период (Excel) | Акт — компания, заявка, объект, сроки, по пунктам — решения и их история, превью, время и место съёмки, отпечатки для сверки в открытом реестре. Реестр — лист «Заявки» и лист «Снимки» за выбранный период. Время — по Москве | Только в кабинете |
checklist в теле выпуска кода | Список пунктов, которые исполнитель отмечает в приложении по ходу съёмки; отметки видны в панели и в отчёте | — |
GET /v1/business/delivery, GET /v1/business/uploads | Настройки доставки и список присланных файлов. Режима доставки два: none — файл остаётся на телефоне, и transit — файл проверяется у нас и тут же уходит в Яндекс.Диск компании, в папку /TrustVisor. Отдельно — хранение фото для приёмки: компания включает его в кабинете на 7, 30 или 90 дней. Фото и кадры-превью видео видны в кабинете в течение срока; решения по снимкам приходят вебхуками accepted («принято») и rework («доснять», с причиной). Видео мы не храним. В ответе — вердикт, отпечаток и путь на вашем Диске, самого файла нет. Поле transit_format задаёт, что именно туда кладётся: package — пакет .trustvisor, media — обычный MP4, PNG или JPEG с подписью внутри (открывается любым плеером и проходит проверку), both — оба файла рядом. Менять настройки — только из кабинета | API-ключ — чтение |
Ошибки
| Код | Значение |
|---|---|
| 401 | Не передан X-Api-Key, либо ключ неверный/отозван |
| 400 | Запрос не удалось разобрать; для вебхуков — недопустимый адрес или превышен лимит 5 вебхуков |
402/403 client_plan_required | Коды на съёмку доступны только на тарифе Business |
403 api_key_not_allowed_here | Операции нужен вход в личный кабинет — API-ключ её не открывает: покупка ключей, настройка доставки, удаление застрявшего файла, создание и удаление вебхуков, история платежей |
| 404 | Код или вебхук не найден (или принадлежит другой компании) |
| 413 | Файл слишком большой |
| 422 | Файл отклонён как подозрительный до полной проверки |
| 429 | Превышен лимит запросов: выпуск кодов — 30/мин; все точки портала, включая проверку файла, — 20 запросов/мин с одного адреса |
Нужна помощь с интеграцией — напишите на info@trustvisor.ru, поможем собрать связку под вашу систему.