Cloud-Based Electronic Digital Signature (Cloud EDS) at the CA#
Description#
Cloud EDS is an electronic digital signature that is stored and used on a remote server, allowing you to sign documents online without installing additional software and without a physical carrier (token). Learn more here
Terms#
- Subject — A person who is the object of a request to receive electronic documents in the E‑Document service.
- OTP code — A temporary code sent to the subject’s phone from 1414, used to confirm receipt of electronic documents.
- Mobile Citizens Database (MCDB) — A unified database of users’ mobile phone numbers needed to provide government services and to send SMS passwords for authorization or service signing via a one‑time password. Registration instructions are available here.
- IIN — Individual Identification Number of a citizen of the Republic of Kazakhstan.
- Unix timestamp — A system for representing points in time used in Unix and other POSIX‑compatible systems. Defined as the number of seconds since midnight on January 1, 1970.
- 6‑digit one‑time code — A code received via Egov Mobile or a mobile banking application.
- CMS — (Cryptographic Message Syntax) is an IETF standard for secure crypto messages. More details here.
- Scan copy — It is a copy of a signed document that does not possess any legal force.
1. Creating a Flow#
First, you need to create a Flow in your personal account. To do this, go to this link. Drag one of the available technologies (DS identifier technology or DS signer technology). After adding the selected technology, the system will automatically form a standard flow for the Cloud EDS procedure. Next, click Create flow and set its name.
After creating your Flow, you will need to use your unique API KEY at the second stage. You can find your API KEY on the page with the list of created Flows.
Simplified example of the Flows table in the personal account:
| Flow Name | API KEY | Technologies |
|---|---|---|
| Flow for Cloud EDS | TTpme201NiUMBA... | LD, F2F |
| Flow for individuals | Efy202XKbVAWRu... | LD, ED, F2F |
| Flow for legal entities | UuuH4V1XC-M9je... | LD, DR, F2F |
2. Creating a Session#
To work with the service, you need to create a session. To do this, send a POST request to create a session using the Flow’s API KEY.
Our service accepts and returns data only in JSON format.
Request URL:
https://kyc.biometric.kz/api/v1/flows/session/create/
| Request format | Method |
|---|---|
| JSON | POST |
Pass the API KEY in the request body:
| Field name | Type | Required | Description |
|---|---|---|---|
| api_key | String | Yes | API KEY of the Flow created in the personal account |
Request examples:
curl --location --request POST 'https://kyc.biometric.kz/api/v1/flows/session/create/' \
--header 'Content-Type: application/json' \
--data-raw '{
"api_key": "YOUR_FLOW_API_KEY"
}'
import requests
import json
url = "https://kyc.biometric.kz/api/v1/flows/session/create/"
payload = json.dumps({
"api_key": "YOUR_FLOW_API_KEY",
})
headers = {
'Content-Type': 'application/json',
}
response = requests.request(
"POST",
url=url,
headers=headers,
data=payload,
)
print(response.json())
const apiKey = 'YOUR_FLOW_API_KEY' // flow api key
fetch('https://kyc.biometric.kz/api/v1/flows/session/create/', {
method: 'POST',
body: JSON.stringify({
api_key: apiKey
})
})
.then(response => response.json())
.then(data => {
const { session_id, technologies } = data
})
const apiKey: string = 'YOUR_FLOW_API_KEY' // flow api key
interface SessionResponseData {
session_id: string,
technologies: string[]
}
fetch('https://kyc.biometric.kz/api/v1/flows/session/create/', {
method: 'POST',
body: JSON.stringify({
api_key: apiKey
})
})
.then(response => response.json())
.then(data => {
const { session_id, technologies }: SessionResponseData = data
})
The response will be a JSON object with the following fields:
- session_id — a one‑time session identifier for passing the flow;
- technologies — an ordered set of flow technologies.
Example response:
{
"session_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"technologies": [
"DSI",
"LDD",
"F2F",
"DSS"
]
}
Important
To use the extended session functionality, be sure to store the created session_id in any convenient way (optionally with the note parent_session_id), as it will be required later to correctly link the parent and child sessions.
3. Session Metadata#
When creating a Flow, you can include certain metadata that helps build a more flexible and dynamic process and simplifies verification.
Pass both API KEY and metadata in the request body. The value of metadata is an object that includes a technology‑named object (face2face, edocument, etc.) consisting of the technology’s metadata.
| Field name | Type | Required | Description |
|---|---|---|---|
| api_key | String | Yes | API KEY of the Flow created in the account |
| metadata | No | Session metadata |
Metadata for DSI (Digital Signature Identifier):
| Field name | Type | Required | Description |
|---|---|---|---|
| iin | No | IIN field | |
| phone | No | Subject’s phone field, format: 77********* |
Note
If no metadata is provided, the Flow proceeds with default behavior.
3.1. Metadata for DSI (Digital Signature Identifier)#
When creating a session for Digital Signature processes, you may send the signatory’s IIN and phone number. This simplifies and speeds up the document signing process. Include a metadata field in the request body.
| Field name | Type | Required | Description |
|---|---|---|---|
| iin | String | Yes | Client’s IIN (Individual Identification Number) |
| phone | String | Yes | Subject’s phone number, format: 77********* |
Request URL:
https://kyc.biometric.kz/api/v1/flows/session/create/
| Request format | Method |
|---|---|
| JSON | POST |
Request examples:
curl --location --request POST 'https://kyc.biometric.kz/api/v1/flows/session/create/' \
--header 'Content-Type: application/json' \
--data-raw '{
"api_key": "YOUR_FLOW_API_KEY",
"metadata": {
"ds_identifier": {
"iin": "0123456789012",
"phone": "77005353535"
}
}
}'
import requests
import json
import base64
url = "https://kyc.biometric.kz/api/v1/flows/session/create/"
payload = json.dumps({
"api_key": "YOUR_FLOW_API_KEY",
"metadata": {
"ds_identifier": {
"iin": "0123456789012",
"phone": "77005353535"
}
},
})
headers = {
'Content-Type': 'application/json',
}
response = requests.post(url=url, headers=headers, data=payload)
print(response.json())
const apiKey = 'YOUR_FLOW_API_KEY';
const payload = {
api_key: apiKey,
metadata: {
ds_identifier: {
iin: "0123456789012",
phone: "77005353535"
}
}
};
fetch('https://kyc.biometric.kz/api/v1/flows/session/create/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
})
.then(response => response.json())
.then(data => {
const { session_id, technologies } = data;
})
The response will include:
- session_id — a one‑time session identifier for passing the flow;
- technologies — an ordered set of flow technologies.
Example response:
{
"session_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"technologies": ["DSI", "LDD", "F2F", "DSS"]
}
Multi‑signing a document#
When passing a Flow session with the Digital Signature technology, it is possible for several users to sign the documents. After the first signature, export the document’s CMS signature, create a new Flow session, then upload the CMS signature (see step Uploading documents for signing). Further signing by other users proceeds as with a regular signing.
4. Uploading documents for signing#
Important
When using the DSS technology, files to be signed must be uploaded via the document upload API.
This must occur before starting DSS Technology processes, i.e., before the password entry stage.
| Field name | Type | Required | Description |
|---|---|---|---|
| session_id | String | Yes | Flow session ID |
| document_type | String | Yes | Document type (default is pdf) |
| document_names | String | Yes | List of names of documents uploaded for signing |
| files | form-data file | Yes | List of files of the documents uploaded for signing |
Request URL:
https://kyc.biometric.kz/api/v1/digital-signature-signer/document/upload/
| Request format | Method |
|---|---|
| JSON | POST |
Request examples:
curl --location --request POST 'https://kyc.biometric.kz/api/v1/digital-signature-signer/document/upload/' \
--header 'Content-Type: multipart/form-data' \
--header 'accept: application/json' \
-F 'session_id=ad129fb1-da95-4fa5-993d-79185fe524c7' \
-F 'document_type=pdf' \
-F 'document_names=document_1' \
-F 'files=@doc_1.pdf;type=application\pdf'
import requests
url = "https://kyc.biometric.kz/api/v1/digital-signature-signer/document/upload/"
payload = {
'session_id': 'ad129fb1-da95-4fa5-993d-79185fe524c7',
'document_type': 'pdf',
'document_names': 'document_1'
}
files=[
('files',('file',open('/path/to/file','rb'),'application/octet-stream'))
]
headers = {
'Content-Type': 'application/json',
}
response = requests.post(url=url, headers=headers, data=payload, files=files)
print(response.json())
const formdata = new FormData();
formdata.append("session_id", "ad129fb1-da95-4fa5-993d-79185fe524c7");
formdata.append("document_type", "pdf");
formdata.append("document_names", "document_1");
formdata.append("files", fileInput.files[0], "file");
fetch('https://kyc.biometric.kz/api/v1/flows/session/create/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: formdata
})
.then(response => response.json())
)
The response will be a JSON array with the following fields:
- document_name — name of the uploaded document;
- document_id — ID of the uploaded document.
Example response:
5. Redirecting the end user#
As a result of the previous steps, a session identifier session_id should be obtained. Now redirect the end user to our frontend client. To do this, construct the following URL:
https://remote.biometric.kz/flow/<session_id>
const session_id = '<session_id>'
const url = 'https://remote.biometric.kz/flow/' + session_id
window.open(url, '_blank')
const session_id: string = '<session_id>'
const url: string = 'https://remote.biometric.kz/flow/' + session_id
window.open(url, '_blank')
You can also set the following query parameters:
- redirect — address to which the redirect will occur after completing the technologies;
- locale — default language.
['ru', 'en', 'kz'];
Example:
The end user will then go to the biometric verification tab. In accordance with the example, the following technologies will be started sequentially:
| Technology code | Description |
|---|---|
| DSI | Digital Signature Identifier |
| LDD | Liveness detection by face |
| F2F | Similarity of two faces by photo |
| DSS | Digital Signature Service |
6. Retrieving the result#
You can get the overall result of the session by sending a GET request to a special URL, passing the session identifier in the parameters:
Request URL:
https://kyc.biometric.kz/api/v1/flows/session/result/
| Request format | Method |
|---|---|
| JSON | GET |
Pass session_id in the query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| session_id | String | Yes | Flow session identifier |
| flow_api_key | String | Yes | API KEY of the Flow in the personal account that was used when creating the session |
Request examples:
curl --location --request GET 'https://kyc.biometric.kz/api/v1/flows/session/result/?session_id=<session_id>&flow_api_key=<flow_api_key>'
import requests
url = "https://kyc.biometric.kz/api/v1/flows/session/result/"
params = {
'session_id': '<session_id>',
'flow_api_key': '<flow_api_key>,
}
response = requests.request(
"GET",
url=url,
params=params,
)
print(response.json())
Compressing large responses
For large responses, we recommend using gzip compression. Add the header Accept-Encoding: gzip to your request, and the server will automatically compress the response if its size exceeds 200 bytes. This is especially useful when retrieving results containing large amounts of data or images.
The response will be a JSON object with the following fields:
- id — session identifier;
- technologies — ordered set of technologies as per the created Flow;
- liveness_result — Liveness result;
- face2face_result — Face2face result.
- edocument_result — Edocument result.
- ds_identifier_result — DS Identifier result.
- ds_signer_result — DS Signer result.
Important
The fields liveness_result, face2face_result, edocument_result, ds_identifier_result, ds_signer_result are shown only if the client passed these technologies during the Flow.
Example response:
{
"id": "session_id",
"technologies": [
{
"name": "Edocument result",
"description": "Digital document"
}
],
"document_recognition_result": {
"first_name": "First",
"last_name": "Last",
"patronymic": "Patronymic",
"personal_number": "pers_number",
"date_of_birth": "01.01.2000",
"document_number": "doc_number",
...
6.1. Retrieving the result (POST)#
You can get the overall result of the session by sending a POST request to a special URL, passing the session identifier in the body parameters:
Request URL:
https://kyc.biometric.kz/api/v1/flows/session/result/
| Request format | Method |
|---|---|
| JSON | POST |
Pass session_id in the body of the request:
| Field name | Type | Required | Description |
|---|---|---|---|
| session_id | String | Yes | Flow session identifier |
| flow_api_key | String | Yes | API KEY of the Flow in the personal account that was used when creating the session |
Request examples:
import requests
url = "https://kyc.biometric.kz/api/v1/flows/session/result/"
payload = {
'session_id': '<session_id>',
'flow_api_key': '<flow_api_key>,
}
headers = {
'Content-Type': 'application/json',
}
response = requests.request(
"POST",
url=url,
headers=headers,
data=payload,
)
print(response.json())
Compressing large responses
For large responses, we recommend using gzip compression. Add the header Accept-Encoding: gzip to your request, and the server will automatically compress the response if its size exceeds 200 bytes. This is especially useful when retrieving results containing large amounts of data or images.
The response will be a JSON object with the following fields:
- id — session identifier;
- technologies — ordered set of technologies as per the created Flow;
- liveness_result — Liveness result;
- document_recognition_result — Document Recognition result;
- face2face_result — Face2face result.
- edocument_result — Edocument result.
- ds_identifier_result — DS Identifier result.
- ds_signer_result — DS Signer result.
Important
The fields liveness_result, document_recognition_result, face2face_result, edocument_result, ds_identifier_result, ds_signer_result are shown only if the client passed these technologies during the Flow.
Example response:
{
"id": "session_id",
"technologies": [
{
"name": "Document Recognition",
"description": "Parse document data from image"
}
],
"document_recognition_result": {
"first_name": "First",
"last_name": "Last",
"patronymic": "Patronymic",
"personal_number": "pers_number",
"date_of_birth": "01.01.2000",
"document_number": "doc_number",
"authority": "authority",
...
6.2. Retrieving the result (LIGHT)#
You can get the overall result of the session by sending a GET request to a special URL, passing the session identifier in the parameters:
Request URL:
https://kyc.biometric.kz/api/v1/flows/session/result/light/
| Request format | Method |
|---|---|
| JSON | GET |
Pass session_id in the query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| session_id | String | Yes | Flow session identifier |
| flow_api_key | String | Yes | API KEY of the Flow in the personal account that was used when creating the session |
Request examples:
curl --location --request GET 'https://kyc.biometric.kz/api/v1/flows/session/result/light/?session_id=<session_id>&flow_api_key=<flow_api_key>'
import requests
url = "https://kyc.biometric.kz/api/v1/flows/session/result/light/"
params = {
'session_id': '<session_id>',
'flow_api_key': '<flow_api_key>,
}
response = requests.request(
"GET",
url=url,
params=params,
)
print(response.json())
Compressing large responses
For large responses, we recommend using gzip compression. Add the header Accept-Encoding: gzip to your request, and the server will automatically compress the response if its size exceeds 200 bytes. This is especially useful when retrieving results containing large amounts of data or images.
The response will be a JSON object with the following fields:
- id — session identifier;
- technologies — ordered set of technologies as per the created Flow;
- liveness_result — Liveness result;
- document_recognition_result — Document Recognition result;
- face2face_result — Face2face result.
- edocument_result — Edocument result.
- ds_identifier_result — DS Identifier result.
- ds_signer_result — DS Signer result.
Important
The fields liveness_result, document_recognition_result, face2face_result, edocument_result, ds_identifier_result, ds_signer_result are shown only if the client passed these technologies during the Flow.
Important
Fields with images will be returned as temporary links to the object in storage.
Example response:
{
"id": "session_id",
"technologies": [
{
"name": "Document Recognition",
"description": "Parse document data from image"
}
],
"document_recognition_result": {
"first_name": "First",
"last_name": "Last",
"patronymic": "Patronymic",
"personal_number": "pers_number",
"date_of_birth": "01.01.2000",
"document_number": "doc_number",
"authority": "authority"
...
6.3. Retrieving results of signed documents (Digital Signature)#
To obtain the results of signed documents as CMS, send a POST request to the special URL, passing the session identifier in the parameters:
Request URL:
https://kyc.biometric.kz/api/v1/digital-signature-signer/document/result/
| Request format | Method |
|---|---|
| JSON | POST |
Pass session_id in the query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| session_id | String | Yes | Flow session identifier |
Request examples:
curl --location --request POST 'https://kyc.biometric.kz/api/v1/digital-signature-signer/document/result/?session_id=<session_id>'
import requests
url = "https://kyc.biometric.kz/api/v1/digital-signature-signer/document/result/"
params = {
'session_id': '<session_id>',
}
response = requests.request(
"POST",
url=url,
params=params,
)
print(response.json())
The response will be a JSON array with the following fields:
- document_name — document name;
- document_id — document ID in the Digital Signature system;
- document_signature — document signature in CMS format.
Example response:
[
{
"document_id": "08561b9d-1f16-4a14-a7c3-78c50d4090f3",
"document_name": "signed_document.cms",
"document_signature": "MIAGCSqGSIb3DQEHAqCAMIACAQExDjAMBggqgwCiXi48/TDQoxIDAgb2JqDQ..."
}
]
6.4. Downloading an archive with document copies#
The CA service provides the ability to download copies of the documents uploaded for signing as an archive, which is created for user convenience only and has no legal force. The archive will contain a copy of each uploaded document with a QR code and client information on the very last page.
The QR code redirects the client to the document authenticity verification page.
Authenticity is verified by comparing the hash of the document uploaded to the server with the document sent by the user.
Each downloaded file inside the archive contains metadata with the tag DocumentId, which corresponds to the ID of the uploaded and signed document on the server.
There are two ways to download the archive with copies of documents:
- Download the result via the frontend client
Download occurs by clicking the link download signed documents in a zip file .

- Download by sending a request to the service
To download the archive with copies via request, send a GET request passing session_id as a query parameter.
Request URL:
https://kyc.biometric.kz/api/v1/digital-signature-signer/document/result/download/
| Request format | Method |
|---|---|
| JSON | POST |
Request parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| session_id | String | Yes | Certification Authority session ID |
The examples below contain test data. In real requests, the values will correspond to the specific subject’s information.
Request examples:
curl --request GET \
--url "https://kyc.biometric.kz/api/v1/digital-signature-signer/document/result/download/?session_id=<session_id>" \
import requests
import json
url = "https://kyc.biometric.kz/api/v1/digital-signature-signer/document/result/download/"
params = {
"session_id": "<session_id>"
}
response = requests.get(url, params=params)
if response.status_code == 200:
with open("documents.zip", "wb") as file:
file.write(response.content)
print("Archive downloaded successfully.")
else:
print("Error:", response.status_code, response.text)
const url = "https://kyc.biometric.kz/api/v1/digital-signature-signer/document/result/download/";
const params = new URLSearchParams({
session_id: "<session_id>"
});
fetch(`${url}?${params.toString()}`, {
method: "POST"
})
.then(response => response.blob())
.then(blob => {
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "documents.zip";
link.click();
})
.catch(error => console.error("Error:", error));
const url: string = "https://kyc.biometric.kz/api/v1/digital-signature-signer/document/result/download/";
const params: URLSearchParams = new URLSearchParams({
session_id: "<session_id>"
});
fetch(`${url}?${params.toString()}`, {
method: "POST",
headers: headers
})
.then(response => response.blob())
.then(blob => {
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "documents.zip";
link.click();
})
.catch(error => console.error("Error:", error));
Example:
https://kyc.biometric.kz/api/v1/digital-signature-signer/document/result/download/?session_id=session_id
The response will be a file in binary format.
7. Extended session#
Important
This functionality is enabled only after prior coordination and subsequent approval from your assigned account manager.
An extended session is a mechanism for separate authentication and authorization of a user in the Certification Authority (CA) that allows returning to the signing process after switching the user to other interface windows and continuing a number of operations afterwards.
To return the user to the session process and avoid a number of repeated checks, provided that the previous session ended within the last 24 hours, create a new session using the previously used Flow API_KEY, then upload an additional document and redirect the client using the provided URL.
7.1. Repeat redirecting the end user#
As in Section 5, the client must be redirected using the current session_id. Append the parameter ?from_session_id={[parent_session_id](#parent_session_id)} at the end of the URL to correctly link the new session with the previous one.
https://remote.biometric.kz/flow/<session_id>?from_session_id=<parent_session_id>
const session_id = '<session_id>'
const parent_session_id = '<parent_session_id>'
const url = 'https://remote.biometric.kz/flow/' + session_id + '?from_session_id=' + parent_session_id
window.open(url, '_blank')
const session_id: string = '<session_id>'
const parent_session_id: string = '<parent_session_id>'
const url: string = 'https://remote.biometric.kz/flow/' + session_id + '?from_session_id=' + parent_session_id
window.open(url, '_blank')
You can also set the following query parameters:
- redirect — address to which the redirect will occur after completing the technologies;
- locale — default language.
['ru', 'en', 'kz'];
Example:
https://remote.biometric.kz/flow/<session_id>?from_session_id=<parent_session_id>&redirect=https://example.com/&locale=ru
The end user will then go to the biometric verification tab.
After completing the session, you can obtain the session results and the signed document results as well.