1. Auth and Qr identification
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
    • refresh
    • Option 1 — compare photo with passport photo
    • Option 2 — compare two photos with citizen data
    • Option 3 — compare two photos without citizen data
  • 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. Auth and Qr identification

Qr Sign/Identification process

QR signing with digital signature (RS-IMZO / E-IMZO)#

1. What is QR signing#

QR signing lets a user sign content from your website with their digital signature (RS-IMZO or E-IMZO) stored in the RS-ID mobile app.
Your backend creates a QR token with the content to sign. Your site shows the QR code; the user scans it with the RS-ID mobile app, sees the content, chooses their signature key and signs. RS-ID validates the signature, sends the signed data (PKCS#7) to your callback_url, and marks the QR token as completed.
You do not install E-IMZO plugins or handle signature keys on your site — signing happens on the user's phone.

Use cases#

Use caseExample
Document signingA user signs a loan, rental or service contract shown on your site.
Approval by several signersA document must be signed by specific people or companies (by PINFL or TIN); the QR is completed when all of them have signed.
Sign-in with digital signatureYour site puts a one-time random challenge into sign_content; the user signs it, and you sign the user in after verifying the signature.
Confirming an operationSigning a payment order or an application before it is processed.

2. Terminology#

TermWho / what it is
ClientThe company integrating RS-ID (you). Registered in RS-ID as a Web SDK client and issued a client_id / client_secret. Includes the client backend and the client frontend.
UserThe person who signs — has the RS-ID mobile app with a digital signature added.
RS-ID mobile appThe RS-ID app on the user's phone. Stores the user's digital signatures and signs content.
ServerThe RS-ID server: creates QR tokens, validates signatures and sends callbacks.
QR tokenOne signing request, identified by qr_id. Has a lifetime (expire_time) and a status.
RS-IMZO / E-IMZOTypes of digital signature (sign_method).
SignerA person or company allowed to sign, identified by PINFL (14 digits, individual) or TIN (9 digits, company).
PKCS#7The standard format of the signed data (CMS) that RS-ID sends to your callback_url.

3. How it works#

1.
Your backend signs in (7.1) and creates a QR token with the content to sign (7.3).
2.
Your site shows the QR code to the user.
3.
The user scans it with the RS-ID mobile app, reads the content and signs it with their RS-IMZO or E-IMZO key (7.4).
4.
RS-ID validates the signature and checks that the signer is allowed.
5.
RS-ID sends the signed data (PKCS#7) to your callback_url (7.5).
6.
Your backend checks the QR status (7.6 / 7.7) until it is COMPLETED or EXPIRED.

4. Integration diagram#

integration-flow-qr-sign.png

5. Environments#

EnvironmentAPI base URLQR link (inside the QR code)
Stage (testing)https://sdk.stage.rsid.uz/web/apihttps://auth.stage.rsid.uz/{qr_id}
Productionhttps://sdk.rsid.uz/web/apihttps://auth.rsid.uz/{qr_id}
Stage and production use different client_id / client_secret. A QR code created on stage can be scanned only with the stage RS-ID app.

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 and access_token stay on your backend. The frontend only needs the QR image or link.
Verify the PKCS#7 yourself when the callback arrives: check that the signature is valid, that the signed content equals your sign_content, and that the certificate belongs to the expected person (PINFL / TIN).
Use an HTTPS callback_url and match the callback to your record by external_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 digitWeb SDK client 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"
}
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 digitWeb SDK client identifier issued by RS-ID.
client_secretstringYesNon-emptyClient secret issued by RS-ID.
{
  "client_id": "web-sdk-client",
  "client_secret": "s3cr3t-value"
}
Response — same as 7.1. If the refresh token is expired or invalid, sign in again (7.1).

7.3 Create a QR token#

Creates a signing request and returns the QR code.
Method - POST
Endpoint - {base_url}/v1/qr
Authorization (Headers) - Bearer {access_token}
Content-Type (Headers) - application/json

Request body
FieldTypeRequiredLength / formatDescription
sign_contentstringYesNon-emptyThe content the user signs. It is shown to the user in the RS-ID app.
expire_timeintegerYes> 0, secondsQR token lifetime in seconds, e.g. 300 (5 minutes).
sign_methodstring (enum)NoRS_IMZO, E_IMZOAllowed signature type. If omitted, the user can sign with any of their signatures.
signersarrayNo—Who is allowed to sign. If omitted, any user can sign once. If set, each listed signer signs once, and the QR is completed when all have signed.
signers[].signerstringYes, if signers is sentPINFL (14 digits) or TIN (9 digits)The person or company allowed to sign.
signers[].allow_idstringNo—Additional identifier of the signer, stored with the signature.
external_idstringNoUnique per clientYour own reference (document or order id). Lets you check the status by your id (7.7). Must be unique — a repeat returns -1080.
callback_eventobjectNo—Callback settings.
callback_event.callback_urlstringRecommendedHTTPS URLWhere RS-ID sends the signed data after each signature (7.5).
redirect_urlstringNoURLLink returned to the RS-ID app after signing.
document_provider_typestring (enum)NoHUJJAT_UZ, DIDOXDocument provider, if the document comes from one.
qr_response_typestring (enum)NoBASE64, DATA, ALLWhat to return. Default BASE64. BASE64 — PNG image; DATA — the link inside the QR; ALL — both.
widthintegerNopxQR image width. Default 100.
heightintegerNopxQR image height. Default 100.
Request examples
Any user signs
{
  "sign_content": "Contract No. A-7781 dated 09.11.2026. I agree to the terms of the service agreement.",
  "expire_time": 300,
  "sign_method": "RS_IMZO",
  "external_id": "CONTRACT-A-7781",
  "callback_event": {
    "callback_url": "https://shop.example.uz/webhooks/rsid/sign"
  },
  "qr_response_type": "ALL",
  "width": 256,
  "height": 256
}
Specific signers
Sign-in with digital signature
Response
FieldTypeDescription
data.qr_idstringQR token id. Use it in 7.6.
data.qr_base64stringQR code as a PNG image in base64. Returned for BASE64 and ALL.
data.qr_datastringThe link inside the QR code (https://auth.rsid.uz/{qr_id}). Returned for DATA and ALL.
data.expire_atstringExpiry time, yyyy-MM-dd HH:mm:ss.
data.qr_statusstringACTIVE for a new token.
codeinteger0 on success.
messagestringResult text.
{
  "data": {
    "qr_id": "9b2e6c1a-4f7d-4a3b-8e5c-1d2f3a4b5c6d",
    "qr_data": "https://auth.rsid.uz/9b2e6c1a-4f7d-4a3b-8e5c-1d2f3a4b5c6d",
    "qr_base64": "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEAAQMAAABmvDolAAAABlBMVEX///8AAABVwtN+...",
    "expire_at": "2026-11-09 17:35:00",
    "qr_status": "ACTIVE"
  },
  "code": 0,
  "message": "Success"
}
Show the image with <img src="data:image/png;base64,{qr_base64}">, or draw your own QR from qr_data.
Errors
CodeReason
-1002Credentials do not belong to a Web SDK client.
-1080A QR token with this external_id already exists.
-5Token user not found.
400Validation error, e.g. sign content cannot be blank or expire_time missing / not positive.

7.4 User flow in the RS-ID mobile app#

1.
The user opens the RS-ID mobile app and scans the QR code.
2.
The app shows the content to sign (sign_content).
3.
The user chooses a digital signature (only sign_method keys are shown, if set). If signers are set, only signatures with an allowed PINFL / TIN can be used.
4.
The user signs. The app sends the signature (PKCS#7) to RS-ID.
5.
RS-ID validates the signature and sends the callback (7.5).
The app shows an error and the signature is not accepted when:
SituationResult
The QR token expiredQR token expired — create a new QR token.
The QR token is already completedQR token completed.
The signature's PINFL / TIN is not in signersThe user is not allowed to sign.
This signer has already signedThe document is already signed with this signature.
All signers have already signedThe document is fully signed.

7.5 Callback with the signed data#

After each successful signature, RS-ID sends a POST request to callback_event.callback_url.
Method - POST
URL - your callback_url
Content-Type - application/json
Request body (sent by RS-ID)
FieldTypeDescription
sign_request_datastringThe JSON of your original create request (7.3), as a string. Use its external_id to find your record.
pkcs7stringThe signed data, PKCS#7 (CMS) in base64. Contains the signed content, the signature and the signer's certificate.
{
  "sign_request_data": "{\"signers\":null,\"expire_time\":300,\"sign_method\":\"RS_IMZO\",\"sign_content\":\"Contract No. A-7781 dated 09.11.2026. I agree to the terms of the service agreement.\",\"redirect_url\":null,\"external_id\":\"CONTRACT-A-7781\",\"document_provider_type\":null,\"callback_event\":{\"callback_url\":\"https://shop.example.uz/webhooks/rsid/sign\"},\"qr_response_type\":\"ALL\",\"width\":256,\"height\":256}",
  "pkcs7": "MIIKvgYJKoZIhvcNAQcCoIIKrzCCCqsCAQExDjAMBggqhlADAgIBAQUAMIIBDgYJKoZIhvcNAQcBoIIA..."
}
Your response — return HTTP 200. The callback is sent once and is not retried, so also check the status with 7.6 / 7.7.
With several signers, a callback is sent for each signature.

7.6 Get QR token status by qr_id#

Method - GET
Endpoint - {base_url}/v1/qr/{qr_id}
Authorization (Headers) - Bearer {access_token}

Path parameters
FieldTypeRequiredLength / formatDescription
qr_idstringYesUUIDFrom 7.3.
Response
FieldTypeDescription
data.qr_idstringQR token id.
data.qr_statusstringACTIVE — waiting for signature; COMPLETED — signed (by all signers, if set); EXPIRED — lifetime passed; DELETED — removed.
data.expire_atstringExpiry time, yyyy-MM-dd HH:mm:ss.
data.qr_datastringLink inside the QR code.
data.qr_base64stringQR image (100×100 PNG, base64) — to show it again.
{
  "data": {
    "qr_id": "9b2e6c1a-4f7d-4a3b-8e5c-1d2f3a4b5c6d",
    "qr_data": "https://auth.rsid.uz/9b2e6c1a-4f7d-4a3b-8e5c-1d2f3a4b5c6d",
    "qr_base64": "iVBORw0KGgoAAAANSUhEUgAAAGQAAABkAQMAAABKLAcXAAAABlBMVEX///8AAABVwtN+...",
    "expire_at": "2026-11-09 17:35:00",
    "qr_status": "COMPLETED"
  },
  "code": 0,
  "message": "Success"
}
Poll every few seconds while qr_status is ACTIVE.
Errors
CodeReason
-1035QR token not found, or it belongs to another client.
-1002Credentials do not belong to a Web SDK client.

7.7 Get QR token status by external_id#

Same as 7.6, but by your own external_id from 7.3.
Method - GET
Endpoint - {base_url}/v1/qr/status/by-external/{external_id}
Authorization (Headers) - Bearer {access_token}

Path parameters
FieldTypeRequiredLength / formatDescription
external_idstringYes—external_id from 7.3.
Response — same as 7.6.
Errors — same as 7.6.

8. Error codes#

CodeNameMeaning
0SUCCESSSuccess.
-5BAD_CREDENTIALSInvalid credentials or token user not found.
-9SYSTEM_ERRORUnexpected server error.
-1000BAD_REQUESTInvalid request.
-1002CLIENT_NOT_PERMITTEDNot a Web SDK client.
-1035INVALID_QR_TOKENQR token not found or belongs to another client.
-1080QR_TOKEN_EXISTS_BY_EXTERNAL_IDA QR token with this external_id already exists.
Modified at 2026-11-09 12:49:37
Previous
Sign with RS-ID (Oauth2 style)
Next
Get user info by code
Built with