> For the complete documentation index, see [llms.txt](https://doc.ozforensics.com/oz-knowledge/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://doc.ozforensics.com/oz-knowledge/general/integration-quick-start-guides/how-to-perform-a-face-matching-analysis.md).

# How to Perform a Face Matching Analysis

This article covers the use case when you need to perform face matching with an external photo while using [OzCapsula](/oz-knowledge/guides/developer-guide/api/oz-api/ozcapsula-data-container.md) for data transmission. Here is what you need to do.

1. Depending on the API configuration:
   1. [Instant API](/oz-knowledge/guides/developer-guide/api/oz-api/instant-api-non-persistent-mode.md): run a Liveness analysis using OzCapsula with the [best shot](/oz-knowledge/guides/developer-guide/api/oz-api/basic-scenarios/liveness/best-shot.md) extraction enabled. This best shot is then used for comparison.
   2. Full API: launch a regular Liveness analysis.
2. Run a face matching request without OzCapsula. Matching happens on the backend, so secure data transmission isn't needed.

The instructions below show how to adjust the flow for each API configuration.

## Instant API

{% stepper %}
{% step %}

### Run the Liveness Analysis with Best Shot

The best shot is a frame from the Liveness video where the face is most clearly seen. When best shot extraction is enabled, the server selects this frame during the Quality (Liveness) analysis and stores it in the same folder as the source video, so it can be reused as input for the face matching (Biometry) analysis without recapturing media.

#### 1.1. Enable Best Shot Extraction

This section describes where to switch on the best shot extraction in each Oz SDK.

{% tabs %}
{% tab title="Android SDK" %}
Add `extract_best_shot` to the `params` map of the `AnalysisProfile` whose `type` is `QUALITY`, inside `CaptureRequest.analysisProfileList`.

```kotlin
val livenessProfile = AnalysisProfile(
    mediaList = listOf(
        MediaRequest(
            id = UUID.randomUUID().toString(),
            actionMedia = OzAction.Smile
        )
    ),
    type = "QUALITY",
    params = mapOf("extract_best_shot" to true)
)

val captureRequest = CaptureRequest(
    analysisProfileList = listOf(livenessProfile)
)
```

After this, run `createMediaCaptureScreen(captureRequest, session_token)` to get the data container and send it to analysis with `addContainer(container)` — exactly as in the standard OzCapsula flow.
{% endtab %}

{% tab title="iOS SDK" %}
Add `extract_best_shot` to the `params` of the `AnalysisProfile` whose `type` is `.quality`, inside `CaptureRequest.analysisProfileList`.

```swift
let livenessProfile = AnalysisProfile(
    mediaList: [
        MediaRequest(
            id: UUID().uuidString,
            actionMedia: .smile
        )
    ],
    type: .quality,
    params: ["extract_best_shot": true]
)

let captureRequest = CaptureRequest(
    analysisProfileList: [livenessProfile]
)
```

After this, run `createMediaCaptureScreen(request: captureRequest, session_token: token)` to get the data container and send it to analysis with `addContainer(container)`.
{% endtab %}

{% tab title="Web SDK" %}
Add `extract_best_shot` to the `params` of the object passed to `OzLiveness.open()`. Unlike the mobile SDKs, this parameter sits at the top level of the launch options, not nested per analysis, and works the same way regardless of whether you use the OzCapsula data container or the legacy flow.

```javascript
OzLiveness.open({
    session_token,                 // required for OzCapsula (Web SDK 1.9.2+)
    action: ['video_selfie_blank'],
    params: {
        extract_best_shot: true
    },
    // ... other options
});
```

{% endtab %}
{% endtabs %}

#### 1.2. Obtain Media for Comparison

Instant API returns the best shot in the base64 format. In the response, you will find it in `folder.analyses.results_media` → `output_images` → `image_b64`. Decode the base64 best shot from the Liveness response and save it as a file (e.g., `best_shot.jpeg`).
{% endstep %}

{% step %}

### Run the Face Matching Analysis

Face matching is launched directly via Oz API, without the SDK capture step.

Call `POST /api/instant/folders/` with your reference photo and the best shot you've obtained from the Liveness analysis as shown in 1.2.

{% hint style="warning" %}
Your media file keys and the corresponding filenames must match.
{% endhint %}

{% code title="Request body" %}

```json
{
  "media:tags": {
    "UUID_of_reference_photo.jpeg": ["photo_selfie"],
    "best_shot.jpeg": ["photo_selfie"]
  },
  "analyses": [
    { "type": "biometry" }
  ]
}
```

{% endcode %}

The response will contain the result of the biometry analysis.
{% endstep %}
{% endstepper %}

***

## Full API

{% stepper %}
{% step %}

### Run the Liveness Analysis

{% tabs %}
{% tab title="Android SDK" %}

```kotlin
val livenessProfile = AnalysisProfile(
    mediaList = listOf(
        MediaRequest(
            id = UUID.randomUUID().toString(),
            actionMedia = OzAction.Smile
        )
    ),
    type = "QUALITY"
)

val captureRequest = CaptureRequest(
    analysisProfileList = listOf(livenessProfile)
)
```

After this, run `createMediaCaptureScreen(captureRequest, session_token)` to get the data container and send it to analysis with `addContainer(container)` — exactly as in the standard OzCapsula flow.
{% endtab %}

{% tab title="iOS SDK" %}

```swift
let livenessProfile = AnalysisProfile(
    mediaList: [
        MediaRequest(
            id: UUID().uuidString,
            actionMedia: .smile
        )
    ],
    type: .quality
)

let captureRequest = CaptureRequest(
    analysisProfileList: [livenessProfile]
)
```

After this, run `createMediaCaptureScreen(request: captureRequest, session_token: token)` to get the data container and send it to analysis with `addContainer(container)`.
{% endtab %}

{% tab title="Web SDK" %}

```javascript
OzLiveness.open({
    session_token,                 // required for OzCapsula (Web SDK 1.9.2+)
    action: ['video_selfie_blank'],
    // ... other options
});
```

{% endtab %}
{% endtabs %}

From the response, you need `folder_id` and the original name of your media file (video that has been taken) which is in `folder.media` → `original_name`.
{% endstep %}

{% step %}

### Run the Face Matching Analysis

{% stepper %}
{% step %}

#### Add your reference photo to the folder

Add your reference photo to the folder identified by the `folder_id` from the response of your Liveness request: `POST /api/folders/{{folder_id}}/media/`.

{% code title="Request body" %}

```json
{
  "media:tags": {
    "UUID_of_reference_photo.jpeg": ["photo_selfie"]
  }
}
```

{% endcode %}
{% endstep %}

{% step %}

#### Call Oz API with the Folder ID

Call Oz API `POST /api/folders/{{folder_id}}/analyses/` with `folder_id` from the response of your Liveness request (**Step 1**). Set biometry as the analysis type and define what media files to compare in the `source_media` section. Use the original name and extension of your media file from **Step 1**, e.g., `original_name.zip` or `original_name.mp4`.

{% code title="Request body" %}

```json
{
  "analyses": [
    {
      "type": "biometry",
      "source_media": [
        <original_name_with_extension>,
        <UUID_of_reference_photo.jpeg>
      ]
    }
  ]
}
```

{% endcode %}

The response will contain the result of the biometry analysis.
{% endstep %}
{% endstepper %}
{% endstep %}
{% endstepper %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://doc.ozforensics.com/oz-knowledge/general/integration-quick-start-guides/how-to-perform-a-face-matching-analysis.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
