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

# Upload faces for duplicate detection enrollment

> Mass-enroll up to 50 face images into the duplicate-detection watchlist in one asynchronous batch.

Mass-enrolls up to 50 face images into the reserved biometric duplicate-detection watchlist in one call. Each image is processed asynchronously: a Trust Validation is created for it, the face is enrolled against the engine, and — only if enrollment succeeds — the image is stored and the Trust Validation is marked Verified.

This lets you pre-seed the duplicate-detection watchlist in bulk (for example, when migrating an existing customer base) instead of enrolling one face per live verification.

Processing is asynchronous. This endpoint queues the batch and returns immediately (`202`). Poll [GET /api/v3/duplicate-detection/uploads/\{uploadId}](/api-reference/duplicate-detection/poll-upload-status) for progress and per-image results.

## Authentication

Same as all other v3 endpoints:

* **Bearer token** (Sanctum) in the `Authorization` header
* **HMAC signature** headers (`X-HMAC-SIGNATURE`, `X-TIMESTAMP`, `X-USER-ID`)

See [Introduction to the API](/api-reference/introduction) for how to create an API token.

## Request

**Content-Type:** `multipart/form-data`

| Field      | Type           | Required | Notes                                                 |
| ---------- | -------------- | -------- | ----------------------------------------------------- |
| `images`   | array of files | Yes      | 1–50 files (configurable batch size, default 50)      |
| `images[]` | file           | Yes      | jpg, jpeg, or png only; max 10 MB each (configurable) |

Example form fields: `images[0]`, `images[1]`, `images[2]`, …

## Example cURL

```bash theme={null}
curl -X POST https://api.idmetagroup.com/api/v3/duplicate-detection/faces \
  -H "Authorization: Bearer {token}" \
  -F "images[0]=@face1.jpg" \
  -F "images[1]=@face2.jpg"
```

## Responses

### 202 Accepted — batch queued

```json theme={null}
{
  "success": true,
  "message": "Face upload accepted and queued for duplicate detection enrollment",
  "data": {
    "uploadId": "3aa8f48e-8a62-4439-82b9-bc3ae4b176a2",
    "trustFlowId": 409,
    "numberOfImages": 12,
    "status": 1,
    "statusLabel": "Processing"
  }
}
```

| Field                    | Description                                                                               |
| ------------------------ | ----------------------------------------------------------------------------------------- |
| `uploadId`               | Pass this to the polling endpoint.                                                        |
| `trustFlowId`            | The internal system Trust Flow all resulting Trust Validations belong to (informational). |
| `status` / `statusLabel` | The batch is always **Processing** (`1`) immediately after submission.                    |

### 422 Validation error (bad file count / type / size)

```json theme={null}
{
  "success": false,
  "message": "Validation error",
  "errors": {
    "images": ["The images must not have more than 50 items."]
  }
}
```

The `errors` object follows the standard Laravel validation error shape. Keys are `images` or `images.0`, `images.1`, etc.

### 422 Company storage not configured

```json theme={null}
{
  "success": false,
  "message": "Company storage is not configured"
}
```

### 422 Biometrics Registration not enabled

```json theme={null}
{
  "success": false,
  "message": "Biometrics Registration is not enabled for this company"
}
```

### 503 Queue unavailable

```json theme={null}
{
  "success": false,
  "message": "Enrollment queue is unavailable. Please retry shortly."
}
```

Transient — safe to retry.

## Behavioral notes

* **Billing:** This endpoint is free. No plan credit is consumed per image, unlike the single-image [Biometrics Detection](/api-reference/compliance/biometrics-registration/overview) endpoint.
* **Screening:** Images are enrolled only. They are not screened against other watchlists at upload time — no duplicate or blacklist match results are returned here.
* **Per-image failures:** If enrollment fails (poor quality, no face detected, etc.), no Trust Validation or image is kept for that image. The failure is reported via the polling endpoint with a human-readable reason.
* **Successful enrollments:** Each enrolled face gets a real Trust Validation that appears in your normal Trust Validations list and can later be matched against by other verifications that screen the duplicate-detection watchlist.

## Error responses

| Code  | When                                                                                                                 |
| ----- | -------------------------------------------------------------------------------------------------------------------- |
| `202` | Batch queued successfully                                                                                            |
| `422` | Validation error (file count, type, or size), company storage not configured, or Biometrics Registration not enabled |
| `503` | Enrollment queue unavailable — retry shortly                                                                         |


## OpenAPI

````yaml api-reference/duplicate-detection/duplicate-detection.openapi.json POST /api/v3/duplicate-detection/faces
openapi: 3.0.3
info:
  title: Duplicate Detection — Face Enrollment API
  description: >-
    Mass-enroll face images into the reserved biometric duplicate-detection
    watchlist. Enrollment is asynchronous.
  version: 1.0.0
servers:
  - url: https://{environment-subdomain}.idmetagroup.com
    description: Your environment (replace `{environment-subdomain}`)
    variables:
      environment-subdomain:
        default: integrate
        description: IDmeta environment subdomain
security:
  - bearerAuth: []
tags:
  - name: Duplicate Detection
    description: Mass-enroll faces into the duplicate-detection watchlist
paths:
  /api/v3/duplicate-detection/faces:
    post:
      tags:
        - Duplicate Detection
      summary: Upload faces for duplicate detection enrollment
      description: >-
        Mass-enrolls up to 50 face images into the reserved biometric
        duplicate-detection watchlist in one call. Processing is asynchronous —
        the batch is queued and returns immediately. Poll GET
        /api/v3/duplicate-detection/uploads/{uploadId} for progress and results.
      operationId: uploadDuplicateDetectionFaces
      parameters:
        - name: Authorization
          in: header
          required: true
          schema:
            type: string
            example: Bearer {your_api_token}
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - images
              properties:
                images:
                  type: array
                  description: >-
                    1–50 image files. Accepted formats: jpg, jpeg, png. Max 10
                    MB each. Use form fields images[0], images[1], etc.
                  items:
                    type: string
                    format: binary
                  minItems: 1
                  maxItems: 50
      responses:
        '202':
          description: Face upload accepted and queued for duplicate detection enrollment
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UploadFacesResponse'
              example:
                success: true
                message: >-
                  Face upload accepted and queued for duplicate detection
                  enrollment
                data:
                  uploadId: 3aa8f48e-8a62-4439-82b9-bc3ae4b176a2
                  trustFlowId: 409
                  numberOfImages: 12
                  status: 1
                  statusLabel: Processing
        '422':
          description: >-
            Validation error, company storage not configured, or Biometrics
            Registration not enabled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                validationError:
                  summary: Validation error
                  value:
                    success: false
                    message: Validation error
                    errors:
                      images:
                        - The images must not have more than 50 items.
                storageNotConfigured:
                  summary: Company storage not configured
                  value:
                    success: false
                    message: Company storage is not configured
                biometricsRegistrationDisabled:
                  summary: Biometrics Registration not enabled
                  value:
                    success: false
                    message: Biometrics Registration is not enabled for this company
        '503':
          description: Enrollment queue is unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                success: false
                message: Enrollment queue is unavailable. Please retry shortly.
components:
  schemas:
    UploadFacesResponse:
      type: object
      properties:
        success:
          type: boolean
        message:
          type: string
        data:
          $ref: '#/components/schemas/UploadFacesData'
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
        message:
          type: string
        errors:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
          description: >-
            Laravel validation error shape. Keys are `images` or `images.0`,
            `images.1`, etc.
    UploadFacesData:
      type: object
      properties:
        uploadId:
          type: string
          format: uuid
          description: Pass this to GET /api/v3/duplicate-detection/uploads/{uploadId}.
        trustFlowId:
          type: integer
          description: >-
            The internal system Trust Flow all resulting Trust Validations
            belong to (informational).
        numberOfImages:
          type: integer
        status:
          type: integer
          description: Batch status. Always `1` (Processing) immediately after submission.
        statusLabel:
          type: string
          description: Human-readable status label.
          example: Processing
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Use `Bearer {your_api_token}` in the Authorization header, or HMAC
        signature headers (`X-HMAC-SIGNATURE`, `X-TIMESTAMP`, `X-USER-ID`). Same
        authentication as other v3 endpoints.

````