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

Usage guide

Integration with Web SDK#

1. What is RS-ID Web SDK#

RS-ID Web SDK lets your web product 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, the user opens the RS-ID page (hosted by RS-ID), 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.
sends the user back to your site and gives your backend the verified citizen profile.

Use cases#

Use caseExample
Remote customer onboarding (KYC)A bank, microfinance or insurance company opens an account online 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 is the actual citizen.
Age / identity checksMarketplaces, telecom, gaming or delivery services that must verify age or a real identity.
Pre-filled registrationThe user only takes a selfie; your form is filled with verified name, document and birth date.

2. Terminology#

TermWho it is
ClientThe company integrating RS-ID (you). Registered in RS-ID and issued a client_id / client_secret. Includes the client backend (calls the RS-ID API) and the client frontend (your website that sends the user to the RS-ID page).
UserThe end person being identified — your customer, a citizen of Uzbekistan.
ServerThe RS-ID server: the Web SDK API and the RS-ID page (<rsid_base_url>) where the user takes the selfie.
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 types#

RS-ID page can be shown to the user in two ways. The API calls are the same; only how you open the page differs.

3.1 Redirect flow#

The client frontend sends the user's browser to the RS-ID page. After a successful identification the RS-ID page redirects the user back to your redirect_url.
Simplest integration, works on desktop and mobile browsers.
The user leaves your site for the duration of the check.
or

3.2 iFrame flow#

The client frontend embeds the RS-ID page inside an <iframe> on its own page, so the user never leaves your site.
Requirements:
allow="camera" is mandatory — without it the browser blocks the camera inside the iframe.
Your page must be served over HTTPS.
After a successful identification the iframe navigates to your redirect_url. Point redirect_url to a small page on your own domain that notifies the parent window, for example:

4. Integration diagram#

integration-flow-web-sdk.png

5. Environments#

EnvironmentAPI base URLRS-ID page
Stage (testing)https://sdk.stage.rsid.uz/web/apihttps://sdk.stage.rsid.uz/?session_id={session_id}
Productionhttps://sdk.rsid.uz/web/apihttps://sdk.rsid.uz/?session_id={session_id}
Stage and production use different client_id / client_secret. A session created on stage opens only on the stage page, and vice versa.

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
Accept-Languageuz / ru / enOptional — language of message
Security. client_secret and access_token must stay on the client backend. Never send them to the browser. The client frontend only needs the session_id.

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 digitClient identifier issued by RS-ID.
client_secretstringYesNon-emptyClient secret issued by RS-ID.
{
  "client_id": "web-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"
}
Refreshing the token — POST {base_url}/v1/auth/refresh?token={refresh_token} with the required params. Reuse the 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.
client_idstringYesNon-emptyClient identifier issued by RS-ID.
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.
codeinteger0 on success.
messagestringResult text.
{
  "data": {
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "token_type": "Bearer",
    "expires_in": 3600,
    "scope": "read write"
  },
  "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. Each session connected to ip_address of user. It provides the session works only user's current device only once.
Method - POST
Endpoint - {base_url}/v1/sessions
Authorization (Headers) - Bearer {access_token}
Content-Type (Headers) - application/json

Request body
FieldTypeRequiredLength / formatDescription
client_typestring (enum)YesWEBIntegration channel. Always WEB for Web SDK.
ip_addressstringYesIPv4 / IPv6The user's public IP address (take it from the user's request to your backend). The RS-ID page only works from this IP — see note below.
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.
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. If omitted, the system default is used.
localestring (enum)NoUZ, RU, ENDefault UZ.
additional_paramsobjectNoOnly the keys belowSettings for the RS-ID page. Any other key is rejected.
additional_params.redirect_urlstringRecommendedURLWhere the user is sent after successful identification (see 7.5).
additional_params.langstringNouz, ru, enLanguage of the RS-ID page.
additional_params.themestringNoe.g. light, darkRS-ID page theme.
additional_params.primary_colorstringNoHex color, e.g. #1A73E8Accent color of the RS-ID page.
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.
IP binding. The session is locked to ip_address. When the user opens the RS-ID page, RS-ID compares the user's IP with this value. If they differ, the page shows an error (-1028). Pass the real public IP of the user, not your server's IP.
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 RS-ID page will only open the camera.
{
  "client_type": "WEB",
  "ip_address": "84.54.70.12",
  "external_id": "ORDER-123",
  "retry_count": 3,
  "threshold": 0.7,
  "locale": "UZ",
  "user_info": {
    "pinfl": "12345678901234",
    "birth_date": "01.01.1990"
  },
  "additional_params": {
    "redirect_url": "https://shop.example.uz/kyc/done?order=ORDER-123",
    "lang": "uz"
  }
}
Using a document number instead of PINFL:
"user_info": { "id_number": "AA1234567", "birth_date": "01.01.1990" }
Session without user_info
Response
FieldTypeLength / formatDescription
datastringUUID, 36 charssession_id. Use it to open the RS-ID page and to get the result.
codeinteger0 on success.
messagestringResult text.
{
  "data": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "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 Web SDK client.
-1024Invalid id_number format.
-1025Invalid pinfl format.
-1026birth_date is missing.
-1034Unknown key in additional_params.
-1052threshold outside 0–1.
-1090User is younger than 16.
400Field validation error, e.g. ip address cannot be blank.

7.4 Open the RS-ID page#

With the session_id, the client frontend opens the RS-ID page — by redirect (3.1) or in an iFrame (3.2):
EnvironmentURL
Stagehttps://sdk.stage.rsid.uz/?session_id={session_id}
Productionhttps://sdk.rsid.uz/?session_id={session_id}
The session has a limited lifetime and number of attempts. Open the page right after creating the session; if it expires, create a new one.

7.5 User flow on the RS-ID page#

The RS-ID page has two modes. Which one the user sees depends on how the session was created in 7.3:
Page modeShown whenWhat the user does
with_infoSession created without user_info (Option 2)Enters their data, then takes a selfie
without_infoSession created with user_info (Option 1)Only takes a selfie

with_info — data entry, then camera#

The page needs the user's data first.
1.
The user enters their passport series and number or PINFL and their date of birth (dd.mm.yyyy), then taps Next (Далее).
rsid-page-with-info_1.png
2.
The page asks for camera access. The user taps Allow (Разрешить) in the browser prompt, or Allow access (Разрешить доступ) on the page.
rsid-page-camera-permission_1.png
3.
The camera opens (same screen as in without_info below). The user places their face inside the circle and the selfie is taken.
4.
RS-ID checks liveness and compares the face with the passport photo of the entered person.
5.
On success the user is redirected to redirect_url (7.6).

without_info — camera only#

The user's data is already known, so the page goes straight to the camera.
1.
The page asks for camera access — same screen as step 2 of with_info above. The user allows it.
2.
The camera opens. The user places their face inside the circle. While no face is found, the circle is red and the page shows "Face not detected" (Лицо не обнаружено); once the face is in position, the selfie is taken.
rsid-page-without-info_1.png
3.
RS-ID checks liveness and compares the face with the passport photo.
4.
On success the user is redirected to redirect_url (7.6).

Failed attempts#

If the user blocks camera access, the page cannot continue — the user must allow the camera in the browser settings and reload the page.
If the selfie is rejected (spoof detected, face does not match, citizen not found), the page shows the reason and lets the user try again while attempts remain (retry_count). When attempts run out or the session expires, the page shows an error and the client must create a new session.

7.6 Redirect after successful identification#

After a successful identification the RS-ID page redirects the user to additional_params.redirect_url from the create-session request.
In the redirect flow, the user's browser returns to your site.
In the iFrame flow, the iframe navigates to redirect_url; use it to notify the parent page (see 3.2).
Put your own identifier into redirect_url (for example ?order=ORDER-123) so you know which session finished. Then the client backend fetches the result (7.6).
Do not treat the redirect alone as proof of identification — anyone can open that URL. Always confirm the result from your backend with 7.6.

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.2.
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": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "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 redirect.
-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.
-1028IP_RESTRICTED_FOR_SESSIONUser's IP differs from session ip_address.
-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-04 11:25:06
Previous
Integration Overview
Next
sign-in
Built with