How to Integrate Oz Liveness Using the Non-Persistent Oz API Mode
This guide walks you through the full integration: getting a session token, capturing media with the SDK, sending the resulting OzCapsula container to Oz API Instant, reading the response, making the accept/reject decision, reducing the response size, and running minimal diagnostics.
This flow combines three things:
Capture mode – the Web SDK (or Mobile SDK) captures the Liveness video in the browser/app and the Client backend forwards it to Oz API. Capture results are not sent from the SDK straight to Oz API; the Client backend acts as an intermediary.
OzCapsula – a proprietary encrypted binary container. The SDK packages captured media and metadata into it; Oz API decrypts and processes it. It protects the captured data from tampering between the user's device and Oz API. The container is an opaque encrypted blob. You cannot decode it, inspect it, or extract individual images / frames / metadata from it on the device. It must be forwarded as-is to your backend. If you need access to captured images (e.g., the best shot), retrieve them from the Oz API analysis response on the server side.
Instant API – the non-persistent mode of Oz API. Results are returned immediately in the response and nothing is stored.
Together: the SDK captures and packages media into OzCapsula → your backend forwards the container to Oz API Instant → Oz API returns the result synchronously, storing nothing.
Glossary
A few terms used throughout this guide:
{{host}}– the base URL of your Oz API deployment. Provided to you during deployment setup.Session token – a short-lived token that ties an OzCapsula to a specific capture session, preventing replay of the same container later. Mandatory for OzCapsula.
Folder – the response object Oz API creates for a single submission. It groups the submitted media and the analyses that were applied to them.
Analysis type – what Oz API runs on the media. The API returns
QUALITYfor Liveness analyses andBIOMETRYfor Face Matching analyses.
Component versions
Oz API
6.6.1
Mobile SDKs (iOS, Android)
10.0.0
Web SDK
1.9.10
Get a session token
OzCapsula requires a session token for each capture session.
To enable the session token functionality, generate a pair of JWT keys. Please find the instructions on how to create them in the API Instant helm chart: proceed to readme.md and, in the Preparation section, locate sub-section Create a JWT secret. Once you have keys, create a folder within your installation, place keys there, and put this path into API_KEYS_DIR (e.g., API_KEYS_DIR=/opt/oz/api/keys). This should be done once for the installation.
Request a session token from Oz API Instant. Request it before each capture session, as close to the moment the user starts capture as possible.
Endpoint:
Headers:
Content-Type: application/json
Request:
Response:
The token is short-lived (default lifetime: 900 seconds). Request one per capture session and pass it to the SDK immediately – do not cache or reuse tokens across sessions.
Authorization mechanism for the call to Oz API depends on installation, by default, no access token is required in the headers. If it is required in your case, please check Authentication.
Capture and package on the device
The SDK captures media from the user and packages it into an OzCapsula container.
Mobile SDK (iOS, Android)
Launch analysis with the session token. The container is returned through the result callback.
Android (Kotlin)
iOS (Swift)
The container is returned as a bytearray (Android) or DataContainer (iOS). Forward it to your backend without any transformation.
Web SDK
Call OzLiveness.Open() with the session token. When capture completes, the SDK fires the on_capture_complete callback. The container is delivered as the second argument.
The container arrives as a Blob with MIME type application/octet-stream. Forward it to your backend without any transformation.
Liveness analysis: send the container to Instant API
Your backend submits the container in a single synchronous POST request.
Endpoint:
Headers:
Content-Type: application/octet-stream(mandatory)
Request body: the raw container bytes – no JSON envelope, no multipart, no base64 wrapping.
On success: HTTP 201 with a JSON folder object describing the result.
On container-level error: HTTP 400 (see Non-success outcomes).
The QUALITY (liveness) analysis provides the best shot. Locate the QUALITY entry in the analyses[] array and read:
The value is a base64-encoded JPEG. Decode it to JPEG.
Biometry (Face Matching) analysis (optional)
If you don't need face matching, skip this step and go straight to Step 5.
Call POST /api/instant/folders/ with your reference photo and the best shot you've obtained from the Liveness analysis at Step 3.
Your media file keys and the corresponding filenames must match.
Request body:
The response will contain the result of the biometry analysis.
Read the response
Top-level fields
folder_id
Unique identifier of the request
resolution_status
Whether processing completed: FINISHED or FAILED
system_resolution
Overall result: SUCCESS, DECLINED, or FAILED
resolution_comment
Note about the analysis resolution. Useful on FAILED (lists which analyses failed)
meta_data
Metadata block. The block contains event_session_id, the session identifier which is required for tracing the request back to the user session in your frontend
media
Media files submitted in the container
analyses
Array of per-analysis results
Inside analyses[]
analyses[]type
QUALITY for liveness, BIOMETRY for face matching
state
Processing state of this analysis: FINISHED or FAILED
resolution_status
Outcome of this analysis: SUCCESS, DECLINED, or FAILED
error_code, error_message
Shown only when the analysis failed technically
results_data
Aggregated result values
results_media
Generated media items. For the QUALITY analysis, contains the best shot in output_images[] – see Step 3
source_media
Input media
Make the accept/reject decision
Use only these two top-level fields:
Interpret system_resolution:
SUCCESS– all checks passed; accept the user.DECLINED– one or more checks failed; reject the user.FAILED– a system error prevented at least one analysis from completing; do not treat as accept or reject (see Non-success outcomes).
For per-analysis verdicts (for example, to know whether liveness passed but biometry failed), read $.analyses[*].resolution_status with the same three values.
Other fields
The response also contains internal identifiers (group_id, media_association_id), file hashes, operator-related fields (operator_comment, operator_status, is_cleared), and other system fields. They are not needed for the integration flow described in this guide.
Non-success outcomes
Invalid container – HTTP 400
400When the container fails validation, Oz API responds with HTTP 400 and error_message: "Invalid request data". The specific error_code indicates the cause:
error_code
Condition
3
Missing payload
4
No media in the container
5
Container is damaged
13
No container in the request
14
Invalid container – any reason (decryption, signature, hash, or session_token validation failure)
Codes 13 and 14 fire before the container is unpackaged; codes 3, 4, 5 fire after unpackaging when the payload itself fails business-level validation.
For code 14, send the container instance and the error_code to Oz Forensics support – the specific cause is only available in server-side logs.
Declined – HTTP 201
201The container was valid and the analyses ran, but at least one check did not pass.
resolution_status: FINISHED.system_resolution: DECLINED.resolution_comment: "[]"(not informative – the decline reason is implicit in the per-analysis result).Per-analysis
resolution_status: DECLINED.
Failed – HTTP 201
201A system error prevented at least one analysis from completing.
resolution_status: FAILED.system_resolution: FAILED.resolution_comment– string listing which analyses failed and with what code.Per-analysis
state: FAILED,resolution_status: FAILED,error_codeanderror_messagepopulated.
Last updated
Was this helpful?
