| Use case | Example |
|---|---|
| Identification inside your own UI | A bank takes the selfie in its own app and checks it against the passport photo from the registry. |
| Branch / kiosk / call-center checks | An operator's system sends the photo taken at the branch or kiosk. |
| Matching a selfie with a document photo | Comparing the user's selfie with the photo from a scanned ID card. |
| Matching two photos | Checking that two photos show the same person, e.g. a new selfie against one saved at registration. |
| Batch or back-office checks | Re-verifying existing customers from your own system. |
| Term | Who it is |
|---|---|
| Client | The 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. |
| User | The person whose face is checked — your customer, a citizen of Uzbekistan. |
| Server | The RS-ID server: the Backend API (<rsid_base_url>). |
| Session | One comparison request. Every compare call creates a new session and returns its session_id (UUID). Use it to get the result. |
| Original / reference photo | The two photos compared in Options 2 and 3: the user's photo and the photo to compare it with. |
| PINFL | Personal identification number of an individual — 14 digits. |
Document number (id_number) | Passport or ID card series and number, e.g. AA1234567. |
session_id; the result is always taken with 7.6 Get result.| Option | Endpoint | What is compared | user_info | Citizen profile in the result |
|---|---|---|---|---|
| Option 1 | POST /v1/authentication/async/compare | One user photo ↔ the citizen's passport photo from the registry | Required | Yes |
| Option 2 | POST /v1/authentication/async/compare-images | Two photos sent by the client | Required | Yes |
| Option 3 | POST /v1/face/async/compare-images | Two photos sent by the client | Not used | No — only the score |
code = 0. Otherwise it has code = -200 (still processing). Both responses carry the session_id in data.GET /v1/user/{session_id} (7.6).| Environment | API base URL |
|---|---|
| Stage (testing) | https://stage.rsid.uz/backend/api |
| Production | https://rsid.uz/backend/api |
client_id / client_secret. Backend API credentials are separate from Web and Mobile SDK credentials — an SDK client cannot call the compare endpoints (-1002).{ "data": { }, "code": 0, "message": "Success" }| Field | Type | Description |
|---|---|---|
code | integer | 0 — success. Any other value is an error or a state (see the error tables). Always check code, not only the HTTP status. |
message | string | Human-readable text in the request language (uz / ru / en). Do not parse it. |
data | any | Response payload. Absent on errors. |
| Header | Value | Used in |
|---|---|---|
Content-Type | application/json | All POST requests |
Authorization | Bearer {access_token} | All requests except sign-in and refresh |
Idempotency-Key | UUID, new for every request | Required for the compare endpoints (7.3–7.5) |
Accept-Language | uz / ru / en | Optional — 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 HTTP400.
data:image/...;base64, prefix.POST{base_url}/v1/auth/sign-in — no Authorization headerapplication/json| Field | Type | Required | Length / format | Description |
|---|---|---|---|---|
client_id | string | Yes | Non-empty; must not start with a digit | Backend API client identifier issued by RS-ID. |
client_secret | string | Yes | Non-empty | Client secret issued by RS-ID. |
{
"client_id": "backend-api-client",
"client_secret": "s3cr3t-value"
}| Field | Type | Description |
|---|---|---|
data.access_token | string (JWT) | Token for the Authorization: Bearer header. |
data.token_type | string | Always Bearer. |
data.expires_in | integer | Token lifetime in seconds. |
data.scope | string | Granted scopes, space-separated. |
data.refresh_token | string (JWT) | Token to get a new access_token without sending credentials again. |
code | integer | 0 on success. |
message | string | Result text. |
{
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "read write",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
},
"code": 0,
"message": "Success"
}access_token until it expires instead of signing in for every request.access_token with the refresh_token, without sending a new sign-in. Call it when the access_token has expired (after expires_in seconds).POST{base_url}/v1/auth/refresh?token={refresh_token} — no Authorization header.application/json| Field | Type | Required | Length / format | Description |
|---|---|---|---|---|
token | string | Yes | JWT | refresh_token from the sign-in (7.1) or a previous refresh response. |
| Field | Type | Required | Length / format | Description |
|---|---|---|---|---|
client_id | string | Yes | Non-empty; must not start with a digit | Backend API client identifier issued by RS-ID. |
client_secret | string | Yes | Non-empty | Client secret issued by RS-ID. |
{
"client_id": "backend-api-client",
"client_secret": "s3cr3t-value"
}| Field | Type | Description |
|---|---|---|
data.access_token | string (JWT) | New token for the Authorization: Bearer header. |
data.token_type | string | Always Bearer. |
data.expires_in | integer | Token lifetime in seconds. |
data.scope | string | Granted scopes, space-separated. |
data.refresh_token | string (JWT) | New refresh token. Use it for the next refresh. |
code | integer | 0 on success. |
message | string | Result text. |
{
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "read write",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
},
"code": 0,
"message": "Success"
}user_info, takes their passport photo and data, and compares the faces.POST{base_url}/v1/authentication/async/compareBearer {access_token}{uuid}application/json| Field | Type | Required | Length / format | Description |
|---|---|---|---|---|
photo | string | Yes | Base64 | The user's photo (selfie). |
is_spoofing_required | boolean | No | true / false | Run the liveness (anti-spoofing) check on the photo. Default false. Recommended true for live selfies. |
user_info | object | Yes | — | Citizen data used to find the passport photo. |
user_info.pinfl | string | Conditional | Exactly 14 digits | PINFL. Send either pinfl or id_number, not both. |
user_info.id_number | string | Conditional | 9 chars: 2 letters + 7 digits, e.g. AA1234567 | Passport / ID card number. Send either pinfl or id_number, not both. |
user_info.birth_date | string | Yes, if user_info is sent | dd.MM.yyyy | Date of birth. User must be at least 16 years old. |
threshold | number | No | 0.0 – 1.0 | Minimum face-similarity score to pass. Default 0.5. See the note below. |
external_id | string | No | — | Your own reference to link the request to your records. Recommended random uuid. |
locale | string (enum) | No | UZ, RU, EN | Default UZ. |
Threshold. thresholdis the minimum face-similarity score (from0.0to1.0) for the comparison to pass. If you don't send it, the default0.5is used. If you do send it, we recommend a value above0.5. For high-quality (strict) identification, send a value above0.7. A higher value is stricter and lowers the risk of a wrong person passing, but genuine users may fail more often.
{
"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" }| Field | Type | Length / format | Description |
|---|---|---|---|
data | string | UUID, 36 chars | session_id of this comparison. Use it in 7.6. |
code | integer | 0 — finished; -200 — still processing. Any other value — error. | |
message | string | Result text. |
{
"data": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"code": 0,
"message": "Success"
}{
"data": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"code": -200,
"message": "Waiting for async process"
}The response is not the verdict. code=0means the comparison has finished, not that the faces matched or the photo is live. Always read the result with 7.6 and checkcomparison_valueandnote.
| Code | Reason |
|---|---|
-1000 | Invalid request — e.g. no user_info, or both / neither of pinfl / id_number; citizen not found in the registry. |
-1002 | Credentials do not belong to a Backend API client. |
-1024 | Invalid id_number format. |
-1025 | Invalid pinfl format. |
-1026 | birth_date is missing. |
-1052 | threshold outside 0–1. |
-1090 | User is younger than 16. |
-2001 | Face service error. |
400 | Field 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. |
user_info, so the result also contains the verified citizen profile from the registry.POST{base_url}/v1/authentication/async/compare-imagesBearer {access_token}{uuid}application/json| Field | Type | Required | Length / format | Description |
|---|---|---|---|---|
original_photo | object | Yes | — | The first photo, e.g. the user's live selfie. |
original_photo.photo | string | Yes | Base64 | Photo data. |
original_photo.is_spoofing_required | boolean | No | true / false | Run the liveness check on this photo. Default false. Recommended true for a live selfie. |
original_photo.order | integer | No | — | Order of the photo. |
reference_photo | object | Yes | — | The second photo to compare with, e.g. a document photo or a saved selfie. |
reference_photo.photo | string | Yes | Base64 | Photo data. |
reference_photo.is_spoofing_required | boolean | No | true / false | Run the liveness check on this photo. Default false. Keep false for document photos. |
reference_photo.order | integer | No | — | Order of the photo. |
user_info | object | Yes | — | Citizen data. Same rules as in 7.3. |
user_info.pinfl | string | Conditional | Exactly 14 digits | PINFL. Send either pinfl or id_number. |
user_info.id_number | string | Conditional | 9 chars: 2 letters + 7 digits | Passport / ID card number. |
user_info.birth_date | string | Yes, if user_info is sent | dd.MM.yyyy | Date of birth. User must be at least 16. |
threshold | number | No | 0.0 – 1.0 | Default 0.5. Recommended above 0.5, above 0.7 for strict comparison. |
external_id | string | No | — | Your own reference. Recommended random uuid. |
locale | string (enum) | No | UZ, RU, EN | Default 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"
}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"
}| Code | Reason |
|---|---|
400 | original_photo or reference_photo missing (original photo should be exist, reference photo should be exist). |
POST{base_url}/v1/face/async/compare-imagesBearer {access_token}{uuid}application/json| Field | Type | Required | Length / format | Description |
|---|---|---|---|---|
original_photo | object | Yes | — | The first photo. |
original_photo.photo | string | Yes | Base64 | Photo data. |
original_photo.is_spoofing_required | boolean | No | true / false | Run the liveness check on this photo. Default false. |
original_photo.order | integer | No | — | Order of the photo. |
reference_photo | object | Yes | — | The second photo. |
reference_photo.photo | string | Yes | Base64 | Photo data. |
reference_photo.is_spoofing_required | boolean | No | true / false | Run the liveness check on this photo. Default false. |
reference_photo.order | integer | No | — | Order of the photo. |
threshold | number | No | 0.0 – 1.0 | Default 0.5. Recommended above 0.5, above 0.7 for strict comparison. |
external_id | string | No | — | Your own reference. Recommended random uuid. |
locale | string (enum) | No | UZ, RU, EN | Default 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"
}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"
}| Code | Reason |
|---|---|
-1002 | Credentials do not belong to a Backend API client. |
-1052 | threshold outside 0–1. |
-2001 | Face service error. |
400 | A 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. |
session_id — for all three options.GET{base_url}/v1/user/{session_id}Bearer {access_token}| Field | Type | Required | Length / format | Description |
|---|---|---|---|---|
session_id | string | Yes | UUID, 36 chars | data from the compare response (7.3–7.5). |
| Field | Meaning |
|---|---|
comparison_value | Face-similarity score, 0–1. Compare it with your threshold. |
note | Empty on a clean pass. Contains the reason otherwise — e.g. Spoofed file detected (liveness failed) or Face match failed (score below threshold). |
profile | Verified 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≥ yourthresholdandnoteis empty. Withis_spoofing_required: true, a spoofed photo does not return an error from the compare endpoint — it is reported here innote.
| Field | Type | Description |
|---|---|---|
data.session_id | string | Session id. |
data.comparison_value | number | Face similarity score, 0–1. |
data.note | string | Failure reason, if any. |
data.profile.user_info.first_name | string | First name. |
data.profile.user_info.last_name | string | Last name. |
data.profile.user_info.middle_name | string | Patronymic. |
data.profile.user_info.pinfl | string | PINFL, 14 digits. |
data.profile.user_info.gender | string | Gender. |
data.profile.user_info.birth_date | string | yyyy-MM-dd. |
data.profile.user_info.birth_place | string | Place of birth. |
data.profile.user_info.birth_country | string | Country of birth. |
data.profile.user_info.nationality | string | Nationality. |
data.profile.user_info.citizenship | string | Citizenship. |
data.profile.document_info.document | string | Document series and number. |
data.profile.document_info.type | string | Document type. |
data.profile.document_info.issued_by | string | Issuing authority. |
data.profile.document_info.issued_at | string | Issue date, yyyy-MM-dd. |
data.profile.document_info.expiry_at | string | Expiry date, yyyy-MM-dd. |
data.profile.permanent_address | object | country, country_id, region_id, district_id, address. |
data.profile.temporary_address | object | May be null. |
| Code | Reason |
|---|---|
-1002 | Session belongs to another client. |
-1005 | The comparison has not finished successfully. If the compare call returned -200 a moment ago, wait 1–2 seconds and call again. |
-1027 | Session expired — fetch the result right after the compare call. |
-1029 | Session not found. |
| Code | Name | Meaning |
|---|---|---|
0 | SUCCESS | Success. |
-5 | BAD_CREDENTIALS | Invalid credentials or token user not found. |
-9 | SYSTEM_ERROR | Unexpected server error. |
-200 | WAITING_ASYNC_PROCESS | Still processing — get the result with 7.6. |
-1000 | BAD_REQUEST | Invalid request. |
-1002 | CLIENT_NOT_PERMITTED | Not allowed for this client. |
-1005 | UNSUCCESS_JOB | Comparison not finished successfully. |
-1024 | INVALID_ID_NUMBER | Invalid document number. |
-1025 | INVALID_PINFL | Invalid PINFL. |
-1026 | BIRTH_DATE_NOT_NULL | Birth date required. |
-1027 | SESSION_EXPIRED | Session expired. |
-1029 | JOB_SESSION_NOT_FOUND | Session not found. |
-1052 | INVALID_THRESHOLD_LIMIT | threshold outside 0–1. |
-1090 | USER_AGE_OLDER_THAN_16 | User must be at least 16. |
-2001 | AI_ERROR | Face service error. |