Skip to content

Retrieving results

This page describes requests, common fields, and response handling rules. Fields and examples for individual technologies are available through the results index and the section menu.

Request results from the client system backend. You can track completion through the flow.end webhook; after an interface signal, also verify the result with a server-side request. The response contains the current session state and available results, including intermediate results.

Keep the API KEY on the backend

These methods require the Workflow API KEY. Do not pass it to the browser or mobile application. A redirect, a Widget finish event, or WebView navigation to /finished does not by itself confirm successful verification.

Full result

POST https://kyc.biometric.vision/api/flows/sessions/result/
curl --request POST \
  --url 'https://kyc.biometric.vision/api/flows/sessions/result/' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --compressed \
  --data '{
    "session_id": "<SESSION_ID>",
    "api_key": "<FLOW_API_KEY>"
  }'

Lightweight result

POST https://kyc.biometric.vision/api/flows/sessions/result/light/
curl --request POST \
  --url 'https://kyc.biometric.vision/api/flows/sessions/result/light/' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --compressed \
  --data '{
    "session_id": "<SESSION_ID>",
    "api_key": "<FLOW_API_KEY>"
  }'

Light is a response variant, not an HTTP method. Both endpoints above use POST with a JSON body. These routes do not support query parameters for retrieving results.

Compatibility with legacy routes

The following legacy API routes are also available in the current code. They use the same output schemas, null exclusion rules, session ownership checks, and rate limit.

Method Path Required parameters Response
GET /api/v1/flows/session/result/ In the query: session_id (UUID), flow_api_key (string), both non-null Full result
POST /api/v1/flows/session/result/ In the JSON body: session_id (UUID), api_key (string), both non-null Full result
GET /api/v1/flows/session/result/light/ In the query: session_id (UUID), flow_api_key (string), both non-null Light result

For these GET methods, the Workflow key is named flow_api_key, not api_key. POST is not defined for the legacy light route. For new integrations, use the POST routes in the examples above.

Authorization and parameters

Authorization uses api_key in the request body: the key identifies the Workflow, and session_id must belong to that Workflow. No additional Authorization or X-API-Key is required for these two methods.

Body parameter Type Required Purpose
session_id string, UUID Required, non-null Identifier returned when creating a session. Named id in the response.
api_key string Required, non-null API KEY of the Workflow that owns the session.

HTTP responses

HTTP status Body / meaning
200 Result object without an outer wrapper. This means data was retrieved successfully, not necessarily that verification succeeded.
400 {"detail":"Wrong flow"} — the session belongs to a different Workflow.
403 {"detail":"Flow session access forbidden"} — access to the session was denied.
404 The Workflow for the key or the session was not found; the error body contains detail. A deleted Workflow cannot be found by its key.
422 Request body validation error: a required field is missing, or the UUID or type is invalid. detail contains an array of validation error descriptions.
429 Rate limit exceeded. Both methods are configured with a 1/s limit; do not assume a separate limit for each session_id.
5xx Server or response generation error, including file reading errors. This is not a negative technology result.

Large responses support gzip compression (Accept-Encoding: gzip; the examples request it with --compressed).

Field interpretation rules

The tables specify the type of the value actually transmitted. If a field allows a missing value, the API excludes it from JSON; this also applies to fields in nested schemas. Therefore, result: false, a missing result, and a missing technology block are different states.

  • A required field is present when its parent object is successfully serialized.
  • When a value is available means the field allows null in the source data, but the key is excluded from the response in that case. An empty string, false, 0, {}, and [] are not removed merely because they are empty or falsy.
  • Removing null from schema fields does not mean cleaning arbitrary JSON. Within dynamic dictionaries and arrays, null may remain and differs from a missing key.
  • A missing block does not establish the cause: verification may not have started, a record may not have been created, or the technology may not be part of the session. A block may appear before verification is complete, sometimes as {}.
  • A UUID is transmitted as a string. IINs, BINs, document numbers, and phone numbers are strings: preserve leading zeros.
  • number is a JSON number; Liveness, Face2Face, and NPCK prediction scores are transmitted as strings, not numbers.

A nested field is required only when its parent object is present. Dynamic JSON has no fixed set of keys unless explicitly stated.

Response structure

The root response object.

Presence requirements are specified separately for each field. The technology result fields listed below are also fields of the root object.

Field JSON type Purpose and conditions
id string, UUID Required. Identifier of the requested session.
status string, enum Required. Session status.
flow_session_result boolean Required. Current aggregate result; see the calculation rules.
validated_at string, date-time When a value is available. Time of successful session validation before verification begins, in ISO 8601 format with a time zone; not the time the result was retrieved.
finished_at string, date-time When a value is available. Time when normal session completion was invoked, in ISO 8601 format with a time zone. Not guaranteed for every terminal status, for example automatic expiration.
technologies object[] Required; may be []. Currently active Workflow technologies in execution order; see the item structure.
request_sessions object[] Required; may be []. Unique sets of device and request information; see the item structure.
flow_session_failure_reasons object[] Required; may be []. Failure reasons for the session and selected technology results; see the item structure.

Technology results index

Individual blocks have type object and are excluded if the corresponding record does not exist. The three arrays at the end of the table are returned as [] if there are no records. Block presence depends on stored results, not only on the current technologies list.

Top-level field Result Default technology codes
liveness_result Liveness LDHP, LDSH, LDD, LDD2, LDPM, LC
face2face_result Face2Face F2F
npck_result Face comparison through NPCK / COID F2F_NPCK
document_recognition_v2_result Document Recognition v2 DR2
edocument_result E-Document ED
edocument_child_result Child E-Document EDC
mxdocument_result MxDocument MXD
mrz_result MRZ MRZ
pps_result PPS PPS
address_result Address ADR, ADR2
gbdfl_result GBDFL GBDFL, GBDFL2
gbdul_result GBDUL GBDUL
kz_info_result KZ Info KZ_INFO
erd_result ERD ERD
rpn_result RPN RPN
tunduk_result Tunduk TDK
aml_result AML AML
ds_identifier_result Digital Signature Identifier DSI, DSN
ds_signer_result Digital Signature Signer DSS
questionnaire_results Questionnaires, object[] QST
ip_check_results IP checks, object[] IP_CHECK
otp_results One-time code verification, object[] OTP

The codes in the table are defaults in the project configuration; a deployed service may override them. Different variants of a technology may share a block. This response has no separate persons_result, array of all Liveness attempts, or results for each Liveness model. Session creation metadata, session context, and validity period are also outside this contract.

Technologies

Parent: technologies[].

The list reflects the current Workflow configuration, not an immutable snapshot taken at session creation. Disabled technologies are excluded.

Field JSON type Purpose and conditions
code string Required. Technology code, for example LDD or DR2; codes are set by the service configuration and are not a closed enum in this schema.
name string Required. Technology display name.
description string Required. Technology description; may be an empty string.

Device information

Parent: request_sessions[].

Fields marked “Required” are always present within this object. Other fields are included when a value is available; null is excluded from the response.

Field JSON type Purpose and conditions
ip_address string Request IP address.
country string Country determined from the IP address; current processing stores the country code.
browser_family string Browser name / family from the User-Agent.
browser_version string Browser version.
os_family string Operating system family.
os_version string OS version.
device_family string Device family.
device_brand string Device manufacturer.
device_model string Device model.
is_bot boolean Bot detection result based on the User-Agent; not the outcome of an anti-fraud check.
device_type string Device category. The current handler produces MOBILE (smartphone), TABLET (tablet), TOUCH_CAPABLE (wearable/touch device), PC (computer), BOT (bot), or UNKNOWN (undetermined). The schema field is a free-form string.

Identical sets of all the listed values are merged; completely empty records are excluded. This is neither a request history nor an attempt count. Do not interpret the item order as the order of visits.

Session status, outcome, and errors

The session status, boolean outcome, and individual check data answer different questions.

Field: status.

The spelling and case of allowed values are shown exactly.

Field JSON type Purpose and conditions
CREATED string The session has been created.
QR string The QR handoff stage for starting verification.
PROGRESS string Verification is in progress.
FINISHED string Normal session completion.
FAILED string The session ended unsuccessfully, including due to expiration.
IN_REVIEW string A manual review decision is pending.
APPROVED string The session was approved during review.
DECLINED string The session was declined during review.

flow_session_result returns false for every status except FINISHED and APPROVED. For these two statuses, the related Workflow technology results are also checked, except for the persons technology:

  • a missing expected result relation produces false;
  • a recorded failure reason or an explicit result: false in the selected result produces false;
  • a missing result value does not by itself mean false; for a relation with multiple records, having no records is also not an independent negative condition in this calculation.

The outcome check uses Workflow technologies without the same active-only filter applied to technologies. Therefore, you cannot reconstruct flow_session_result by simply applying a logical AND to all visible result values. APPROVED also does not guarantee flow_session_result: true.

A technology's result reflects its rules and configuration. For example, AML may be accepted despite a match if rejection on a match is disabled; some checks may accept service unavailability. A failure reason may still be retained, leaving the aggregate outcome negative. KZ Info and ERD have no separate result at all: check the retrieval status, data, and error.

Failure reasons

Parents: *.failure_reason (except Address) and flow_session_failure_reasons[].

Address is an exception: address_result.failure_reason is a UUID string; see the Address section.

Field JSON type Purpose and conditions
type string Required. Error category, listed below.
detail string When a value is available. Description of the specific reason, up to 512 characters; may be absent. This is diagnostic text, not a closed enum.

Values of failure_reason.type.

flow_session_failure_reasons[].type is a free-form string that combines technology categories with session categories (OTHER, EXPIRED).

Field JSON type Purpose and conditions
TIMEOUT string The operation timed out.
NO_CAM string The camera is missing or unavailable.
CALC_RESULT string Verification failed based on calculation results.
SERVICE_ERROR string Service or external provider error.
REQUEST_ERROR string Request creation or processing error.
CLIENT string A reason arising during verification: input data, user actions, or scenario restrictions.
OTHER string Another reason.
DIFFERENT_FACES string Different faces were detected in the frames.
VR_CAM string A virtual camera was detected.
EXPIRED string The session expired; this is a general session error category, not an enum value of a technology error object.

The aggregate error array contains session errors, followed by errors from selected technology results in Workflow order. It is not a complete retry history; items have no technology code, error UUID, or timestamp. Duplicates are possible. Use the technology's own block to associate a reason with a check.

Examples of diagnostic combinations are provided in the failure reasons reference. Do not make a decision based only on detail text. result: false does not guarantee that failure_reason is present, and result: true does not guarantee that no error is present.

Incomplete sessions and retries

Retrieving results does not require a terminal status. During verification, partial data, empty arrays, and blocks without result may be available; flow_session_result: false at this point does not mean a final rejection. Statuses and dates may change in the next response.

Blocks Record selection
Liveness, both versions of Document Recognition, Address, GBDFL, GBDUL, MxDocument, Tunduk, MRZ, PPS, RPN The single most recent record by creation time, not the most recent successful record. No tie-breaking order is defined for equal timestamps.
edocument_result, edocument_child_result The most recent record selected separately for regular and child E-Document technologies.
Face2Face, NPCK, KZ Info, ERD, AML, Digital Signature Identifier and Signer One related session result; updates to this record appear in the next response.
ip_check_results, questionnaire_results, otp_results All related records. OTP records are sorted newest first; no order is defined for IP checks or questionnaires.

For the aggregate outcome and error array, relations with multiple records are evaluated using one selected record, even when the public block returns an array. For IP checks and questionnaires, do not assume this selects the most recent attempt.

E-Document, Document Recognition v2, and PPS results may be copied from a previous session when person data reuse is configured. This is indicated by status: "COPIED" and source_session. It is not a new retrieval of a document or photo. Copying depends on validity period settings and checks of the source result's eligibility.

Files in full and light responses

Field Full response Light
liveness_result.face_photo Base64 URL
document_recognition_result.images.* Base64 URL
document_recognition_v2_result.images[].content Base64 URL
edocument_result.face_photo, barcode, qrcode, document_image, document_pdf Base64 URL
edocument_child_result.face_photo, barcode, qrcode, document_image, document_pdf Base64 Base64
mxdocument_result.frontside_image, backside_image, face_photo Base64 URL
tunduk_result.photo Base64 URL
mrz_result.photo, pps_result.photos[].photo, questionnaire_results[].answers[].content URL URL
Data within dynamic JSON As stored No special replacement of nested values

Base64 contains the file bytes without a data:...;base64, prefix. For document_pdf, these are PDF bytes; image types and extensions cannot be determined from field names alone. Light preserves field names and structure, replacing values with URL strings only in the locations listed.

A file field is available when a file is associated with the result. If no file exists, the field is excluded; the legacy Document Recognition images dictionary may remain {}, and the v2 image array may remain []. Some files appear later than other data or are not generated in the selected scenario.

URLs are generated by the storage system; S3 uses signed access. The expiry time is not included in the response or fixed by this API. Do not save a URL as a permanent address: request a fresh result when needed. A URL does not guarantee that the file has not been deleted; the full response additionally requires successful file reads to generate Base64.

Registry request statuses

This table explains common status meanings. Each technology section specifies its own allowed set: not all technologies use every value.

Values of the status field for Address, GBDFL, GBDUL, PPS, and RPN.

Result enum values preserve the case shown in the table.

Field JSON type Purpose and conditions
UNAPPROVED string Consent / permission to retrieve data has not yet been confirmed.
PENDING string Waiting for a response / request execution.
VALID string Positive confirmation of data access; does not by itself guarantee that all fields are populated.
INVALID string Negative confirmation of access.
TIMEOUT string Confirmation / response timed out.
NOT_FOUND string The requested data or subject was not found.
FAILED string Retrieval / processing error.
ERROR_ACCEPTED string The error was accepted according to the scenario's continuation settings; this does not confirm data retrieval.
COPIED string The result was copied from a previous session.
SUCCESS string Data was retrieved successfully.
REQUEST_RATE_LIMIT_EXCEEDED_ERROR string The Address service request rate limit was exceeded.

Successful result

Below are two complete responses for the same illustrative Liveness session. Additional metrics were not generated, so their fields are absent. The Base64 example uses a small synthetic PNG rather than a person's photo; the light URL is fictional.

Full response

{
  "id": "11111111-1111-4111-8111-111111111111",
  "status": "FINISHED",
  "validated_at": "2026-09-01T10:00:00Z",
  "finished_at": "2026-09-01T10:01:00Z",
  "flow_session_result": true,
  "technologies": [
    {
      "code": "LDD",
      "name": "Liveness check",
      "description": "Face verification by changing distance"
    }
  ],
  "liveness_result": {
    "result": true,
    "prediction": "0.9800",
    "face_photo": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+aWQAAAABJRU5ErkJggg=="
  },
  "request_sessions": [],
  "flow_session_failure_reasons": [],
  "ip_check_results": [],
  "questionnaire_results": [],
  "otp_results": []
}

Light response

{
  "id": "11111111-1111-4111-8111-111111111111",
  "status": "FINISHED",
  "validated_at": "2026-09-01T10:00:00Z",
  "finished_at": "2026-09-01T10:01:00Z",
  "flow_session_result": true,
  "technologies": [
    {
      "code": "LDD",
      "name": "Liveness check",
      "description": "Face verification by changing distance"
    }
  ],
  "liveness_result": {
    "result": true,
    "prediction": "0.9800",
    "face_photo": "https://files.example.invalid/liveness/face.png?signature=EXAMPLE"
  },
  "request_sessions": [],
  "flow_session_failure_reasons": [],
  "ip_check_results": [],
  "questionnaire_results": [],
  "otp_results": []
}

Unsuccessful result

A complete response with a negative Liveness result. A 200 response from the method returning this JSON does not override flow_session_result: false.

{
  "id": "22222222-2222-4222-8222-222222222222",
  "status": "FAILED",
  "flow_session_result": false,
  "technologies": [
    {
      "code": "LDD",
      "name": "Liveness check",
      "description": "Face verification by changing distance"
    }
  ],
  "liveness_result": {
    "result": false,
    "failure_reason": {
      "type": "CALC_RESULT",
      "detail": "Low overall prediction"
    }
  },
  "request_sessions": [],
  "flow_session_failure_reasons": [
    {
      "type": "CALC_RESULT",
      "detail": "Low overall prediction"
    }
  ],
  "ip_check_results": [],
  "questionnaire_results": [],
  "otp_results": []
}

Intermediate response

A complete response before verification begins. The absence of the Liveness block here is expected.

{
  "id": "33333333-3333-4333-8333-333333333333",
  "status": "CREATED",
  "flow_session_result": false,
  "technologies": [
    {
      "code": "LDD",
      "name": "Liveness check",
      "description": "Face verification by changing distance"
    }
  ],
  "request_sessions": [],
  "flow_session_failure_reasons": [],
  "ip_check_results": [],
  "questionnaire_results": [],
  "otp_results": []
}

Result fragments

The JSON examples on technology pages are fragments of the root object, not complete responses. All numbers and names are illustrative; the examples are not intended to be sent to APIs that start checks.

A copied v2 recognition result in light format; dynamic text may contain null:

E-Document without files and with reused dates:

An accepted GBDUL error and an Address error in a different format:

The PPS photo remains a URL in both variants, and a file question may have no value:

Retrieved empty KZ Info and ERD responses, and completed OTP verification:

Other document and face comparison formats (light response fragments; these blocks do not have to occur in the same session):

{
  "document_recognition_result": {
    "result": true,
    "first_name": "EXAMPLE",
    "last_name": "SAMPLE",
    "images": {}
  }
}

Waiting for a registry response and retrieved information (dynamic JSON is deliberately not presented as a universal schema):

Identification, signing, and IP checks:

Process the response

  1. Check the HTTP status and associate the response id with your application and the original session_id.
  2. Consider the session status, flow_session_result, and the state of the relevant technologies. Do not treat an intermediate false as a final rejection.
  3. Distinguish missing fields, empty containers, empty strings, and explicit negative values.
  4. For files, use the full/light table; do not try to decode every file field as Base64.
  5. When requesting results again, account for updates to the selected record and newly available results. Do not use this response as a complete attempt history.