﻿---
icon: person-fill
label: Face Verification API
---

# Face Verification API

## Overview

The Face Verification API provides face detection, embedding extraction, and face comparison services for identity verification and authentication use cases.

The Face Verification API enables you to:
- Detect faces in images with bounding boxes and confidence scores
- Extract face embeddings from images for identity verification
- Compare face embeddings to verify if two faces belong to the same person
- Process multiple faces in a single image
- Utilize high-accuracy AI models for face verification

## Base URLs

| Region | Base URL |
|--------|----------|
| **EU** | `https://face-verification-api-eu.realeyes.ai/v1/` |
| **US** | `https://face-verification-api-us.realeyes.ai/v1/` |

---

## API Endpoints

### Detect Faces

Returns a list of detected faces on the provided image with their respective bounding boxes.

**Endpoint:** `POST /v1/face-verification/detect-faces`

**Authentication:** API Key or Bearer Token

**Request Body:**

```json
{
  "image": {
    "bytes": "base64-encoded-image-string",
    "url": null
  },
  "maxFaceCount": 10
}
```

**Request Parameters:**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `image` | object | Yes | The image to process |
| `image.url` | string (nullable) | No | URL of a jpeg or png image |
| `image.bytes` | string (nullable) | No | Base 64 string encoded binary jpeg or png image |
| `maxFaceCount` | integer | No | Maximum number of faces to detect in the image. Must be between 1 and 10 (default: 1); values outside this range return 400 Bad Request. |

**Response Example:**

```json
{
  "faces": [
    {
      "confidence": 0.9876,
      "boundingBox": {
        "x": 120,
        "y": 80,
        "width": 200,
        "height": 250
      }
    }
  ],
  "unprocessedFaceCount": 0
}
```

**Response Fields:**

| Field Path | Type | Description |
|------------|------|-------------|
| `faces` | array (nullable) | Faces found on the image |
| `faces[].confidence` | number | Face detection score with value range [0.0, 1.0] (higher is better) |
| `faces[].boundingBox` | object | Model for the bounding box of a detected face |
| `faces[].boundingBox.x` | integer | Horizontal position of the detected face bounding box |
| `faces[].boundingBox.y` | integer | Vertical position of the detected face bounding box |
| `faces[].boundingBox.width` | integer | Width of the detected face bounding box |
| `faces[].boundingBox.height` | integer | Height of the detected face bounding box |
| `unprocessedFaceCount` | integer | Number of faces found on the image but were not returned (because the max_faces request parameter filtered them out) |

**Example Request:**

```bash
curl -X POST "https://face-verification-api-eu.realeyes.ai/v1/face-verification/detect-faces" \
  -H "Authorization: ApiKey API-KEY-FROM-DEV-CONSOLE" \
  -H "Content-Type: application/json" \
  -d '{
    "image": {
      "bytes": "/9j/4AAQSkZJRgABAQEAYABgAAD..."
    },
    "maxFaceCount": 10
  }'
```

**Response Codes:**
- `200` - Returns the detected faces results (the `faces` array may be empty if no face is detected)
- `400` - Invalid request (no image provided, invalid base64 string, etc.)
- `401` - Missing or invalid authentication

---

### Get Face Embeddings

Returns a list of face embeddings for all the detected faces in the provided image.

**Endpoint:** `POST /v1/face-verification/get-face-embeddings`

**Authentication:** API Key or Bearer Token

**Request Body:**

```json
{
  "image": {
    "bytes": "base64-encoded-image-string",
    "url": null
  },
  "maxFaceCount": 1
}
```

**Request Parameters:**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `image` | object | Yes | The image to process |
| `image.url` | string (nullable) | No | URL of a jpeg or png image |
| `image.bytes` | string (nullable) | No | Base 64 string encoded binary jpeg or png image |
| `maxFaceCount` | integer | No | Maximum number of faces to get the embedding on. Must be between 1 and 10 (default: 1); values outside this range return 400 Bad Request. |

**Response Example:**

```json
{
  "faces": [
    {
      "face": {
        "confidence": 0.9876,
        "boundingBox": {
          "x": 120,
          "y": 80,
          "width": 200,
          "height": 250
        }
      },
      "embedding": [0.123, -0.456, 0.789]
    }
  ],
  "unprocessedFaceCount": 0
}
```

**Response Fields:**

| Field Path | Type | Description |
|------------|------|-------------|
| `faces` | array (nullable) | Faces found on the image |
| `faces[].face` | object | Model for face detection |
| `faces[].face.confidence` | number | Face detection score with value range [0.0, 1.0] (higher is better) |
| `faces[].face.boundingBox` | object | Model for the bounding box of a detected face |
| `faces[].face.boundingBox.x` | integer | Horizontal position of the detected face bounding box |
| `faces[].face.boundingBox.y` | integer | Vertical position of the detected face bounding box |
| `faces[].face.boundingBox.width` | integer | Width of the detected face bounding box |
| `faces[].face.boundingBox.height` | integer | Height of the detected face bounding box |
| `faces[].embedding` | array (nullable) | Face verification embedding of the face |
| `unprocessedFaceCount` | integer | Number of faces found on the image but were not calculated the embedding on (because the max_faces request parameter filtered them out) |

**Example Request:**

```bash
curl -X POST "https://face-verification-api-eu.realeyes.ai/v1/face-verification/get-face-embeddings" \
  -H "Authorization: ApiKey API-KEY-FROM-DEV-CONSOLE" \
  -H "Content-Type: application/json" \
  -d '{
    "image": {
      "bytes": "/9j/4AAQSkZJRgABAQEAYABgAAD..."
    },
    "maxFaceCount": 1
  }'
```

**Response Codes:**
- `200` - Returns the face embeddings results (the `faces` array may be empty if no face is detected)
- `400` - Invalid request (no image provided, invalid base64 string, etc.)
- `401` - Missing or invalid authentication

#### Embedding Format

Each `embedding` is a fixed-length vector of **512 `float32` values**. The vectors are **L2-normalized** (unit length).

The returned embeddings can be stored for later use, but they are **specific to the version of the model** that produced them. Embeddings extracted by two different model versions are **not compatible** and must not be compared with each other.

#### Comparing Embeddings

To verify whether two embeddings belong to the same person, the dedicated [Compare Face Embeddings](#compare-face-embeddings) endpoint is the recommended approach: it performs the comparison and returns the mapped similarity score (0–100) directly, removing the need for a client-side implementation.

As additional information, the comparison works as follows in detail:

- Because the vectors are already L2-normalized, the cosine similarity is simply their **dot product**, and the result lies in the range `[-1, 1]` (higher means more similar).
- The cosine similarity is compared against a **threshold**: if it is greater than or equal to the threshold, the pair is treated as a match; otherwise it is rejected.
- A higher threshold is stricter (fewer false accepts, more false rejects). **Any match below the threshold corresponding to a similarity score of 70 should be rejected.** The **recommended operating point is a similarity score of 80** (cosine similarity ≈ `0.2975`).

#### Threshold Reference

The table below maps the **similarity score** (the value returned by the Compare Face Embeddings endpoint) to the corresponding **cosine similarity threshold** and error rates.

| Similarity score    | Cosine similarity threshold | FPR (false positive rate) | TPR (true positive rate) |
|---------------------|-----------------------------|---------------------------|--------------------------|
| 100                 | `1.0000`                    | ≤ 1e-06                   | —                        |
| 95                  | `0.5899`                    | 1e-06                     | 0.612                    |
| 90                  | `0.3825`                    | 1e-05                     | 0.918                    |
| 80 _(recommended)_  | `0.2975`                    | 1e-04                     | 0.956                    |
| 70 _(minimum)_      | `0.2372`                    | 1e-03                     | 0.972                    |
| 0                   | `0.0000`                    | —                         | —                        |

> Similarity scores between the anchor points above are obtained by piecewise-linear interpolation. The FPR/TPR figures are measured at the listed thresholds.

> **Advanced guidance:** The thresholds listed above are **recommended values**, derived from extensive in-the-wild datasets, and serve as a reasonable starting point. The optimal threshold depends on the specific use case and the underlying data distribution. As datasets may differ, **fine-tuning the threshold through evaluation on representative data** is advised, in order to achieve the desired balance between false accepts and false rejects.

---

### Compare Face Embeddings

Returns the similarity between two face embeddings as an integer between 0 and 100.

**Endpoint:** `POST /v1/face-verification/compare-face-embeddings`

**Authentication:** API Key or Bearer Token

**Request Body:**

```json
{
  "embedding1": [0.123, -0.456, 0.789],
  "embedding2": [0.125, -0.450, 0.792]
}
```

**Request Parameters:**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `embedding1` | array (nullable) | Yes | Embedding to compare |
| `embedding2` | array (nullable) | Yes | Embedding to compare with |

**Response Example:**

```json
{
  "similarity": 85
}
```

**Response Fields:**

| Name | Type | Description |
|------|------|-------------|
| `similarity` | integer | Similarity between the two embeddings with value range [-1, 100] (higher is better). Reject any matches where similarity is less than 70. <br><br> See [Comparing Embeddings](#comparing-embeddings) for the methodology and the full threshold reference. |

**Example Request:**

```bash
curl -X POST "https://face-verification-api-eu.realeyes.ai/v1/face-verification/compare-face-embeddings" \
  -H "Authorization: ApiKey API-KEY-FROM-DEV-CONSOLE" \
  -H "Content-Type: application/json" \
  -d '{
    "embedding1": [0.123, -0.456, 0.789],
    "embedding2": [0.125, -0.450, 0.792]
  }'
```

**Response Codes:**
- `200` - Returns the similarity result
- `400` - Invalid request (malformed request body or invalid embeddings)
- `401` - Missing or invalid authentication

---

### Health Check

Check the API health status.

**Endpoint:** `GET /v1/healthz`

**Authentication:** None required

**Response Example:**

```
2026-02-16T10:30:45Z
```

**Response Fields:**

| Name | Type | Description |
|------|------|-------------|
| (response body) | string | The server UTC time in ISO 8601 format |

**Example Request:**

```bash
curl -X GET "https://face-verification-api-eu.realeyes.ai/v1/healthz"
```

**Response Codes:**
- `200` - API is healthy

---

## Common Response Codes

| Code | Description |
|------|-------------|
| `200` | Success |
| `400` | Bad Request - Invalid parameters |
| `401` | Unauthorized - Missing or invalid authentication |
| `403` | Forbidden - Valid authentication but account not found or insufficient permissions |
| `404` | Not Found - Resource not found |
| `500` | Internal Server Error |

---

## Swagger Documentation

Interactive API documentation is available via Swagger UI:

- **EU**: [https://face-verification-api-eu.realeyes.ai/swagger](https://face-verification-api-eu.realeyes.ai/swagger)
- **US**: [https://face-verification-api-us.realeyes.ai/swagger](https://face-verification-api-us.realeyes.ai/swagger)

---

*Last updated: 2026-02-16*

