1. Mobile SDK
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. Mobile SDK

Usage guide

Integration with Mobile SDK#

1. What is RS-ID Mobile SDK#

RS-ID Mobile SDK lets your mobile app (Android / iOS) confirm that a real, live person is who they claim to be, using their face and the national identity registry of Uzbekistan.
You do not build any camera, liveness or face-matching logic. Your backend creates a session, your app starts the RS-ID SDK (a native library added to your app), the user takes a selfie, and RS-ID:
1.
checks that the selfie is a live person, not a photo, screen or mask (anti-spoofing);
2.
fetches the citizen's official passport photo and data from the government registry;
3.
compares the selfie with the passport photo;
4.
returns the result to your app, and gives your backend the verified citizen profile.

Use cases#

Use caseExample
Remote customer onboarding (KYC)A bank, microfinance or insurance app opens an account without a branch visit.
Identity confirmation before a sensitive actionConfirming the account owner before a large transfer, a password reset or changing a phone number.
Online contract signingMaking sure the person signing a loan or rental agreement in the app is the actual citizen.
Age / identity checksMarketplaces, telecom, gaming or delivery apps that must verify age or a real identity.
Pre-filled registrationThe user only takes a selfie; your registration form is filled with verified name, document and birth date.
Repeat verificationA returning user is verified again with the data from their earlier session, without entering it again.

2. Terminology#

TermWho it is
ClientThe company integrating RS-ID (you). Registered in RS-ID and issued a client_id / client_secret for Mobile SDK. Includes the client backend (calls the RS-ID API) and the client app (your Android / iOS app with the RS-ID SDK inside).
UserThe end person being identified — your customer, a citizen of Uzbekistan.
ServerThe RS-ID server: the Mobile SDK API (<rsid_base_url>).
RS-ID SDKThe native RS-ID library added to the client app. It shows the RS-ID screens (data entry, camera) and sends the selfie to the server.
SessionOne identification attempt created by the client backend. Identified by session_id (UUID). Has a limited lifetime and a limited number of attempts.
PINFLPersonal identification number of an individual — 14 digits.
Document number (id_number)Passport or ID card series and number, e.g. AA1234567.

3. Integration type — native SDK#

The RS-ID screens run inside your app through the RS-ID SDK. The user never leaves the app.
1.
Add the RS-ID SDK to your Android / iOS project. The package and installation instructions are provided by RS-ID together with your credentials.
2.
Allow camera access in the app:
Android — android.permission.CAMERA in AndroidManifest.xml;
iOS — NSCameraUsageDescription in Info.plist (the text shown to the user when the camera is requested).
3.
Start the SDK with the session_id from your backend (7.4).
4.
Handle the result the SDK returns to your app — success, failure or cancelled by the user (7.6).
5.
Confirm the result on your backend with GET /v1/user/{session_id} (7.7).
Unlike Web SDK, Mobile SDK sessions are not bound to an IP address and there is no redirect_url — the result comes back to your app from the SDK.

4. Integration diagram#

integration-flow-mobile-sdk.png

5. Environments#

EnvironmentAPI base URL
Stage (testing)https://sdk.stage.rsid.uz/mobile/api
Productionhttps://sdk.rsid.uz/mobile/api
Stage and production use different client_id / client_secret. Mobile SDK credentials are separate from Web SDK credentials — a Web SDK client cannot create mobile sessions (-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 (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
Accept-Languageuz / ru / enOptional — language of message
Security. client_secret must stay on the client backend. Never put it into the app — app files can be extracted. Call sign-in and create session only from your backend.

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 digitMobile SDK client identifier issued by RS-ID.
client_secretstringYesNon-emptyClient secret issued by RS-ID.
{
  "client_id": "mobile-sdk-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 session.

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 digitMobile SDK client identifier issued by RS-ID.
client_secretstringYesNon-emptyClient secret issued by RS-ID.
{
  "client_id": "mobile-sdk-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 Create session#

Creates an identification session for one user. The session belongs to your client: only requests made with your client's token can use it.
Method - POST
Endpoint - {base_url}/v1/sessions
Authorization (Headers) - Bearer {access_token}
Content-Type (Headers) - application/json

Request body
FieldTypeRequiredLength / formatDescription
client_typestring (enum)YesMOBILEIntegration channel. Always MOBILE for Mobile SDK.
user_infoobjectNo—Citizen data. Send it to create a session with user_info; omit it for a session without user_info.
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.
session_idstringNoUUID, 36 charsAn earlier session of your client for the same user. The new session takes the citizen data from it, so the user does not enter it again. Ignored if user_info is sent.
external_idstringNo—Your own reference (order, application or customer id) to link the session to your records. Recommended random uuid.
retry_countintegerNo> 0Maximum number of attempts. If omitted, 0 or above the system maximum, the system maximum is used.
thresholdnumberNo0.0 – 1.0Minimum face-similarity score to pass. Default 0.5. See the note below.
localestring (enum)NoUZ, RU, ENDefault UZ.
additional_paramsobjectNoOnly the keys belowSettings for the RS-ID SDK screens. Any other key is rejected.
additional_params.langstringNouz, ru, enLanguage of the SDK screens.
additional_params.themestringNoe.g. light, darkTheme of the SDK screens.
additional_params.primary_colorstringNoHex color, e.g. #1A73E8Accent color of the SDK screens.
Threshold. threshold is the minimum face-similarity score (from 0.0 to 1.0) the selfie must reach against the passport photo for identification 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 need more attempts.
No IP binding, no redirect. Mobile sessions do not use ip_address or redirect_url. The result is returned to your app by the SDK (7.6).
Request examples — choose an option:
Session with user_info

Option 1 — Session with user_info#

The client backend already knows the user's data. The SDK will only open the camera.
{
  "client_type": "MOBILE",
  "external_id": "ORDER-123",
  "retry_count": 3,
  "threshold": 0.7,
  "locale": "UZ",
  "user_info": {
    "pinfl": "12345678901234",
    "birth_date": "01.01.1990"
  },
  "additional_params": {
    "lang": "uz"
  }
}
Using a document number instead of PINFL:
"user_info": { "id_number": "AA1234567", "birth_date": "01.01.1990" }
Session without user_info
Repeat verification (session_id)
Response
FieldTypeLength / formatDescription
datastringUUID, 36 charssession_id of the new session. Pass it to the RS-ID SDK and use it to get the result.
codeinteger0 on success.
messagestringResult text.
{
  "data": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "code": 0,
  "message": "Success"
}
Errors
CodeReason
-1000Invalid request — e.g. both or neither of pinfl / id_number in user_info.
-1002Credentials do not belong to a Mobile SDK client, or session_id belongs to another client.
-1024Invalid id_number format.
-1025Invalid pinfl format.
-1026birth_date is missing.
-1029session_id not found.
-1034Unknown key in additional_params.
-1052threshold outside 0–1.
-1090User is younger than 16.
400Field validation error, or client_type is missing.

7.4 Start the RS-ID SDK#

With the session_id, the client app starts the RS-ID SDK.
1.
Your backend creates the session (7.3) and returns session_id to the app.
2.
The app starts the RS-ID SDK with:
ParameterDescription
session_idFrom 7.3.
access_tokenA valid access token of your Mobile SDK client. The SDK uses it to call the RS-ID server; the server accepts requests for a session only with the token of the client that created it.
EnvironmentStage or production — must match the environment where the session was created.
The session has a limited lifetime and number of attempts. Start the SDK right after creating the session; if it expires, create a new one.

7.5 User flow in the RS-ID SDK#

The SDK has two modes. Which one the user sees depends on how the session was created in 7.3:
SDK modeShown whenWhat the user does
with_infoSession created without user_info and without session_id (Option 2)Enters their data, then takes a selfie
without_infoSession created with user_info (Option 1) or with an earlier session_id (Option 3)Only takes a selfie

with_info — data entry, then camera#

The SDK starts with the data-entry screen.
1.
The user enters their passport series and number or PINFL (JSHSHIR) and their date of birth (DD.MM.YYYY).
mobile-sdk-1-form_1.png
2.
The user accepts the User agreement and Privacy policy with the switch. The Continue (Davom etish) button becomes active; the user taps it.
mobile-sdk-2-form-filled_1.png
3.
The app asks for camera access (system permission dialog). The user allows it.
4.
The camera opens with the hint "Hold your face inside the circle" (Yuzingizni doira ichida tuting). While no face is found, the circle is red; once the face is in position, the selfie is taken.
mobile-sdk-3-camera_1.png
5.
RS-ID checks liveness and compares the face with the passport photo of the entered person. The SDK shows "Identification in progress" (Identifikatsiya amalga oshirilmoqda).
mobile-sdk-4-processing_1.png
6.
On success the SDK shows "Identification completed successfully!" (Identifikatsiya qilish muvaffaqiyatli amalga oshirildi!) and returns the result to the app (7.6).
mobile-sdk-5-success_1.png

without_info — camera only#

1.
The app asks for camera access (system permission dialog). The user allows it.
2.
The camera opens. The user places their face inside the frame and the selfie is taken.
mobile-sdk-3-camera_1.png
3.
RS-ID checks liveness and compares the face with the passport photo.
mobile-sdk-4-processing_1.png
4.
The SDK returns the result to the app (7.6).
mobile-sdk-5-success_1.png

Failed attempts#

If the user denies camera access, the SDK cannot continue — the user must allow the camera in the phone settings for your app.
If the selfie is rejected (spoof detected, face does not match, citizen not found), the SDK shows the reason and lets the user try again while attempts remain (retry_count). When attempts run out or the session expires, the SDK returns a failure and the client must create a new session.

7.6 Result in the app#

When the user finishes, the SDK returns the result to your app:
ResultWhat to do
SuccessTell your backend the session is finished; the backend fetches the profile (7.7).
FailureAttempts ran out or the session expired. Create a new session (7.3) if the user wants to try again.
CancelledThe user closed the SDK. You can start the SDK again with the same session_id while it is active.
Do not treat the result in the app alone as proof of identification — the app runs on the user's device and can be modified. Always confirm the result from your backend with 7.7.

7.7 Get identification result#

The client backend gets the verified citizen profile.
Method - GET
Endpoint - {base_url}/v1/user/{session_id}
Authorization (Headers) - Bearer {access_token}

Path parameters
FieldTypeRequiredLength / formatDescription
session_idstringYesUUID, 36 charsFrom 7.3.
Response
FieldTypeDescription
data.session_idstringSession id.
data.comparison_valuenumberFace similarity score, 0–1.
data.notestringFailure note, 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.
{
  "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"
}
Errors
CodeReason
-1005Identification was not successful.
-1027Session expired — fetch the result right after the SDK returns success.
-1029Session not found.
-1002Session belongs to another client.

8. Error codes#

CodeNameMeaning
0SUCCESSSuccess.
-5BAD_CREDENTIALSInvalid credentials or token user not found.
-9SYSTEM_ERRORUnexpected server error.
-1000BAD_REQUESTInvalid request.
-1002CLIENT_NOT_PERMITTEDNot allowed for this client.
-1005UNSUCCESS_JOBIdentification not successful.
-1008IDENTIFICATION_FAILEDFace did not match.
-1024INVALID_ID_NUMBERInvalid document number.
-1025INVALID_PINFLInvalid PINFL.
-1026BIRTH_DATE_NOT_NULLBirth date required.
-1027SESSION_EXPIREDSession expired.
-1029JOB_SESSION_NOT_FOUNDSession not found.
-1031RETRY_COUNT_EXPIREDNo attempts left.
-1032SUCCESS_JOB_EXISTS_FOR_SESSIONSession already identified.
-1033SPOOFED_FILE_DETECTEDLiveness check failed.
-1034ADDITIONAL_PARAMS_INVALIDUnknown additional_params key.
-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 05:07:56
Previous
user-info
Next
sign-in
Built with