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

# Informe de búsqueda facial 1:N: JSON de coincidencias

> Informe de búsqueda facial 1:N de Didit: IDs de sesión coincidentes, porcentajes de similitud, marcas de lista de bloqueo y datos del usuario.

## Descripción general

Búsqueda facial es una búsqueda biométrica **1:N**: Didit toma el rostro detectado más grande de tu `user_image` y lo busca en el índice de búsqueda facial de tu aplicación. Ese índice contiene los rostros registrados a partir de sesiones de verificación, llamadas independientes a la API guardadas, rostros subidos directamente a perfiles de usuario y tus listas de bloqueo y de permitidos. Se diferencia de Coincidencia facial, que es **1:1**: Coincidencia facial compara una selfie con el retrato de un documento concreto, mientras que Búsqueda facial responde a la pregunta "¿hemos visto a esta persona antes en algún lugar?".

Conviene entender dos comportamientos antes de analizar el informe:

* **Solo las coincidencias con la lista de bloqueo provocan un rechazo.** `face_search.status` es `Declined` solo cuando se dispara una advertencia `FACE_IN_BLOCKLIST` o `POSSIBLE_FACE_IN_BLOCKLIST`. Las coincidencias duplicadas por sí solas devuelven `Approved`, así que revisa `matches` y `warnings`, no solo `status`.
* **Persistencia y registro opcionales.** Cuando `save_api_request=true` (el valor predeterminado), la llamada se guarda como una sesión de tipo API y el rostro buscado se registra en tu índice de búsqueda facial. Los rostros registrados mediante llamadas a Búsqueda facial **se excluyen de los resultados de futuras búsquedas faciales**, de modo que las búsquedas repetidas nunca coinciden entre sí. Pasa `save_api_request=false` para hacer una consulta puntual: no se almacena nada y el rostro no se registra.

## Dónde aparecen los resultados

Face Search es una API independiente. Los resultados de la búsqueda se devuelven **de forma síncrona y solo en la respuesta de `POST /v3/face-search/`**, como un único objeto `face_search` en el nivel superior:

```text theme={null}
POST /v3/face-search/  ──▶  { "request_id": …, "face_search": { … }, "vendor_data": …, "metadata": …, "created_at": … }
```

No existe ningún array plural `face_searches[]`. La convención de arrays en plural que usan `id_verifications[]`, `aml_screenings[]` y `liveness_checks[]` en el endpoint de decisión de sesión no se aplica aquí.

Cuando `save_api_request=true` (el valor predeterminado), la llamada también se guarda como una sesión de tipo API:

* **Business Console**: la sesión aparece en tu lista de sesiones con la imagen de búsqueda, las coincidencias y las advertencias.
* **`GET /v3/session/{sessionId}/decision/`**: puedes recuperarla usando el `request_id` devuelto como id de sesión. Los datos guardados aparecen como una entrada `FACE_SEARCH` en `features[]` y como un elemento de `liveness_checks[]` que contiene los `matches` almacenados (con valores de `match_image_url` recién firmados) y las `warnings`, **no** como un objeto `face_search`.

Cuando `save_api_request=false`, `request_id` es un UUID de correlación transitorio: la sesión nunca se almacena, por lo que no se puede consultar desde la Consola ni desde el endpoint de decisión.

## Esquema

Consulta [Búsqueda facial en la referencia de modelos de datos](https://docs.didit.me/es/reference/data-models.md#búsqueda-facial) para ver las tablas de campos canónicas. La estructura siguiente refleja lo que el endpoint devuelve realmente en tiempo de ejecución.

```typescript theme={null}
interface FaceSearchResponse {
  request_id: string;            // UUID — the persisted session id when save_api_request=true
  face_search: {
    status: 'Approved' | 'Declined';
    total_matches: number;       // 0-5, length of matches[]
    matches: FaceSearchMatch[];  // capped at 5, ordered by similarity
    user_image: {                // always present
      entities: {
        bbox: [number, number, number, number];
        confidence: number;      // 0-1, one entry per detected face
      }[];
      best_angle: 0 | 90 | 180 | 270;
    };
    warnings: Warning[];
  };
  vendor_data: string | null;    // echoed from the request
  metadata: object | null;       // echoed from the request
  created_at: string;            // ISO 8601, e.g. "2026-06-12T01:04:42.763237+00:00"
}

interface FaceSearchMatch {
  session_id: string | null;     // UUID of the matched session; null for non-session matches
  session_number: number | null; // Console-friendly number; null for non-session matches
  similarity_percentage: number; // 0-100
  source: 'session' | 'imported' | 'list_entry' | 'retained_template';
  vendor_data: string | null;    // the matched session's, imported profile's, or retained template's User vendor_data
  vendor_user_id: string | null; // UUID of the linked User; null for list_entry matches and sessions without a User
  biometric_template_id: string | null; // set only for retained_template matches
  verification_date: string | null;  // "YYYY-MM-DDThh:mm:ssZ"; null for list_entry matches; the retention date for retained_template matches
  user_details: {
    full_name: string | null;
    document_type: string | null;
    document_number: string | null;
  } | null;                      // null when the matched session has no document data
  match_image_url: string | null; // signed URL when save_api_request=true; raw storage path otherwise; null for retained_template matches
  status: 'Approved' | 'Declined' | 'In Review' | null;  // the matched session's status
  is_blocklisted: boolean;
  is_allowlisted: boolean;
  api_service: 'ID_VERIFICATION' | 'FACE_MATCH' | 'AGE_ESTIMATION' | 'POA' | 'AML'
             | 'PASSIVE_LIVENESS' | 'DATABASE_VALIDATION' | 'PHONE_VERIFICATION'
             | 'EMAIL_VERIFICATION' | null;  // null when the match comes from a workflow session
}

interface Warning {
  risk: string;
  feature: 'LIVENESS';           // always LIVENESS on this endpoint
  additional_data: object | null;
  log_type: 'error' | 'warning' | 'information';
  short_description: string;
  long_description: string;
}
```

Notas sobre los campos:

* **`matches[]` tiene un máximo de 5** entradas por encima del umbral mínimo de similitud, ordenadas por similitud descendente (`search_type=blocklisted_or_approved` coloca primero las entradas de la lista de bloqueo, después las de la lista de permitidos y luego ordena por similitud).
* **`source`** indica de dónde se registró el rostro coincidente: `session` es una sesión de verificación o una invocación guardada de la API independiente; `imported` es un rostro subido directamente a un perfil de usuario; `list_entry` es un rostro asociado a una de tus listas; `retained_template` es una [plantilla biométrica](https://docs.didit.me/es/management-api/biometric-templates/overview.md) sin imagen que la aplicación conservó tras eliminar la sesión de origen. `session_id`, `session_number`, `status` y `api_service` son `null` en las coincidencias `imported`, `list_entry` y `retained_template`.
* **Las coincidencias `retained_template`** incluyen `vendor_user_id`, `vendor_data` y `biometric_template_id`, y siempre tienen `null` en `match_image_url`, `user_details` y todo lo relacionado con la sesión: la sesión que generó el rostro ya no existe y la plantilla no contiene ninguna imagen ni datos de identidad. `is_blocklisted` es siempre `false` en una plantilla conservada; un rostro de la lista de bloqueo se informa por separado como una coincidencia `list_entry`. Elimina la plantilla con `DELETE /v3/biometric-templates/{biometric_template_id}/`.
* **`api_service`** es el tipo de API independiente de la sesión coincidente (en mayúsculas, por ejemplo `PASSIVE_LIVENESS`) y es `null` cuando el rostro coincidente procede de una sesión de verificación de un flujo de trabajo normal.
* **`user_details`** procede de la verificación de documento de la sesión coincidente. En las coincidencias `source: imported` se rellena con los datos del perfil de usuario (`full_name` definido, `document_type`/`document_number` nulos); es `null` cuando no existen datos de identidad (por ejemplo, en sesiones solo de prueba de vida).
* **Las advertencias usan una estructura reducida** en comparación con las advertencias de los flujos: no incluyen `node_id`. El contrato de respuesta documentado (`FaceSearchResponseSerializer`) declara cinco campos: `risk`, `additional_data`, `log_type`, `short_description` y `long_description`. El payload en tiempo de ejecución incluye además `feature`, que aquí siempre es `"LIVENESS"`. Consulta [Advertencias de Búsqueda facial](https://docs.didit.me/es/core-technology/face-search/warnings-face-search.md).
* **Las coincidencias del mismo usuario no se excluyen.** A diferencia de la detección de duplicados de los flujos, el endpoint independiente no filtra las sesiones anteriores con el mismo `vendor_data`, por lo que un usuario legítimo que vuelve coincide con sus propias sesiones anteriores.

## Valores de estado

El `face_search.status` de nivel superior se deriva de `warnings[]`. El `status` de cada coincidencia refleja el resultado de verificación de la **sesión coincidente** y es independiente.

| Valor | Cuándo aparece |
| - | - |
| `Approved` | No se disparó ninguna advertencia de lista de bloqueo. Incluye el caso en que se encontraron coincidencias duplicadas: los duplicados son señales informativas, no rechazos. |
| `Declined` | Se disparó una advertencia `FACE_IN_BLOCKLIST` o `POSSIBLE_FACE_IN_BLOCKLIST`: la imagen de búsqueda coincidió con un rostro de tu lista de bloqueo facial. |

Nota: cuando la imagen de búsqueda no contiene ningún rostro detectable, la API devuelve HTTP `400` con `{"error": "No face detected in the image"}` **antes** de construir un objeto `face_search`, así que no existe un estado `Declined` para ese caso. Si no hay créditos suficientes, se devuelve HTTP `403` antes de procesar cualquier imagen.

## Ejemplos

### Aprobada: coincidencia duplicada, sin lista de bloqueo

```json theme={null}
{
  "request_id": "5e0c3a1f-7b2d-4c8e-9f10-2a3b4c5d6e7f",
  "face_search": {
    "status": "Approved",
    "total_matches": 1,
    "matches": [
      {
        "session_id": "1f2e3d4c-5b6a-7980-1122-334455667788",
        "session_number": 1024,
        "similarity_percentage": 87.42,
        "source": "session",
        "vendor_data": "user-9",
        "verification_date": "2025-11-20T09:15:00Z",
        "user_details": {
          "full_name": "Jane Marie Doe",
          "document_type": "Passport",
          "document_number": "X1234567"
        },
        "match_image_url": "https://<media-host>/face/9c8b7a6d/reference.jpg?signature=...",
        "status": "Approved",
        "is_blocklisted": false,
        "is_allowlisted": false,
        "api_service": null
      }
    ],
    "user_image": {
      "entities": [
        {
          "bbox": [40, 40, 120, 120],
          "confidence": 0.732973
        }
      ],
      "best_angle": 0
    },
    "warnings": [
      {
        "risk": "DUPLICATED_FACE",
        "feature": "LIVENESS",
        "additional_data": {
          "duplicated_session_id": "1f2e3d4c-5b6a-7980-1122-334455667788",
          "duplicated_session_number": 1024,
          "api_service": null
        },
        "log_type": "information",
        "short_description": "Duplicated face from other approved session",
        "long_description": "The system identified a duplicated face from another approved session, requiring further investigation."
      }
    ]
  },
  "vendor_data": "user-123",
  "metadata": null,
  "created_at": "2026-06-12T01:04:42.763237+00:00"
}
```

### Rechazada: coincidencia con la lista de bloqueo

```json theme={null}
{
  "request_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
  "face_search": {
    "status": "Declined",
    "total_matches": 1,
    "matches": [
      {
        "session_id": "882c42d5-8a4d-4d20-8080-a22f57822c86",
        "session_number": 323442,
        "similarity_percentage": 99.99,
        "source": "session",
        "vendor_data": "user-1",
        "verification_date": "2025-01-01T00:00:00Z",
        "user_details": {
          "full_name": "Jane Marie Doe",
          "document_type": "ID",
          "document_number": "X1234567"
        },
        "match_image_url": "https://<media-host>/face/3f6a1c2e/reference.jpg?signature=...",
        "status": "Approved",
        "is_blocklisted": true,
        "is_allowlisted": false,
        "api_service": "PASSIVE_LIVENESS"
      }
    ],
    "user_image": {
      "entities": [
        {
          "bbox": [40, 40, 120, 120],
          "confidence": 0.732973
        }
      ],
      "best_angle": 0
    },
    "warnings": [
      {
        "risk": "FACE_IN_BLOCKLIST",
        "feature": "LIVENESS",
        "additional_data": {
          "blocklisted_session_id": "882c42d5-8a4d-4d20-8080-a22f57822c86",
          "blocklisted_session_number": 323442,
          "api_service": "PASSIVE_LIVENESS"
        },
        "log_type": "error",
        "short_description": "Face in blocklist",
        "long_description": "The system identified a face in the blocklist, which means the face is not allowed to be verified."
      }
    ]
  },
  "vendor_data": "user-123",
  "metadata": null,
  "created_at": "2026-06-12T01:04:42.763237+00:00"
}
```

## Relacionado

* [Advertencias de Búsqueda facial](https://docs.didit.me/es/core-technology/face-search/warnings-face-search.md): todos los códigos de advertencia que puede emitir la búsqueda
* [Referencia de la API de Búsqueda facial](https://docs.didit.me/es/standalone-apis/face-search.md): parámetros de la solicitud y modos de `search_type`
* [Modelos de datos: Búsqueda facial](https://docs.didit.me/es/reference/data-models.md#búsqueda-facial): esquema canónico
* [Webhooks](https://docs.didit.me/es/integration/webhooks.md): payloads de `status.updated` para sesiones persistidas

> [!NOTE]
>
> Cuando `save_api_request=true`, los valores de `match_image_url` son URL firmadas de corta duración: vuelve a consultar el endpoint de decisión de la sesión con el `request_id` devuelto para obtener otras nuevas. Cuando `save_api_request=false`, son rutas de almacenamiento interno y no se pueden descargar directamente. Guarda en tu sistema solo el id de la sesión coincidente, el estado y `similarity_percentage`; no conserves la imagen biométrica subyacente.


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