1. Backend with information
RSID docs
English
  • English
  • Russian
  • Uzbek
  • Integration Overview
  • Web SDK
    • Usage guide
    • sign-in
      POST
    • refresh
      POST
    • create-session
      POST
    • user-info
      GET
  • Mobile SDK
    • Usage guide
    • sign-in
      POST
    • refresh
      POST
    • create-session
      POST
    • user
      GET
  • Backend with information
    • Usage guide
    • sign-in
      POST
    • refresh
      POST
    • Option 1 — compare photo with passport photo
      POST
    • Option 2 — compare two photos with citizen data
      POST
    • Option 3 — compare two photos without citizen data
      POST
    • Get result
      GET
  • Backend without information
    • Usage guide
    • sign-in
      POST
    • refresh
      POST
    • Option 1 — compare photo with passport photo
      POST
    • Option 2 — compare two photos with citizen data
      POST
    • Option 3 — compare two photos without citizen data
      POST
  • Auth and Qr identification
    • Sign with RS-ID (Oauth2 style)
    • Qr Sign/Identification process
    • Get user info by code
      POST
    • sign-in
      POST
    • refresh
      POST
    • Create a QR token
      POST
    • Get QR token status by qr_id
      GET
    • Get QR token status by external_id
      GET
  • Schemas
    • ErrorResponse
    • AuthCodeRequest
    • ClientCredentials
    • Token
    • UserInfo
    • TokenResponseEnvelope
    • DocumentInfo
    • Signer
    • StringResponseEnvelope
    • ContactInfo
    • CallbackEvent
    • UserProfile
    • QrTokenCreateRequest
    • PhotoItem
    • Address
    • UserProfileResponseEnvelope
    • AdditionalParams
    • WebSessionCreateRequest
    • QrToken
    • UserProfileResponse
    • CompareFaceRequest
    • UserResponseEnvelope
    • CompareImagesWithInfoRequest
    • QrTokenResponseEnvelope
    • CompareImagesRequest
    • SignCallback
    • ComparisonResult
    • MobileSessionCreateRequest
    • ComparisonResultEnvelope
  1. Backend with information

Usage guide

Integration with Backend API#

1. What is RS-ID Backend API#

RS-ID Backend API is a server-to-server integration. Your backend sends face photos directly to RS-ID and gets back the comparison result and, when you send citizen data, the verified citizen profile from the national identity registry of Uzbekistan.
There is no RS-ID page or SDK. You take the photos in your own app or site, and your backend calls to RS-ID:
1.
optionally checks that each photo is a live person, not a photo, screen or mask (anti-spoofing);
2.
compares the faces: either the user's photo with their passport photo from the government registry, or two photos you send;
3.
returns the similarity score and, when citizen data was sent, the verified citizen profile.

Use cases#

Use caseExample
Identification inside your own UIA bank takes the selfie in its own app and checks it against the passport photo from the registry.
Branch / kiosk / call-center checksAn operator's system sends the photo taken at the branch or kiosk.
Matching a selfie with a document photoComparing the user's selfie with the photo from a scanned ID card.
Matching two photosChecking that two photos show the same person, e.g. a new selfie against one saved at registration.
Batch or back-office checksRe-verifying existing customers from your own system.

2. Terminology#

TermWho it is
ClientThe company integrating RS-ID (you). Registered in RS-ID and issued a client_id / client_secret for Backend API. Only the client backend calls RS-ID.
UserThe person whose face is checked — your customer, a citizen of Uzbekistan.
ServerThe RS-ID server: the Backend API (<rsid_base_url>).
SessionOne comparison request. Every compare call creates a new session and returns its session_id (UUID). Use it to get the result.
Original / reference photoThe two photos compared in Options 2 and 3: the user's photo and the photo to compare it with.
PINFLPersonal identification number of an individual — 14 digits.
Document number (id_number)Passport or ID card series and number, e.g. AA1234567.

3. Integration options#

Choose the option that matches what you need to compare. All three are asynchronous and return a session_id; the result is always taken with 7.6 Get result.
OptionEndpointWhat is compareduser_infoCitizen profile in the result
Option 1POST /v1/authentication/async/compareOne user photo ↔ the citizen's passport photo from the registryRequiredYes
Option 2POST /v1/authentication/async/compare-imagesTwo photos sent by the clientRequiredYes
Option 3POST /v1/face/async/compare-imagesTwo photos sent by the clientNot usedNo — only the score
Common flow:
1.
Your backend signs in (7.1).
2.
It calls one of the options (7.3–7.5).
3.
If the result is ready within 3 seconds, the response has code = 0. Otherwise it has code = -200 (still processing). Both responses carry the session_id in data.
4.
Your backend gets the result with GET /v1/user/{session_id} (7.6).

4. Integration diagram#

integration-flow-backend-api.png

5. Environments#

EnvironmentAPI base URL
Stage (testing)https://stage.rsid.uz/backend/api
Productionhttps://rsid.uz/backend/api
Stage and production use different client_id / client_secret. Backend API credentials are separate from Web and Mobile SDK credentials — an SDK client cannot call the compare endpoints (-1002).

6. General rules#

Response envelope#

Every API response has the same structure:
{ "data": { }, "code": 0, "message": "Success" }
FieldTypeDescription
codeinteger0 — success. Any other value is an error or a state (see the error tables). Always check code, not only the HTTP status.
messagestringHuman-readable text in the request language (uz / ru / en). Do not parse it.
dataanyResponse payload. Absent on errors.

Headers#

HeaderValueUsed in
Content-Typeapplication/jsonAll POST requests
AuthorizationBearer {access_token}All requests except sign-in and refresh
Idempotency-KeyUUID, new for every requestRequired for the compare endpoints (7.3–7.5)
Accept-Languageuz / ru / enOptional — language of message
Idempotency-Key. Generate a new UUID for every compare request. If you repeat a request with the same key within 5 minutes, RS-ID returns the saved response of the first request instead of running a new comparison — useful for safe retries after a network error. A repeat while the first request is still running returns HTTP 409. A missing key returns HTTP 400.

Photos#

Send photos as base64 strings, without the data:image/...;base64, prefix.
Use a clear, front-facing photo of one face. JPEG or PNG.
The whole request must not exceed 20 MB.

7. API definitions#

7.1 Sign in#

Exchanges client credentials for an access token.
Method - POST
Endpoint - {base_url}/v1/auth/sign-in — no Authorization header
Content-Type (Headers) - application/json

Request body
FieldTypeRequiredLength / formatDescription
client_idstringYesNon-empty; must not start with a digitBackend API client identifier issued by RS-ID.
client_secretstringYesNon-emptyClient secret issued by RS-ID.
{
  "client_id": "backend-api-client",
  "client_secret": "s3cr3t-value"
}
Response
FieldTypeDescription
data.access_tokenstring (JWT)Token for the Authorization: Bearer header.
data.token_typestringAlways Bearer.
data.expires_inintegerToken lifetime in seconds.
data.scopestringGranted scopes, space-separated.
data.refresh_tokenstring (JWT)Token to get a new access_token without sending credentials again.
codeinteger0 on success.
messagestringResult text.
{
  "data": {
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "token_type": "Bearer",
    "expires_in": 3600,
    "scope": "read write",
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  },
  "code": 0,
  "message": "Success"
}
Reuse the access_token until it expires instead of signing in for every request.

7.2 Refresh token#

Gets a new access_token with the refresh_token, without sending a new sign-in. Call it when the access_token has expired (after expires_in seconds).
Method - POST
Endpoint - {base_url}/v1/auth/refresh?token={refresh_token} — no Authorization header.
Content-Type (Headers) - application/json

Query parameters
FieldTypeRequiredLength / formatDescription
tokenstringYesJWTrefresh_token from the sign-in (7.1) or a previous refresh response.
Request body
FieldTypeRequiredLength / formatDescription
client_idstringYesNon-empty; must not start with a digitBackend API client identifier issued by RS-ID.
client_secretstringYesNon-emptyClient secret issued by RS-ID.
{
  "client_id": "backend-api-client",
  "client_secret": "s3cr3t-value"
}
Response
FieldTypeDescription
data.access_tokenstring (JWT)New token for the Authorization: Bearer header.
data.token_typestringAlways Bearer.
data.expires_inintegerToken lifetime in seconds.
data.scopestringGranted scopes, space-separated.
data.refresh_tokenstring (JWT)New refresh token. Use it for the next refresh.
codeinteger0 on success.
messagestringResult text.
{
  "data": {
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "token_type": "Bearer",
    "expires_in": 3600,
    "scope": "read write",
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  },
  "code": 0,
  "message": "Success"
}
If the refresh token is expired or invalid, sign in again (7.1).

7.3 Option 1 — Compare a photo with the passport photo#

Compares one user photo with the citizen's passport photo from the government registry. RS-ID finds the citizen by user_info, takes their passport photo and data, and compares the faces.
Method - POST
Endpoint - {base_url}/v1/authentication/async/compare
Authorization (Headers) - Bearer {access_token}
Idempotency-Key (Headers) - {uuid}
Content-Type (Headers) - application/json

Request body
FieldTypeRequiredLength / formatDescription
photostringYesBase64The user's photo (selfie).
is_spoofing_requiredbooleanNotrue / falseRun the liveness (anti-spoofing) check on the photo. Default false. Recommended true for live selfies.
user_infoobjectYes—Citizen data used to find the passport photo.
user_info.pinflstringConditionalExactly 14 digitsPINFL. Send either pinfl or id_number, not both.
user_info.id_numberstringConditional9 chars: 2 letters + 7 digits, e.g. AA1234567Passport / ID card number. Send either pinfl or id_number, not both.
user_info.birth_datestringYes, if user_info is sentdd.MM.yyyyDate of birth. User must be at least 16 years old.
thresholdnumberNo0.0 – 1.0Minimum face-similarity score to pass. Default 0.5. See the note below.
external_idstringNo—Your own reference to link the request to your records. Recommended random uuid.
localestring (enum)NoUZ, RU, ENDefault UZ.
Threshold. threshold is the minimum face-similarity score (from 0.0 to 1.0) for the comparison to pass. If you don't send it, the default 0.5 is used. If you do send it, we recommend a value above 0.5. For high-quality (strict) identification, send a value above 0.7. A higher value is stricter and lowers the risk of a wrong person passing, but genuine users may fail more often.
Request example
{
  "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"
}
Using a document number instead of PINFL:
"user_info": { "id_number": "AA1234567", "birth_date": "01.01.1990" }
Response
FieldTypeLength / formatDescription
datastringUUID, 36 charssession_id of this comparison. Use it in 7.6.
codeinteger0 — finished; -200 — still processing. Any other value — error.
messagestringResult text.
{
  "data": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "code": 0,
  "message": "Success"
}
Still processing (the result will be available in 7.6):
{
  "data": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "code": -200,
  "message": "Waiting for async process"
}
The response is not the verdict. code = 0 means the comparison has finished, not that the faces matched or the photo is live. Always read the result with 7.6 and check comparison_value and note.
Errors
CodeReason
-1000Invalid request — e.g. no user_info, or both / neither of pinfl / id_number; citizen not found in the registry.
-1002Credentials do not belong to a Backend API client.
-1024Invalid id_number format.
-1025Invalid pinfl format.
-1026birth_date is missing.
-1052threshold outside 0–1.
-1090User is younger than 16.
-2001Face service error.
400Field validation error (e.g. photo cannot be blank), or Idempotency-Key header missing.
409 (HTTP)A request with the same Idempotency-Key is still being processed.

7.4 Option 2 — Compare two photos with citizen data#

Compares two photos sent by the client with each other. The citizen is identified by user_info, so the result also contains the verified citizen profile from the registry.
Method - POST
Endpoint - {base_url}/v1/authentication/async/compare-images
Authorization (Headers) - Bearer {access_token}
Idempotency-Key (Headers) - {uuid}
Content-Type (Headers) - application/json

Request body
FieldTypeRequiredLength / formatDescription
original_photoobjectYes—The first photo, e.g. the user's live selfie.
original_photo.photostringYesBase64Photo data.
original_photo.is_spoofing_requiredbooleanNotrue / falseRun the liveness check on this photo. Default false. Recommended true for a live selfie.
original_photo.orderintegerNo—Order of the photo.
reference_photoobjectYes—The second photo to compare with, e.g. a document photo or a saved selfie.
reference_photo.photostringYesBase64Photo data.
reference_photo.is_spoofing_requiredbooleanNotrue / falseRun the liveness check on this photo. Default false. Keep false for document photos.
reference_photo.orderintegerNo—Order of the photo.
user_infoobjectYes—Citizen data. Same rules as in 7.3.
user_info.pinflstringConditionalExactly 14 digitsPINFL. Send either pinfl or id_number.
user_info.id_numberstringConditional9 chars: 2 letters + 7 digitsPassport / ID card number.
user_info.birth_datestringYes, if user_info is sentdd.MM.yyyyDate of birth. User must be at least 16.
thresholdnumberNo0.0 – 1.0Default 0.5. Recommended above 0.5, above 0.7 for strict comparison.
external_idstringNo—Your own reference. Recommended random uuid.
localestring (enum)NoUZ, RU, ENDefault UZ.
Request example
{
  "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"
}
Response — same as 7.3: data = session_id, code = 0 (finished) or -200 (still processing). Read the result with 7.6.
{
  "data": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "code": 0,
  "message": "Success"
}
Errors — same as 7.3, plus:
CodeReason
400original_photo or reference_photo missing (original photo should be exist, reference photo should be exist).

7.5 Option 3 — Compare two photos without citizen data#

Compares two photos sent by the client without any citizen data. No registry lookup is made, so the result has only the similarity score — no citizen profile.
Method - POST
Endpoint - {base_url}/v1/face/async/compare-images
Authorization (Headers) - Bearer {access_token}
Idempotency-Key (Headers) - {uuid}
Content-Type (Headers) - application/json

Request body
FieldTypeRequiredLength / formatDescription
original_photoobjectYes—The first photo.
original_photo.photostringYesBase64Photo data.
original_photo.is_spoofing_requiredbooleanNotrue / falseRun the liveness check on this photo. Default false.
original_photo.orderintegerNo—Order of the photo.
reference_photoobjectYes—The second photo.
reference_photo.photostringYesBase64Photo data.
reference_photo.is_spoofing_requiredbooleanNotrue / falseRun the liveness check on this photo. Default false.
reference_photo.orderintegerNo—Order of the photo.
thresholdnumberNo0.0 – 1.0Default 0.5. Recommended above 0.5, above 0.7 for strict comparison.
external_idstringNo—Your own reference. Recommended random uuid.
localestring (enum)NoUZ, RU, ENDefault UZ.
Request example
{
  "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"
}
Response — same as 7.3: data = session_id, code = 0 (finished) or -200 (still processing). Read the result with 7.6.
{
  "data": "b7c2e1f0-9a8d-4c6b-b5e4-3d2c1b0a9f8e",
  "code": 0,
  "message": "Success"
}
Errors
CodeReason
-1002Credentials do not belong to a Backend API client.
-1052threshold outside 0–1.
-2001Face service error.
400A photo is missing or not valid base64, or Idempotency-Key header missing.
409 (HTTP)A request with the same Idempotency-Key is still being processed.

7.6 Get result#

The client backend gets the result of a comparison by its session_id — for all three options.
Method - GET
Endpoint - {base_url}/v1/user/{session_id}
Authorization (Headers) - Bearer {access_token}

Path parameters
FieldTypeRequiredLength / formatDescription
session_idstringYesUUID, 36 charsdata from the compare response (7.3–7.5).
How to read the result
FieldMeaning
comparison_valueFace-similarity score, 0–1. Compare it with your threshold.
noteEmpty on a clean pass. Contains the reason otherwise — e.g. Spoofed file detected (liveness failed) or Face match failed (score below threshold).
profileVerified citizen profile. Returned only for Options 1 and 2, and only when comparison_value ≥ threshold. Never returned for Option 3.
Pass rule. Treat the check as passed only when comparison_value ≥ your threshold and note is empty. With is_spoofing_required: true, a spoofed photo does not return an error from the compare endpoint — it is reported here in note.
Response
FieldTypeDescription
data.session_idstringSession id.
data.comparison_valuenumberFace similarity score, 0–1.
data.notestringFailure reason, if any.
data.profile.user_info.first_namestringFirst name.
data.profile.user_info.last_namestringLast name.
data.profile.user_info.middle_namestringPatronymic.
data.profile.user_info.pinflstringPINFL, 14 digits.
data.profile.user_info.genderstringGender.
data.profile.user_info.birth_datestringyyyy-MM-dd.
data.profile.user_info.birth_placestringPlace of birth.
data.profile.user_info.birth_countrystringCountry of birth.
data.profile.user_info.nationalitystringNationality.
data.profile.user_info.citizenshipstringCitizenship.
data.profile.document_info.documentstringDocument series and number.
data.profile.document_info.typestringDocument type.
data.profile.document_info.issued_bystringIssuing authority.
data.profile.document_info.issued_atstringIssue date, yyyy-MM-dd.
data.profile.document_info.expiry_atstringExpiry date, yyyy-MM-dd.
data.profile.permanent_addressobjectcountry, country_id, region_id, district_id, address.
data.profile.temporary_addressobjectMay be null.
Response examples
Option 1 / 2 — passed
{
  "data": {
    "session_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "comparison_value": 0.93,
    "profile": {
      "user_info": {
        "first_name": "ALISHER",
        "last_name": "KARIMOV",
        "middle_name": "BAXTIYOROVICH",
        "pinfl": "12345678901234",
        "gender": "MALE",
        "birth_date": "1990-01-01",
        "birth_place": "TOSHKENT",
        "birth_country": "UZBEKISTAN",
        "nationality": "UZBEK",
        "citizenship": "UZBEKISTAN"
      },
      "document_info": {
        "document": "AA1234567",
        "type": "PASSPORT",
        "issued_by": "IIV 26283",
        "issued_at": "2018-05-10",
        "expiry_at": "2028-05-09"
      },
      "contact_info": {},
      "permanent_address": {
        "country": "UZBEKISTAN",
        "country_id": 182,
        "region_id": 26,
        "district_id": 2603,
        "address": "..."
      },
      "temporary_address": null
    }
  },
  "code": 0,
  "message": "Success"
}
Option 3 — passed
Face did not match
Spoof detected
Errors
CodeReason
-1002Session belongs to another client.
-1005The comparison has not finished successfully. If the compare call returned -200 a moment ago, wait 1–2 seconds and call again.
-1027Session expired — fetch the result right after the compare call.
-1029Session not found.

8. Error codes#

CodeNameMeaning
0SUCCESSSuccess.
-5BAD_CREDENTIALSInvalid credentials or token user not found.
-9SYSTEM_ERRORUnexpected server error.
-200WAITING_ASYNC_PROCESSStill processing — get the result with 7.6.
-1000BAD_REQUESTInvalid request.
-1002CLIENT_NOT_PERMITTEDNot allowed for this client.
-1005UNSUCCESS_JOBComparison not finished successfully.
-1024INVALID_ID_NUMBERInvalid document number.
-1025INVALID_PINFLInvalid PINFL.
-1026BIRTH_DATE_NOT_NULLBirth date required.
-1027SESSION_EXPIREDSession expired.
-1029JOB_SESSION_NOT_FOUNDSession not found.
-1052INVALID_THRESHOLD_LIMITthreshold outside 0–1.
-1090USER_AGE_OLDER_THAN_16User must be at least 16.
-2001AI_ERRORFace service error.
Modified at 2026-11-05 12:51:11
Previous
user
Next
sign-in
Built with