Руководство по интеграции
Интеграция с Backend API (без данных)#
1. Что такое RS-ID Backend API#
RS-ID Backend API — интеграция сервер-сервер. Ваш бэкенд отправляет фотографии лица напрямую в RS-ID и получает результат сравнения. При необходимости данные гражданина проверяются по государственному реестру Республики Узбекистан.Без данных. В этой интеграции RS-ID возвращает только результат сравнения — оценку сходства и причину неудачи. Персональные данные гражданина (ФИО, документ, адрес) после идентификации не возвращаются.
Страницы RS-ID и SDK здесь нет. Вы делаете фото в своём приложении или на сайте, а ваш бэкенд обращается к RS-ID. RS-ID:1.
по желанию проверяет, что на каждом фото живой человек, а не фото, экран или маска (анти-спуфинг);
2.
сравнивает лица: либо фото пользователя с фото из паспорта из государственного реестра, либо два присланных вами фото;
3.
возвращает оценку сходства и причину неудачи, если она есть. Персональные данные гражданина не возвращаются.
Сценарии использования#
| Сценарий | Пример |
|---|
| Идентификация в вашем собственном интерфейсе | Банк делает селфи в своём приложении и сверяет его с фото из паспорта из реестра. |
| Проверки в офисе / киоске / колл-центре | Система оператора отправляет фото, сделанное в офисе или киоске. |
| Сверка селфи с фото документа | Сравнение селфи пользователя с фото из отсканированной ID-карты. |
| Сверка двух фото | Проверка, что на двух фото один человек, например новое селфи и селфи, сохранённое при регистрации. |
| Пакетные проверки / бэк-офис | Повторная проверка существующих клиентов из вашей системы. |
2. Терминология#
| Термин | Кто это |
|---|
| Клиент | Компания, которая интегрирует RS-ID (вы). Зарегистрирована в RS-ID и получила client_id / client_secret для Backend API. К RS-ID обращается только бэкенд клиента. |
| Пользователь | Человек, лицо которого проверяется, — ваш клиент, гражданин Узбекистана. |
| Сервер | Сервер RS-ID: Backend API (<rsid_base_url>). |
| Сессия | Один запрос на сравнение. Каждый вызов сравнения создаёт новую сессию и возвращает её session_id (UUID). По нему получают результат. |
| Исходное / эталонное фото | Два фото, которые сравниваются в Вариантах 2 и 3: фото пользователя и фото, с которым его сравнивают. |
| ПИНФЛ | Персональный идентификационный номер физического лица — 14 цифр. |
Номер документа (id_number) | Серия и номер паспорта или ID-карты, например AA1234567. |
3. Варианты интеграции#
Выберите вариант в зависимости от того, что нужно сравнить. Все три работают асинхронно и возвращают session_id; результат всегда получают через 7.6 Получение результата.| Вариант | Endpoint | Что сравнивается | user_info |
|---|
| Вариант 1 | POST /v1/authentication/async/compare | Одно фото пользователя ↔ фото из паспорта гражданина из реестра | Обязательно |
| Вариант 2 | POST /v1/authentication/async/compare-images | Два фото, присланных клиентом | Обязательно |
| Вариант 3 | POST /v1/face/async/compare-images | Два фото, присланных клиентом | Не используется |
1.
Ваш бэкенд проходит авторизацию (7.1).
2.
Вызывает один из вариантов (7.3–7.5).
3.
Если результат готов в течение 3 секунд, в ответе code = 0. Иначе code = -200 (ещё обрабатывается). В обоих случаях в data возвращается session_id.
4.
Ваш бэкенд получает результат через GET /v1/user/{session_id} (7.6).
4. Схема интеграции#
5. Окружения#
| Окружение | Базовый URL API |
|---|
| Stage (тестовое) | https://stage.rsid.uz/backend/api |
| Production | https://rsid.uz/backend/api |
Для stage и production используются разные client_id / client_secret. Учётные данные Backend API отличаются от учётных данных Web и Mobile SDK — клиент SDK не может вызывать методы сравнения (-1002).
6. Общие правила#
Формат ответа#
Все ответы API имеют одинаковую структуру:{ "data": { }, "code": 0, "message": "Success" }
| Поле | Тип | Описание |
|---|
code | integer | 0 — успех. Любое другое значение — ошибка или состояние (см. таблицы ошибок). Всегда проверяйте code, а не только HTTP-статус. |
message | string | Текст на языке запроса (uz / ru / en). Не разбирайте его программно. |
data | any | Данные ответа. Отсутствует при ошибке. |
Заголовки#
| Заголовок | Значение | Где используется |
|---|
Content-Type | application/json | Все POST-запросы |
Authorization | Bearer {access_token} | Все запросы, кроме sign-in и refresh |
Idempotency-Key | UUID, новый для каждого запроса | Обязателен для методов сравнения (7.3–7.5) |
Accept-Language | uz / ru / en | Необязательно — язык поля message |
Idempotency-Key. Генерируйте новый UUID для каждого запроса на сравнение. Если повторить запрос с тем же ключом в течение 5 минут, RS-ID вернёт сохранённый ответ первого запроса, а не запустит новое сравнение, — это позволяет безопасно повторять запрос после сетевой ошибки. Повтор, пока первый запрос ещё выполняется, возвращает HTTP 409. Без ключа возвращается HTTP 400.
Фотографии#
Передавайте фото строкой base64, без префикса data:image/...;base64,.
Используйте чёткое фронтальное фото одного лица. JPEG или PNG.
Размер всего запроса — не более 20 МБ.
7. Описание API#
7.1 Авторизация (Sign in)#
Обменивает учётные данные клиента на токен доступа.Метод - POST
Endpoint - {base_url}/v1/auth/sign-in — без заголовка Authorization
Content-Type (заголовок) - application/json| Поле | Тип | Обязательно | Длина / формат | Описание |
|---|
client_id | string | Да | Не пустое; не может начинаться с цифры | Идентификатор клиента Backend API, выданный RS-ID. |
client_secret | string | Да | Не пустое | Секрет клиента, выданный RS-ID. |
{
"client_id": "backend-api-client",
"client_secret": "s3cr3t-value"
}
| Поле | Тип | Описание |
|---|
data.access_token | string (JWT) | Токен для заголовка Authorization: Bearer. |
data.token_type | string | Всегда Bearer. |
data.expires_in | integer | Срок жизни токена в секундах. |
data.scope | string | Выданные права, через пробел. |
data.refresh_token | string (JWT) | Токен для получения нового access_token без повторной отправки учётных данных. |
code | integer | 0 при успехе. |
message | string | Текст результата. |
{
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "read write",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
},
"code": 0,
"message": "Success"
}
Используйте access_token повторно до истечения срока, а не авторизуйтесь заново для каждого запроса.
7.2 Обновление токена (Refresh token)#
Выдаёт новый access_token по refresh_token без повторной авторизации. Вызывайте, когда access_token истёк (через expires_in секунд).Метод - POST
Endpoint - {base_url}/v1/auth/refresh?token={refresh_token} — без заголовка Authorization.
Content-Type (заголовок) - application/json| Поле | Тип | Обязательно | Длина / формат | Описание |
|---|
token | string | Да | JWT | refresh_token из авторизации (7.1) или из предыдущего ответа обновления. |
| Поле | Тип | Обязательно | Длина / формат | Описание |
|---|
client_id | string | Да | Не пустое; не может начинаться с цифры | Идентификатор клиента Backend API, выданный RS-ID. |
client_secret | string | Да | Не пустое | Секрет клиента, выданный RS-ID. |
{
"client_id": "backend-api-client",
"client_secret": "s3cr3t-value"
}
| Поле | Тип | Описание |
|---|
data.access_token | string (JWT) | Новый токен для заголовка Authorization: Bearer. |
data.token_type | string | Всегда Bearer. |
data.expires_in | integer | Срок жизни токена в секундах. |
data.scope | string | Выданные права, через пробел. |
data.refresh_token | string (JWT) | Новый refresh-токен для следующего обновления. |
code | integer | 0 при успехе. |
message | string | Текст результата. |
{
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "read write",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
},
"code": 0,
"message": "Success"
}
Если refresh-токен истёк или недействителен, авторизуйтесь заново (7.1).
7.3 Вариант 1 — Сравнение фото с фото из паспорта#
Сравнивает одно фото пользователя с фото из паспорта гражданина из государственного реестра. RS-ID находит гражданина по user_info, берёт его фото из паспорта и данные и сравнивает лица.Метод - POST
Endpoint - {base_url}/v1/authentication/async/compare
Authorization (заголовок) - Bearer {access_token}
Idempotency-Key (заголовок) - {uuid}
Content-Type (заголовок) - application/json| Поле | Тип | Обязательно | Длина / формат | Описание |
|---|
photo | string | Да | Base64 | Фото пользователя (селфи). |
is_spoofing_required | boolean | Нет | true / false | Выполнить проверку «живости» (анти-спуфинг) для фото. По умолчанию false. Для живых селфи рекомендуется true. |
user_info | object | Да | — | Данные гражданина, по которым ищется фото из паспорта. |
user_info.pinfl | string | Условно | Ровно 14 цифр | ПИНФЛ. Передавайте либо pinfl, либо id_number, но не оба. |
user_info.id_number | string | Условно | 9 символов: 2 буквы + 7 цифр, например AA1234567 | Номер паспорта / ID-карты. Передавайте либо pinfl, либо id_number, но не оба. |
user_info.birth_date | string | Да, если передан user_info | dd.MM.yyyy | Дата рождения. Пользователю должно быть не меньше 16 лет. |
threshold | number | Нет | 0.0 – 1.0 | Минимальный порог сходства лиц для прохождения. По умолчанию 0.5. См. примечание ниже. |
external_id | string | Нет | — | Ваш собственный идентификатор для связи запроса с вашими данными. Рекомендуется случайный uuid. |
locale | string (enum) | Нет | UZ, RU, EN | По умолчанию UZ. |
Порог (threshold). threshold — минимальная оценка сходства лиц (от 0.0 до 1.0), при которой сравнение считается пройденным. Если параметр не передан, используется значение по умолчанию 0.5. Если вы передаёте его сами, рекомендуем значение выше 0.5. Для высокоточной (строгой) идентификации передавайте значение выше 0.7. Чем выше значение, тем строже проверка и ниже риск, что пройдёт другой человек, но настоящие пользователи могут чаще не проходить проверку.
{
"photo": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8U...",
"is_spoofing_required": true,
"user_info": {
"pinfl": "12345678901234",
"birth_date": "01.01.1990"
},
"threshold": 0.7,
"external_id": "9b1d2c7e-4f3a-4b8e-a1c5-6d2f0e9a7b31",
"locale": "UZ"
}
С номером документа вместо ПИНФЛ:"user_info": { "id_number": "AA1234567", "birth_date": "01.01.1990" }
| Поле | Тип | Длина / формат | Описание |
|---|
data | string | UUID, 36 символов | session_id этого сравнения. Используйте его в 7.6. |
code | integer | | 0 — завершено; -200 — ещё обрабатывается. Любое другое значение — ошибка. |
message | string | | Текст результата. |
{
"data": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"code": 0,
"message": "Success"
}
Ещё обрабатывается (результат будет доступен в 7.6):{
"data": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"code": -200,
"message": "Waiting for async process"
}
Ответ — это не вердикт. code = 0 означает, что сравнение завершено, а не что лица совпали или фото живое. Всегда получайте результат через 7.6 и проверяйте comparison_value и note.
| Код | Причина |
|---|
-1000 | Некорректный запрос — например, нет user_info, переданы оба поля pinfl / id_number или ни одного; гражданин не найден в реестре. |
-1002 | Учётные данные не принадлежат клиенту Backend API. |
-1024 | Неверный формат id_number. |
-1025 | Неверный формат pinfl. |
-1026 | Не передан birth_date. |
-1052 | threshold вне диапазона 0–1. |
-1090 | Пользователю меньше 16 лет. |
-2001 | Ошибка сервиса распознавания лиц. |
400 | Ошибка валидации поля (например, photo cannot be blank) или не передан заголовок Idempotency-Key. |
409 (HTTP) | Запрос с тем же Idempotency-Key ещё выполняется. |
7.4 Вариант 2 — Сравнение двух фото с данными гражданина#
Сравнивает два фото, присланных клиентом, между собой. Гражданин определяется по user_info.Метод - POST
Endpoint - {base_url}/v1/authentication/async/compare-images
Authorization (заголовок) - Bearer {access_token}
Idempotency-Key (заголовок) - {uuid}
Content-Type (заголовок) - application/json| Поле | Тип | Обязательно | Длина / формат | Описание |
|---|
original_photo | object | Да | — | Первое фото, например живое селфи пользователя. |
original_photo.photo | string | Да | Base64 | Данные фото. |
original_photo.is_spoofing_required | boolean | Нет | true / false | Выполнить проверку «живости» для этого фото. По умолчанию false. Для живого селфи рекомендуется true. |
original_photo.order | integer | Нет | — | Порядковый номер фото. |
reference_photo | object | Да | — | Второе фото для сравнения, например фото документа или сохранённое селфи. |
reference_photo.photo | string | Да | Base64 | Данные фото. |
reference_photo.is_spoofing_required | boolean | Нет | true / false | Выполнить проверку «живости» для этого фото. По умолчанию false. Для фото документа оставьте false. |
reference_photo.order | integer | Нет | — | Порядковый номер фото. |
user_info | object | Да | — | Данные гражданина. Правила те же, что в 7.3. |
user_info.pinfl | string | Условно | Ровно 14 цифр | ПИНФЛ. Передавайте либо pinfl, либо id_number. |
user_info.id_number | string | Условно | 9 символов: 2 буквы + 7 цифр | Номер паспорта / ID-карты. |
user_info.birth_date | string | Да, если передан user_info | dd.MM.yyyy | Дата рождения. Пользователю должно быть не меньше 16 лет. |
threshold | number | Нет | 0.0 – 1.0 | По умолчанию 0.5. Рекомендуется выше 0.5, для строгого сравнения — выше 0.7. |
external_id | string | Нет | — | Ваш собственный идентификатор. Рекомендуется случайный uuid. |
locale | string (enum) | Нет | UZ, RU, EN | По умолчанию UZ. |
{
"original_photo": {
"order": 1,
"is_spoofing_required": true,
"photo": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8U..."
},
"reference_photo": {
"order": 2,
"is_spoofing_required": false,
"photo": "iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAACXBIWXMAAAsTAAALEwEAmpwY..."
},
"user_info": {
"pinfl": "12345678901234",
"birth_date": "01.01.1990"
},
"threshold": 0.7,
"external_id": "c4e8a1f2-7b3d-4e6a-9f0c-2b5d8e1a4c77"
}
Ответ — как в 7.3: data = session_id, code = 0 (завершено) или -200 (ещё обрабатывается). Результат получайте через 7.6.{
"data": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"code": 0,
"message": "Success"
}
Ошибки — как в 7.3, а также:| Код | Причина |
|---|
400 | Не передано original_photo или reference_photo (original photo should be exist, reference photo should be exist). |
7.5 Вариант 3 — Сравнение двух фото без данных гражданина#
Сравнивает два фото, присланных клиентом, без каких-либо данных гражданина. Обращения к реестру нет.Метод - POST
Endpoint - {base_url}/v1/face/async/compare-images
Authorization (заголовок) - Bearer {access_token}
Idempotency-Key (заголовок) - {uuid}
Content-Type (заголовок) - application/json| Поле | Тип | Обязательно | Длина / формат | Описание |
|---|
original_photo | object | Да | — | Первое фото. |
original_photo.photo | string | Да | Base64 | Данные фото. |
original_photo.is_spoofing_required | boolean | Нет | true / false | Выполнить проверку «живости» для этого фото. По умолчанию false. |
original_photo.order | integer | Нет | — | Порядковый номер фото. |
reference_photo | object | Да | — | Второе фото. |
reference_photo.photo | string | Да | Base64 | Данные фото. |
reference_photo.is_spoofing_required | boolean | Нет | true / false | Выполнить проверку «живости» для этого фото. По умолчанию false. |
reference_photo.order | integer | Нет | — | Порядковый номер фото. |
threshold | number | Нет | 0.0 – 1.0 | По умолчанию 0.5. Рекомендуется выше 0.5, для строгого сравнения — выше 0.7. |
external_id | string | Нет | — | Ваш собственный идентификатор. Рекомендуется случайный uuid. |
locale | string (enum) | Нет | UZ, RU, EN | По умолчанию UZ. |
{
"original_photo": {
"order": 1,
"is_spoofing_required": true,
"photo": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8U..."
},
"reference_photo": {
"order": 2,
"is_spoofing_required": false,
"photo": "/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODww..."
},
"threshold": 0.7,
"external_id": "e2a7c9d4-1b6f-4a3e-8c5d-7f0b2e9a6d18"
}
Ответ — как в 7.3: data = session_id, code = 0 (завершено) или -200 (ещё обрабатывается). Результат получайте через 7.6.{
"data": "b7c2e1f0-9a8d-4c6b-b5e4-3d2c1b0a9f8e",
"code": 0,
"message": "Success"
}
| Код | Причина |
|---|
-1002 | Учётные данные не принадлежат клиенту Backend API. |
-1052 | threshold вне диапазона 0–1. |
-2001 | Ошибка сервиса распознавания лиц. |
400 | Не передано фото или фото не в формате base64, либо не передан заголовок Idempotency-Key. |
409 (HTTP) | Запрос с тем же Idempotency-Key ещё выполняется. |
7.6 Получение результата#
Бэкенд клиента получает результат сравнения по его session_id — для всех трёх вариантов. В результате только session_id, comparison_value и note; персональные данные гражданина не возвращаются.Метод - GET
Endpoint - {base_url}/v1/user/{session_id}
Authorization (заголовок) - Bearer {access_token}| Поле | Тип | Обязательно | Длина / формат | Описание |
|---|
session_id | string | Да | UUID, 36 символов | data из ответа на сравнение (7.3–7.5). |
| Поле | Значение |
|---|
comparison_value | Оценка сходства лиц, 0–1. Сравните её со своим threshold. |
note | Пусто при чистом прохождении. Иначе содержит причину — например Spoofed file detected («живость» не подтверждена) или Face match failed (оценка ниже порога). |
Правило прохождения. Считайте проверку пройденной, только если comparison_value ≥ вашего threshold и note пустое. При is_spoofing_required: true подделка фото не возвращает ошибку в методе сравнения — она отображается здесь, в поле note.
| Поле | Тип | Описание |
|---|
data.session_id | string | Идентификатор сессии. |
data.comparison_value | number | Оценка сходства лиц, 0–1. |
data.note | string | Причина неудачи, если есть. |
{
"data": {
"session_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"comparison_value": 0.93
},
"code": 0,
"message": "Success"
}
| Код | Причина |
|---|
-1002 | Сессия принадлежит другому клиенту. |
-1005 | Сравнение не завершилось успешно. Если метод сравнения только что вернул -200, подождите 1–2 секунды и повторите запрос. |
-1027 | Сессия истекла — запрашивайте результат сразу после сравнения. |
-1029 | Сессия не найдена. |
8. Коды ошибок#
| Код | Название | Значение |
|---|
0 | SUCCESS | Успех. |
-5 | BAD_CREDENTIALS | Неверные учётные данные или пользователь токена не найден. |
-9 | SYSTEM_ERROR | Непредвиденная ошибка сервера. |
-200 | WAITING_ASYNC_PROCESS | Ещё обрабатывается — получите результат через 7.6. |
-1000 | BAD_REQUEST | Некорректный запрос. |
-1002 | CLIENT_NOT_PERMITTED | Недоступно для этого клиента. |
-1005 | UNSUCCESS_JOB | Сравнение не завершилось успешно. |
-1024 | INVALID_ID_NUMBER | Неверный номер документа. |
-1025 | INVALID_PINFL | Неверный ПИНФЛ. |
-1026 | BIRTH_DATE_NOT_NULL | Требуется дата рождения. |
-1027 | SESSION_EXPIRED | Сессия истекла. |
-1029 | JOB_SESSION_NOT_FOUND | Сессия не найдена. |
-1052 | INVALID_THRESHOLD_LIMIT | threshold вне диапазона 0–1. |
-1090 | USER_AGE_OLDER_THAN_16 | Пользователю должно быть не меньше 16 лет. |
-2001 | AI_ERROR | Ошибка сервиса распознавания лиц. |
Modified at 2026-11-10 07:05:24