> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vu-one.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Integration guide

> How to integrate Face Analysis: prepare the images, align operations with images, build the call, and validate the integration before production.

## The flow in four steps

<Steps>
  <Step title="Verify connectivity">
    `GET /version` with your `Api-Key` (it doesn't require it, but this way you test the full header). It must return `200`. Check the status code, not the body: its format is not part of the contract. If it fails, the problem is URL, network or proxy — there is nothing to debug on the API side yet.
  </Step>

  <Step title="Prepare the images">
    JPEG or PNG, base64 **without** the `data:` prefix and without line breaks. One face per image, frontal, well lit.
  </Step>

  <Step title="Declare the operations">
    `operations` is a **list of lists aligned with `images`**: `operations[i]` applies to `images[i]`. If you omit it, every image runs `biometric` by default.
  </Step>

  <Step title="Decide with the rule in the positive">
    `status === 200 && biometric["0"]["1"] >= 70` confirms; anything else does not. The threshold details are in the [introduction](/en/vucs/face-analysis/introduction).
  </Step>
</Steps>

## Image requirements

| Aspect | Requirement |
| - | - |
| Hard minimum resolution | **160 × 160 px** — below that, the service returns `400`. |
| Recommended resolution | **≥ 360 × 360 px** — below 360, the quality verdict is automatically degraded to `low`, even though the HTTP code stays `200`. |
| Face | Exactly one per image, frontal, eyes visible. |
| Compression | JPEG quality **≥ 90**. Aggressive compression degrades both attributes and the biometric score. |
| Encoding | Standard base64, no `data:` prefix, no line breaks. |

To convert an image to base64:

<CodeGroup>
  ```powershell Windows (PowerShell) theme={null}
  [Convert]::ToBase64String([IO.File]::ReadAllBytes('C:\path\selfie.jpg')) | Set-Clipboard
  ```

  ```bash Linux theme={null}
  base64 -w0 selfie.jpg
  ```

  ```bash macOS theme={null}
  base64 -i selfie.jpg | pbcopy
  ```
</CodeGroup>

## The request body

| Field | Type | What it does |
| - | - | - |
| `info` | string, **required** | Your operation reference, 2 to 256 characters. Echoed back verbatim. |
| `images` | string\[], **required** | The images in base64. |
| `operations` | string\[]\[] | The per-image operations, aligned with `images`. Omitted ⇒ `biometric` for all. |
| `faceVectors` | number\[]\[] | Stored biometric vectors (512 values) to compare against the images. They continue the numbering after the images. |
| `distanceMethodology` | string | `vu_v4` (default), `cosine` or `euclidean_l2`. Changes the **scale** of the score. |
| `returnFaceVector` | boolean | Returns each face's 512-value vector, to store and compare later without the photo. |
| `returnFaceImage` | boolean | Returns the aligned face crop in base64. |
| `events` | boolean | Adds the internal execution trace. Diagnostics only. |

<Warning>
  **A misaligned `operations` is not a tidy `400`.** An `operations` list shorter than `images` produces a `500` with a **plain-text** body (`Internal Server Error`), and omitting `images` does too. Validate the alignment before calling; those errors are caused by your request and retrying returns exactly the same thing.
</Warning>

## The three ways to compare

```json theme={null}
// 1. Selfie vs document photo: two images
{ "info": "op-1", "images": ["<selfie>", "<docFace>"], "operations": [["biometric"], ["biometric"]] }

// 2. Selfie vs stored vector: one image + one faceVector
//    The vector continues the numbering: the selfie is "0", the vector is "1".
{ "info": "op-2", "images": ["<selfie>"], "faceVectors": [[0.031, -0.114, "...512 values"]] }

// 3. Enrolling: request the vector to store it
{ "info": "op-3", "images": ["<selfie>"], "returnFaceVector": true }
```

<Note>
  If you store vectors to compare later, also store **which methodology** generated them and always compare with the same one. A `vu_v4` vector compared with `euclidean_l2` yields scores on another scale and your threshold stops being valid.
</Note>

## A batch does not tolerate partial failures

If you send 4 images and the third has no face, you do not get 3 results and one error: you get **a single `400`** with `imageNumber: 2` (0-based) and no results at all. There are no partial results. If your flow tolerates per-image failures, send one request per image.

## Timeouts and retries

| Situation | Policy |
| - | - |
| Read timeout | **30 s** — every image in the batch adds processing time. |
| Sporadic `500` | Retry with backoff, maximum 2 attempts. |
| `500` that repeats identically | It is your request (`images` missing or `operations` misaligned). Do not retry: fix it. |
| No-match or `spoofing: true` | **Never** retry with the same image: the result is deterministic. |
| `400` / `401` / `422` | Do not retry: fix the request or the credential. |

## Before going to production

1. `GET /version` returns `200` from your production connectivity.
2. Your verification condition requires `200` **and** a score ≥ 70 on `biometric["0"]["1"]`, and an unexpected response does not approve by exclusion.
3. If you changed `distanceMethodology`, you calibrated your own threshold and did not reuse 70.
4. Your deserializer indexes results by **string** (`"0"`, `"1"`) and tolerates `inferenceConfidence` with or without `code`/`confidence`.
5. Your HTTP client tolerates error bodies **that are not JSON** (the plain-text 500s).
6. `operations` has exactly one entry per image.
7. Images are at least 360 × 360 and JPEG quality is ≥ 90.
8. You never retry a no-match or a `spoofing: true` with the same image.
9. The api-key lives in your backend, never in the mobile app or front-end.
10. You send your own `info` per operation and log the `id` of every response.
11. `events` stays disabled in production: the trace is for diagnostics.

<Card title="Next: Responses" icon="list-check" href="/en/vucs/face-analysis/responses">
  The biometric matrix field by field, the quality verdict that changes shape, and the nested antispoofing.
</Card>


## Related topics

- [Integration guide](/en/vucs/id-analysis/integration.md)
- [Identity Link API: Integration Guide](/en/identity-link/introduction.md)
- [Create and Manage Verification Links](/en/identity-link/links.md)
- [Identity Link Webhooks: Verification Lifecycle Events](/en/identity-link/webhooks.md)
- [Authenticate with OAuth2 Client Credentials](/en/identity-link/authentication.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.