> ## 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.

# API de verificación de documentos: OCR y autenticidad

> Didit verifica documentos de más de 220 países y más de 14.000 tipos: autenticidad, OCR, MRZ, menos de 2 s, pago por uso y sin contratos.



## OpenAPI

````yaml es/openapi-25.json POST /v3/id-verification/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: API de verificación de identidad. Autentícate con el encabezado x-api-key.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/id-verification/:
    post:
      tags:
        - Standalone APIs
      summary: Verificación de identidad (OCR del documento + controles de fraude)
      description: >-
        Aplica OCR a un documento de identidad y ejecuta comprobaciones de
        fraude documental en una sola llamada: devuelve los campos extraídos del
        titular, la MRZ analizada, un `status` `Approved`/`Declined`/`In Review`
        y una lista `warnings` que explica cada problema detectado. Admite más
        de 14,000+ tipos de documentos de 220+ países y territorios.


        **Cómo funciona.** Envía la `front_image` del documento (obligatoria) y,
        en documentos de dos caras, la `back_image`. Sube fotos sin recortar en
        las que se vean las cuatro esquinas del documento: el servicio detecta,
        alinea y recorta el documento por sí mismo, así que no lo recortes
        previamente. El documento se clasifica automáticamente (nunca declaras
        el país ni el tipo de documento), la zona visual se lee con OCR y se
        decodifican la MRZ y cualquier código de barras. Después, una serie de
        comprobaciones cruzadas valida las fechas, los formatos de número y los
        dígitos de control de la MRZ, y compara la zona visual con la MRZ. Con
        `perform_document_liveness=true`, las imágenes se analizan además para
        detectar capturas de pantalla, copias impresas y manipulación del
        retrato.


        **Lógica de decisión.** El `status` es `Approved` salvo que al menos una
        advertencia derive en un rechazo. Los riesgos de fraude y de fallo grave
        siempre rechazan: `DOCUMENT_EXPIRED`, `SCREEN_CAPTURE_DETECTED`,
        `PRINTED_COPY_DETECTED`, `PORTRAIT_MANIPULATION_DETECTED`,
        `PUBLIC_DOCUMENT_IMAGE_DETECTED`, además de los fallos de extracción
        (`NAME_NOT_DETECTED`, `DATE_OF_BIRTH_NOT_DETECTED`,
        `DOCUMENT_NUMBER_NOT_DETECTED`). (`PORTRAIT_IMAGE_NOT_DETECTED`,
        `INVALID_DATE` y `MRZ_NOT_DETECTED` existen en las sesiones de flujo de
        verificación (workflow), pero este endpoint independiente nunca los
        genera. `COULD_NOT_DETECT_DOCUMENT_TYPE` se devuelve aquí cuando la
        imagen frontal no coincide con alta confianza con el diseño de un
        documento oficial conocido, y rechaza la solicitud). Tres grupos de
        riesgo se pueden configurar en cada solicitud mediante
        `invalid_mrz_action`, `inconsistent_data_action` y
        `expiration_date_not_detected_action` (`DECLINE` o `NO_ACTION`). Todas
        las demás advertencias (p. ej., `POSSIBLE_DUPLICATED_USER`) son
        informativas y nunca rechazan por sí solas. Cuando
        `perform_document_liveness=true` (el valor predeterminado) y la
        comprobación de falsificación no devuelve una puntuación utilizable (el
        proveedor falló, respondió con un código distinto de 200 o respondió
        HTTP 200 con `status="ERR"`), la llamada devuelve `200` con `status: "In
        Review"` y una advertencia `DOCUMENT_LIVENESS_NOT_COMPUTED` (`log_type:
        "warning"`) en lugar de `Approved`: una comprobación que no se ejecutó
        no es prueba de que el documento sea auténtico. Esta escalada no es
        configurable y nunca anula un `Declined`; con
        `perform_document_liveness=false` la comprobación se omite y el estado
        depende de las demás advertencias, como antes. Un documento que no se
        puede procesar en absoluto devuelve `400` con `{"error":
        "COULD_NOT_RECOGNIZE_DOCUMENT"}`; un documento legible pero con
        problemas devuelve `200` con `status: "Declined"`. Revisa siempre
        `id_verification.status` y `id_verification.warnings`, no solo el código
        HTTP.


        **Facturación.** Cada respuesta `200` consume un crédito de la API de
        Verificación de identidad (se paga con el crédito de tu plan o con tu
        saldo de recarga). Cuando el saldo de la organización no alcanza para
        cubrir la llamada, el endpoint devuelve `403` con el error de créditos
        insuficientes antes de procesar ninguna imagen.


        **Persistencia de la sesión (`save_api_request`, valor predeterminado
        `true`).** Cuando es `true`, la llamada se guarda como una sesión de
        tipo API: aparece en la Business Console, el `request_id` devuelto es un
        ID de sesión real que puedes pasar a `GET
        /v3/session/{sessionId}/decision/`, las imágenes recortadas del
        documento y del retrato se almacenan y se devuelven como URL de medios
        de corta duración (`https://<media-host>/ocr/...`), y se emite un
        webhook `status.updated` a los endpoints de webhook que tengas
        configurados. Cuando es `false`, no se almacena nada, `request_id` es un
        UUID de correlación de un solo uso y
        `portrait_image`/`front_image`/`back_image` se devuelven directamente
        como cadenas JPEG codificadas en base64.


        **Sandbox.** Las claves de API de sandbox omiten todo el procesamiento y
        la facturación: tras validar la solicitud (una entrada mal formada sigue
        devolviendo `400`), el endpoint devuelve un payload simulado estático
        `Approved` (una tarjeta de identidad ficticia de EE. UU. de "Sandbox
        User"), no se guarda ninguna sesión y no se consumen créditos.


        **Autenticación.** Envía la clave de API de tu aplicación en el
        encabezado `x-api-key`. Las credenciales ausentes o no válidas devuelven
        `403` (`{"detail": "You do not have permission to perform this
        action."}`): esta API nunca devuelve `401`.


        **Límite de solicitudes.** Presupuesto de escritura compartido de 300
        solicitudes/min por clave de API entre todos los endpoints
        POST/PATCH/DELETE; si lo superas, se devuelve `429`.
      operationId: post_v3id-verification
      parameters: []
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - front_image
              properties:
                front_image:
                  type: string
                  format: binary
                  description: >-
                    Anverso del documento de identidad. Extensiones permitidas:
                    `tiff`, `jpg`, `jpeg`, `png`, `webp`, `pdf`. Tamaño máximo
                    de carga: **10 MB** (los archivos más grandes se rechazan
                    con `400`). Los PDF se convierten en imagen antes del OCR;
                    los PDF cifrados requieren `front_image_password`. Las
                    imágenes se comprimen automáticamente a ~0.5 MB y se aplica
                    la orientación EXIF. Sube la captura completa, sin recortar,
                    con las cuatro esquinas del documento visibles.
                front_image_password:
                  type: string
                  description: >-
                    Contraseña para descifrar `front_image` cuando es un PDF
                    cifrado. Enviar un PDF cifrado sin contraseña (o con una
                    incorrecta) devuelve `400`.
                  writeOnly: true
                back_image:
                  type: string
                  format: binary
                  description: >-
                    Reverso del documento: envíalo siempre que el documento lo
                    tenga (muchos documentos de identidad llevan la MRZ o un
                    código de barras en el reverso; si lo omites, la MRZ y los
                    campos del reverso simplemente quedan vacíos en la
                    respuesta, y este endpoint no genera una advertencia por
                    falta de MRZ). Mismo formato y límites de tamaño que
                    `front_image`. Si se omite, `back_image` y los campos del
                    reverso son `null` en la respuesta.
                back_image_password:
                  type: string
                  description: >-
                    Contraseña para descifrar `back_image` cuando es un PDF
                    cifrado.
                  writeOnly: true
                perform_document_liveness:
                  type: boolean
                  default: true
                  description: >-
                    Analiza ambas imágenes en busca de fraude de presentación:
                    reproducciones en pantalla (`SCREEN_CAPTURE_DETECTED`),
                    copias impresas (`PRINTED_COPY_DETECTED`) y manipulación del
                    retrato (`PORTRAIT_MANIPULATION_DETECTED`). Cualquiera de
                    ellos provoca un rechazo automático. Está activado por
                    defecto. Establécelo en `false` para omitir el análisis de
                    fraude y reducir la latencia. Si está activado y el
                    proveedor no devuelve una puntuación utilizable, la
                    respuesta es `In Review` con una advertencia
                    `DOCUMENT_LIVENESS_NOT_COMPUTED` en lugar de `Approved`.
                  example: true
                minimum_age:
                  type: integer
                  nullable: true
                  default: null
                  minimum: 1
                  maximum: 120
                  description: >-
                    Se acepta y se valida (1–120), pero **actualmente este
                    endpoint no lo aplica**: nunca genera una advertencia
                    `MINIMUM_AGE_NOT_MET` a partir de este campo. Aplica las
                    reglas de edad a partir de los valores `date_of_birth`/`age`
                    devueltos, o usa un flujo de sesión de verificación con
                    restricciones de edad.
                expiration_date_not_detected_action:
                  type: string
                  enum:
                    - NO_ACTION
                    - DECLINE
                  default: NO_ACTION
                  description: >-
                    Qué hacer cuando no se puede leer ninguna fecha de caducidad
                    (`EXPIRATION_DATE_NOT_DETECTED`). El valor predeterminado es
                    `NO_ACTION` porque muchos documentos de identidad no llevan
                    impresa la fecha de caducidad. Nota: una fecha de caducidad
                    *detectada y ya vencida* siempre provoca el rechazo
                    (`DOCUMENT_EXPIRED`), independientemente de esta opción.
                invalid_mrz_action:
                  type: string
                  enum:
                    - NO_ACTION
                    - DECLINE
                  default: DECLINE
                  description: >-
                    Qué hacer cuando la MRZ extraída no supera la validación de
                    los dígitos de control (`MRZ_VALIDATION_FAILED`). Si falta
                    la MRZ, este endpoint no genera ninguna advertencia. Solo
                    aplica a documentos que incluyen MRZ. `REVIEW` no se admite
                    en este endpoint y devuelve `400`.
                inconsistent_data_action:
                  type: string
                  enum:
                    - NO_ACTION
                    - DECLINE
                  default: DECLINE
                  description: >-
                    Qué hacer cuando los datos extraídos son incoherentes entre
                    sí: `DATA_INCONSISTENT`,
                    `MRZ_AND_DATA_EXTRACTED_FROM_OCR_NOT_SAME` (la zona visual
                    no coincide con la MRZ) o
                    `DOCUMENT_NAME_DIFFERENT_FROM_OTHER_APPROVED_DOCUMENTS`.
                critical_field_occlusion_action:
                  type: string
                  enum:
                    - NO_ACTION
                    - DECLINE
                  default: DECLINE
                  description: >-
                    Qué hacer cuando un campo impreso crítico estaba tapado
                    físicamente en la captura
                    (`CRITICAL_FIELD_OCCLUSION_DETECTED`): un número de
                    identidad, un nombre, la fecha de nacimiento o la fecha de
                    caducidad. Rechaza por defecto, como los demás riesgos de
                    integridad del documento de este endpoint: tapar los números
                    con los que se concilia un informe es justo el aspecto de un
                    documento censurado. En cualquier caso, el valor leído de un
                    campo tapado se elimina de la extracción, por lo que suele
                    ir acompañado de la advertencia `*_NOT_DETECTED`
                    correspondiente. `REVIEW` no es compatible con este endpoint
                    y devuelve `400`.
                document_or_personal_number_format_mismatch_action:
                  type: string
                  enum:
                    - NO_ACTION
                    - DECLINE
                  default: NO_ACTION
                  description: >-
                    Qué hacer cuando un número no coincide con el formato que
                    usa su autoridad emisora para ese tipo de documento
                    (`DOCUMENT_NUMBER_FORMAT_MISMATCH`,
                    `PERSONAL_NUMBER_FORMAT_MISMATCH`). El valor predeterminado
                    es `NO_ACTION`, que informa de la advertencia sin cambiar el
                    estado. `REVIEW` no es compatible con este endpoint y
                    devuelve `400`.
                preferred_characters:
                  type: string
                  enum:
                    - latin
                    - non_latin
                  default: latin
                  description: >-
                    Alfabeto preferido para los campos de nombre y dirección en
                    documentos que imprimen texto tanto latino como no latino
                    (árabe, cirílico, CJK, …). `latin` devuelve valores
                    transliterados o latinos; `non_latin` da preferencia al
                    alfabeto nativo.
                save_api_request:
                  type: boolean
                  default: true
                  description: >-
                    Cuando es `true` (valor predeterminado), guarda la llamada
                    como una sesión de tipo API: visible en la Business Console,
                    recuperable mediante `GET /v3/session/{sessionId}/decision/`
                    con el `request_id` devuelto, notificada mediante un webhook
                    `status.updated` y con las imágenes del documento devueltas
                    como URL de archivos multimedia. Cuando es `false`, no se
                    almacena nada, `request_id` es un UUID temporal y las
                    imágenes se devuelven en la propia respuesta como cadenas
                    JPEG en base64.
                  example: true
                vendor_data:
                  type: string
                  description: >-
                    Cadena opaca opcional (tu ID de usuario interno, correo
                    electrónico, UUID…) que se guarda en la sesión persistida y
                    se devuelve en la respuesta. Úsala para relacionar las
                    llamadas a la API con tus propios registros y para filtrar
                    sesiones más adelante.
                  example: user-123
                metadata:
                  type: object
                  additionalProperties: true
                  description: >-
                    Objeto JSON opcional que se almacena con la sesión (cuando
                    `save_api_request=true`) y se devuelve en la respuesta. En
                    solicitudes multipart, envíalo como un campo de cadena
                    codificado en JSON (p. ej.,
                    `metadata={"flow":"onboarding"}`): se convierte en un
                    objeto.
                  example:
                    flow: onboarding
            example:
              front_image: (binary JPEG/PNG/PDF of the document front)
              back_image: (binary JPEG/PNG/PDF of the document back)
              perform_document_liveness: true
              save_api_request: true
              vendor_data: user-123
              metadata:
                flow: onboarding
      responses:
        '200':
          description: >-
            Documento procesado. `id_verification.status` es `Approved`,
            `Declined` o `In Review`; cada problema detectado se detalla en
            `id_verification.warnings`. Se devuelve `In Review` cuando una
            comprobación de prueba de vida del documento solicitada no produjo
            un resultado utilizable (`DOCUMENT_LIVENESS_NOT_COMPUTED`). Un
            documento con problemas también devuelve `200` con `status:
            "Declined"`: revisa el cuerpo, no solo el código HTTP. Cuando
            `save_api_request=true`, `request_id` es el ID de la sesión guardada
            y los campos de imagen son URL de medios de corta duración; con
            `save_api_request=false` son cadenas JPEG en base64 incluidas en la
            respuesta.
          content:
            application/json:
              examples:
                Approved:
                  summary: >-
                    Documento de identidad de dos caras leído correctamente
                    (guardado: imágenes como URL de medios)
                  value:
                    request_id: 11d219ed-d59c-4b1d-8d65-9b933f12d5b8
                    id_verification:
                      status: Approved
                      document_type: Identity Card
                      document_subtype: ID_CARD_GENERIC
                      document_number: CBX164224
                      personal_number: 20446581H
                      portrait_image: >-
                        https://<media-host>/ocr/11d219ed-d59c-4b1d-8d65-9b933f12d5b8-portrait_image-8c2f.jpg?signature=...
                      front_image: >-
                        https://<media-host>/ocr/11d219ed-d59c-4b1d-8d65-9b933f12d5b8-front_image-4a1e.jpg?signature=...
                      back_image: >-
                        https://<media-host>/ocr/11d219ed-d59c-4b1d-8d65-9b933f12d5b8-back_image-77b0.jpg?signature=...
                      front_image_camera_front: null
                      back_image_camera_front: null
                      front_image_camera_front_face_match_score: null
                      back_image_camera_front_face_match_score: null
                      front_image_quality_score:
                        focus_score: 78
                        brightness_score: 83.2
                        brightness_issue: ok
                        is_document_fully_visible: true
                        resolution_score: 40.7
                        overall_score: 70.2
                      back_image_quality_score:
                        focus_score: 100
                        brightness_score: 95.6
                        brightness_issue: ok
                        is_document_fully_visible: true
                        resolution_score: 43
                        overall_score: 84.4
                      date_of_birth: '1980-01-13'
                      age: 46
                      expiration_date: '2032-03-31'
                      date_of_issue: '2022-03-31'
                      issuing_state: ESP
                      issuing_state_name: Spain
                      first_name: Julio Francisco
                      last_name: Fores Sena
                      full_name: Julio Francisco Fores Sena
                      gender: M
                      address: >-
                        Brda. Urb. El Cardonal 0052 52 Po3 B,Taco,San Cristobal
                        De La Laguna,Santa Cruz De Tenerife
                      formatted_address: >-
                        Av. el Cardonal, 52, b, 38108 La Laguna, Santa Cruz de
                        Tenerife, Spain
                      place_of_birth: Valencia, Valencia
                      marital_status: UNKNOWN
                      nationality: ESP
                      extra_fields:
                        first_surname: Fores
                        second_surname: Sena
                      mrz:
                        surname: FORES SENA
                        name: JULIO FRANCISCO
                        country: ESP
                        nationality: ESP
                        birth_date: '800113'
                        expiry_date: '320331'
                        sex: M
                        document_type: ID
                        document_number: CBX164224
                        optional_data: 20446581H
                        optional_data_2: ''
                        birth_date_hash: '9'
                        expiry_date_hash: '8'
                        document_number_hash: '3'
                        final_hash: '3'
                        personal_number: 20446581H
                        warnings: []
                        errors: []
                        mrz_type: TD1
                        mrz_string: |-
                          IDESPCBX164224320446581H<<<<<<
                          8001139M3203318ESP<<<<<<<<<<<3
                          FORES<SENA<<JULIO<FRANCISCO<<<
                        mrz_key: CBX164224380011393203318
                      parsed_address:
                        street_1: Avenida el Cardonal 52
                        street_2: b
                        city: La Laguna
                        region: Canarias
                        country: ES
                        postal_code: '38108'
                        address_type: Avenida
                        formatted_address: >-
                          Av. el Cardonal, 52, b, 38108 La Laguna, Santa Cruz de
                          Tenerife, Spain
                        raw_results:
                          address_components:
                            - long_name: b
                              short_name: b
                              types:
                                - subpremise
                            - long_name: '52'
                              short_name: '52'
                              types:
                                - street_number
                            - long_name: Avenida el Cardonal
                              short_name: Av. el Cardonal
                              types:
                                - route
                            - long_name: La Laguna
                              short_name: La Laguna
                              types:
                                - locality
                                - political
                            - long_name: Spain
                              short_name: ES
                              types:
                                - country
                                - political
                            - long_name: '38108'
                              short_name: '38108'
                              types:
                                - postal_code
                          formatted_address: >-
                            Av. el Cardonal, 52, b, 38108 La Laguna, Santa Cruz
                            de Tenerife, Spain
                          geometry:
                            location:
                              lat: 28.4501161
                              lng: -16.3004407
                            location_type: ROOFTOP
                          types:
                            - street_address
                            - subpremise
                        document_location:
                          latitude: 28.4501161
                          longitude: -16.3004407
                        label: Spain Identity Card Address
                        is_verified: true
                        category: Residential
                      warnings: []
                      barcodes: []
                    vendor_data: user-123
                    metadata:
                      flow: onboarding
                    created_at: '2026-06-12T02:21:56.013573+00:00'
                Declined - expired document:
                  summary: Carga solo del anverso de un documento de identidad expirado
                  value:
                    request_id: f61681b8-9422-4378-ac3e-04c6a247fb45
                    id_verification:
                      status: Declined
                      document_type: Identity Card
                      document_subtype: ID_CARD_GENERIC
                      document_number: BNK123072
                      personal_number: 21771255F
                      portrait_image: >-
                        https://<media-host>/ocr/f61681b8-9422-4378-ac3e-04c6a247fb45-portrait_image-1d9a.jpg?signature=...
                      front_image: >-
                        https://<media-host>/ocr/f61681b8-9422-4378-ac3e-04c6a247fb45-front_image-5c2b.jpg?signature=...
                      back_image: null
                      front_image_camera_front: null
                      back_image_camera_front: null
                      front_image_camera_front_face_match_score: null
                      back_image_camera_front_face_match_score: null
                      front_image_quality_score:
                        focus_score: 100
                        brightness_score: 95.7
                        brightness_issue: ok
                        is_document_fully_visible: true
                        resolution_score: 22.2
                        overall_score: 79.3
                      back_image_quality_score: null
                      date_of_birth: '1997-01-30'
                      age: 29
                      expiration_date: '2025-11-26'
                      date_of_issue: null
                      issuing_state: ESP
                      issuing_state_name: Spain
                      first_name: Lucia
                      last_name: Marin Castro
                      full_name: Lucia Marin Castro
                      gender: F
                      address: null
                      formatted_address: null
                      place_of_birth: null
                      marital_status: UNKNOWN
                      nationality: ESP
                      extra_fields:
                        first_surname: Marin
                        second_surname: Castro
                      mrz: {}
                      parsed_address: null
                      warnings:
                        - risk: DOCUMENT_EXPIRED
                          feature: ID_VERIFICATION
                          additional_data: null
                          log_type: error
                          short_description: Document expired
                          long_description: >-
                            The document's expiration date has passed, rendering
                            it no longer valid for use.
                      barcodes: []
                    vendor_data: user-123
                    metadata: null
                    created_at: '2026-06-12T02:25:48.117204+00:00'
              schema:
                type: object
                properties:
                  request_id:
                    type: string
                    format: uuid
                    description: >-
                      ID de la sesión guardada cuando `save_api_request=true`
                      (se puede usar con `GET
                      /v3/session/{sessionId}/decision/`); en caso contrario, un
                      UUID de correlación temporal.
                  id_verification:
                    type: object
                    properties:
                      status:
                        type: string
                        enum:
                          - Approved
                          - Declined
                          - In Review
                        description: >-
                          `Approved` cuando ninguna advertencia se resuelve en
                          un rechazo y la comprobación de prueba de vida del
                          documento solicitada produjo un resultado utilizable;
                          `In Review` cuando esa comprobación solicitada no
                          produjo ningún resultado utilizable
                          (`DOCUMENT_LIVENESS_NOT_COMPUTED`); `Declined` cuando
                          una advertencia se resuelve en un rechazo: la lista
                          `warnings` explica el motivo.
                      document_type:
                        type: string
                        nullable: true
                        description: >-
                          Nombre visible del tipo de documento detectado:
                          `Identity Card`, `Passport`, `Driver's License`,
                          `Residence Permit`, `Health Insurance Card` o `Tax
                          Card`. Es `null` cuando el documento no se pudo
                          clasificar.
                        example: Identity Card
                      document_subtype:
                        type: string
                        nullable: true
                        description: >-
                          Subtipo más detallado cuando está disponible (por
                          ejemplo, `ID_CARD_GENERIC`, `EPASSPORT`).
                        example: ID_CARD_GENERIC
                      document_number:
                        type: string
                        nullable: true
                        example: CBX164224
                      personal_number:
                        type: string
                        nullable: true
                        description: >-
                          Número personal/nacional secundario impreso en algunos
                          documentos.
                        example: 20446581H
                      portrait_image:
                        type: string
                        nullable: true
                        description: >-
                          Foto de retrato recortada del documento. Es una URL de
                          medios de corta duración
                          (`https://<media-host>/ocr/...`) cuando
                          `save_api_request=true` (valor por defecto) y una
                          cadena JPEG codificada en base64 en línea cuando
                          `save_api_request=false`. `null` cuando no se detectó
                          ningún retrato.
                      front_image:
                        type: string
                        nullable: true
                        description: >-
                          Recorte alineado del anverso del documento. URL del
                          archivo multimedia si se guardó; en caso contrario,
                          JPEG en base64 en línea.
                      back_image:
                        type: string
                        nullable: true
                        description: >-
                          Recorte alineado del reverso del documento. `null` si
                          no se subió ninguna `back_image`.
                      front_image_camera_front:
                        type: string
                        nullable: true
                        description: >-
                          Siempre `null` en este endpoint (solo se rellena en
                          sesiones de verificación con captura por cámara).
                      back_image_camera_front:
                        type: string
                        nullable: true
                        description: Siempre `null` en este endpoint.
                      front_image_camera_front_face_match_score:
                        type: number
                        nullable: true
                        description: Siempre `null` en este endpoint.
                      back_image_camera_front_face_match_score:
                        type: number
                        nullable: true
                        description: Siempre `null` en este endpoint.
                      front_image_quality_score:
                        type: object
                        nullable: true
                        description: >-
                          Diagnóstico de la calidad de captura de la imagen
                          subida (`null` cuando no se proporcionó esa cara del
                          documento o la puntuación falló). Todas las
                          puntuaciones van de 0 a 100.
                        properties:
                          focus_score:
                            type: number
                            format: float
                            description: >-
                              Nitidez del recorte del documento (cuanto más
                              alto, más nítido).
                          brightness_score:
                            type: number
                            format: float
                            description: Calidad de la exposición (cuanto mayor, mejor).
                          brightness_issue:
                            type: string
                            nullable: true
                            description: >-
                              `ok` cuando la exposición es correcta; en caso
                              contrario, el problema detectado (p. ej.,
                              demasiado oscura o demasiado clara).
                          is_document_fully_visible:
                            type: boolean
                            nullable: true
                            description: >-
                              Indica si las cuatro esquinas del documento están
                              dentro del encuadre.
                          resolution_score:
                            type: number
                            format: float
                            description: Resolución efectiva del área del documento.
                          overall_score:
                            type: number
                            format: float
                            description: Puntuación de calidad agregada.
                      back_image_quality_score:
                        type: object
                        nullable: true
                        description: >-
                          Diagnóstico de la calidad de captura de la imagen
                          subida (`null` cuando no se proporcionó esa cara del
                          documento o la puntuación falló). Todas las
                          puntuaciones van de 0 a 100.
                        properties:
                          focus_score:
                            type: number
                            format: float
                            description: >-
                              Nitidez del recorte del documento (cuanto más
                              alto, más nítido).
                          brightness_score:
                            type: number
                            format: float
                            description: Calidad de la exposición (cuanto mayor, mejor).
                          brightness_issue:
                            type: string
                            nullable: true
                            description: >-
                              `ok` cuando la exposición es correcta; en caso
                              contrario, el problema detectado (p. ej.,
                              demasiado oscura o demasiado clara).
                          is_document_fully_visible:
                            type: boolean
                            nullable: true
                            description: >-
                              Indica si las cuatro esquinas del documento están
                              dentro del encuadre.
                          resolution_score:
                            type: number
                            format: float
                            description: Resolución efectiva del área del documento.
                          overall_score:
                            type: number
                            format: float
                            description: Puntuación de calidad agregada.
                      date_of_birth:
                        type: string
                        format: date
                        nullable: true
                        example: '1980-01-13'
                      age:
                        type: integer
                        nullable: true
                        description: >-
                          Edad del titular en años, calculada a partir de
                          `date_of_birth`.
                        example: 46
                      expiration_date:
                        type: string
                        format: date
                        nullable: true
                        example: '2032-03-31'
                      date_of_issue:
                        type: string
                        format: date
                        nullable: true
                        example: '2022-03-31'
                      issuing_state:
                        type: string
                        nullable: true
                        description: País emisor (ISO 3166-1 alpha-3).
                        example: ESP
                      issuing_state_name:
                        type: string
                        nullable: true
                        example: Spain
                      first_name:
                        type: string
                        nullable: true
                        example: Julio Francisco
                      last_name:
                        type: string
                        nullable: true
                        example: Fores Sena
                      full_name:
                        type: string
                        nullable: true
                        example: Julio Francisco Fores Sena
                      gender:
                        type: string
                        nullable: true
                        description: >-
                          `M`, `F` o `null` cuando no está impreso o no se
                          detectó.
                        example: M
                      address:
                        type: string
                        nullable: true
                        description: Dirección tal como aparece impresa en el documento.
                      formatted_address:
                        type: string
                        nullable: true
                        description: Versión geocodificada y normalizada de `address`.
                      place_of_birth:
                        type: string
                        nullable: true
                        example: Valencia, Valencia
                      marital_status:
                        type: string
                        nullable: true
                        description: >-
                          `UNKNOWN`, salvo que el documento incluya el estado
                          civil.
                        example: UNKNOWN
                      nationality:
                        type: string
                        nullable: true
                        description: Nacionalidad del titular (ISO 3166-1 alfa-3).
                        example: ESP
                      extra_fields:
                        type: object
                        nullable: true
                        additionalProperties: true
                        description: >-
                          Datos adicionales propios del documento que no tienen
                          una columna dedicada (por ejemplo,
                          `first_surname`/`second_surname` en los documentos de
                          identidad españoles o las clases de licencia en las
                          licencias de conducir).
                      mrz:
                        type: object
                        description: >-
                          Zona de lectura mecánica analizada. Es un **objeto
                          vacío** (`{}`) cuando el documento no tiene MRZ o no
                          se pudo leer; en ese caso, revisa también la lista
                          `warnings`. Las fechas dentro de la MRZ usan el
                          formato sin procesar `YYMMDD`.
                        properties:
                          surname:
                            type: string
                            example: FORES SENA
                          name:
                            type: string
                            example: JULIO FRANCISCO
                          country:
                            type: string
                            description: País emisor (ISO 3166-1 alpha-3).
                            example: ESP
                          nationality:
                            type: string
                            description: Nacionalidad del titular (ISO 3166-1 alfa-3).
                            example: ESP
                          birth_date:
                            type: string
                            description: >-
                              Fecha de nacimiento de la MRZ sin procesar
                              (`YYMMDD`).
                            example: '800113'
                          expiry_date:
                            type: string
                            description: >-
                              Fecha de caducidad de la MRZ sin procesar
                              (`YYMMDD`).
                            example: '320331'
                          sex:
                            type: string
                            example: M
                          document_type:
                            type: string
                            description: >-
                              Código de tipo de documento de la MRZ (por
                              ejemplo, `ID`, `P`).
                            example: ID
                          document_number:
                            type: string
                            example: CBX164224
                          optional_data:
                            type: string
                            nullable: true
                            example: 20446581H
                          optional_data_2:
                            type: string
                            nullable: true
                            example: ''
                          birth_date_hash:
                            type: string
                            description: >-
                              Dígito de control de la MRZ para la fecha de
                              nacimiento.
                            example: '9'
                          expiry_date_hash:
                            type: string
                            description: >-
                              Dígito de control de la MRZ para la fecha de
                              caducidad.
                            example: '8'
                          document_number_hash:
                            type: string
                            description: >-
                              Dígito de control de la MRZ para el número de
                              documento.
                            example: '3'
                          final_hash:
                            type: string
                            description: Dígito de control compuesto de la MRZ.
                            example: '3'
                          personal_number:
                            type: string
                            nullable: true
                            example: 20446581H
                          warnings:
                            type: array
                            items:
                              type: string
                            description: Advertencias no críticas del análisis de la MRZ.
                          errors:
                            type: array
                            items:
                              type: string
                            description: >-
                              Errores de dígitos de control o de análisis de la
                              MRZ. Los errores no vacíos aparecen como una
                              advertencia `MRZ_VALIDATION_FAILED`.
                          mrz_type:
                            type: string
                            description: >-
                              Formato de la MRZ: `TD1` (documentos de identidad,
                              3 líneas), `TD2` o `TD3` (pasaportes, 2 líneas).
                            example: TD1
                          mrz_string:
                            type: string
                            description: >-
                              Texto de la MRZ sin procesar tal como se leyó, con
                              las líneas separadas por `\n`.
                          mrz_key:
                            type: string
                            description: >-
                              Clave compuesta (número de documento + dígitos de
                              control) que se usa en las verificaciones
                              cruzadas.
                      parsed_address:
                        type: object
                        nullable: true
                        description: >-
                          Desglose estructurado y geocodificado de `address`.
                          `null` cuando el documento no incluye ninguna
                          dirección o no se pudo analizar.
                        properties:
                          street_1:
                            type: string
                            nullable: true
                            example: Avenida el Cardonal 52
                          street_2:
                            type: string
                            nullable: true
                            example: b
                          city:
                            type: string
                            nullable: true
                            example: La Laguna
                          region:
                            type: string
                            nullable: true
                            example: Canarias
                          country:
                            type: string
                            nullable: true
                            description: Código de país ISO 3166-1 alfa-2.
                            example: ES
                          postal_code:
                            type: string
                            nullable: true
                            example: '38108'
                          address_type:
                            type: string
                            nullable: true
                            example: Avenida
                          formatted_address:
                            type: string
                            nullable: true
                            description: Cadena de dirección geocodificada canónica.
                            example: >-
                              Av. el Cardonal, 52, b, 38108 La Laguna, Santa
                              Cruz de Tenerife, Spain
                          raw_results:
                            type: object
                            additionalProperties: true
                            description: >-
                              Payload de geocodificación sin procesar
                              (`address_components`, `geometry.location`,
                              `place_id`, …) para usos avanzados.
                          document_location:
                            type: object
                            nullable: true
                            properties:
                              latitude:
                                type: number
                              longitude:
                                type: number
                            description: >-
                              Coordenadas geocodificadas de la dirección del
                              documento.
                          label:
                            type: string
                            nullable: true
                            description: De qué campo del documento se leyó la dirección.
                            example: Spain Identity Card Address
                          is_verified:
                            type: boolean
                            description: >-
                              Indica si la geocodificación confirmó que la
                              dirección existe.
                          category:
                            type: string
                            nullable: true
                            description: >-
                              Categoría de la dirección (p. ej., `Residential`,
                              `Commercial`).
                            example: Residential
                      warnings:
                        type: array
                        description: >-
                          Vacío en una aprobación sin incidencias. Cada entrada
                          explica un riesgo detectado; las entradas con
                          `log_type: "error"` establecen `status` en `Declined`,
                          y `DOCUMENT_LIVENESS_NOT_COMPUTED` (`log_type:
                          "warning"`) lo establece en `In Review`.
                        items:
                          type: object
                          properties:
                            risk:
                              type: string
                              description: >-
                                Código de riesgo legible por máquina. Riesgos
                                que siempre rechazan: `DOCUMENT_EXPIRED`,
                                `MINIMUM_AGE_NOT_MET`,
                                `PORTRAIT_IMAGE_NOT_DETECTED`,
                                `SCREEN_CAPTURE_DETECTED`,
                                `PRINTED_COPY_DETECTED`,
                                `PORTRAIT_MANIPULATION_DETECTED`,
                                `PUBLIC_DOCUMENT_IMAGE_DETECTED`,
                                `INVALID_DATE`, `COULD_NOT_RECOGNIZE_DOCUMENT`
                                (solo 400, nunca una advertencia),
                                `DOCUMENT_NUMBER_NOT_DETECTED`,
                                `COULD_NOT_DETECT_DOCUMENT_TYPE`,
                                `NAME_NOT_DETECTED`,
                                `DATE_OF_BIRTH_NOT_DETECTED`. Controlados por
                                opciones de la solicitud: `MRZ_NOT_DETECTED` /
                                `MRZ_VALIDATION_FAILED` (`invalid_mrz_action`),
                                `DATA_INCONSISTENT` /
                                `MRZ_AND_DATA_EXTRACTED_FROM_OCR_NOT_SAME` /
                                `DOCUMENT_NAME_DIFFERENT_FROM_OTHER_APPROVED_DOCUMENTS`
                                (`inconsistent_data_action`),
                                `EXPIRATION_DATE_NOT_DETECTED`
                                (`expiration_date_not_detected_action`). Los
                                demás riesgos (p. ej.,
                                `POSSIBLE_DUPLICATED_USER`) son informativos.
                                `DOCUMENT_LIVENESS_NOT_COMPUTED` se genera
                                cuando `perform_document_liveness=true` pero la
                                comprobación de falsificación no devolvió una
                                puntuación utilizable; establece `status` en `In
                                Review`. `COULD_NOT_DETECT_DOCUMENT_TYPE`
                                también se devuelve cuando el anverso del
                                documento no coincide con un diseño de documento
                                oficial conocido con alta confianza, por
                                ejemplo, un documento editado o generado por
                                computadora, o un diseño que aún no es
                                compatible.
                              example: DOCUMENT_EXPIRED
                            feature:
                              type: string
                              enum:
                                - ID_VERIFICATION
                              description: >-
                                Función que emitió la advertencia. En este
                                endpoint siempre es `ID_VERIFICATION`.
                            additional_data:
                              type: object
                              nullable: true
                              additionalProperties: true
                              description: >-
                                Contexto adicional para algunos riesgos (p. ej.,
                                `POSSIBLE_DUPLICATED_USER` incluye
                                `duplicated_session_id`); `null` para la
                                mayoría.
                            log_type:
                              type: string
                              enum:
                                - error
                                - warning
                                - information
                              description: >-
                                Gravedad. Las advertencias `error` llevan
                                `status` a `Declined`; `warning` (solo
                                `DOCUMENT_LIVENESS_NOT_COMPUTED`, cuando la
                                comprobación de falsificación solicitada no
                                produjo una puntuación utilizable) lleva
                                `status` a `In Review`; las entradas
                                `information` son informativas y nunca cambian
                                el estado.
                            short_description:
                              type: string
                              description: Resumen legible del riesgo en una línea.
                            long_description:
                              type: string
                              description: Explicación legible del riesgo.
                      barcodes:
                        type: array
                        description: >-
                          Códigos de barras decodificados del documento (PDF417,
                          QR, …). Vacío cuando el documento no tiene ninguno o
                          no se pudo leer ninguno.
                        items:
                          type: object
                          properties:
                            type:
                              type: string
                              description: >-
                                Tipo de código de barras (p. ej., `PDF417`,
                                `QR_CODE`, `UNKNOWN`).
                            position:
                              type: object
                              nullable: true
                              additionalProperties: true
                              description: >-
                                Ubicación del código de barras en la imagen,
                                cuando está disponible.
                            data:
                              type: string
                              description: Payload decodificado.
                            data_raw:
                              type: string
                              description: >-
                                Payload sin procesar (sin decodificar), cuando
                                es distinto.
                            side:
                              type: string
                              nullable: true
                              description: '`front` o `back`.'
                  vendor_data:
                    type: string
                    nullable: true
                    description: Devuelve el `vendor_data` que enviaste, o `null`.
                  metadata:
                    type: object
                    nullable: true
                    additionalProperties: true
                    description: Devuelve el objeto `metadata` que enviaste, o `null`.
                  created_at:
                    type: string
                    format: date-time
                    description: >-
                      Marca de tiempo ISO 8601 (UTC) del momento en que se
                      generó la respuesta.
        '400':
          description: >-
            Error de validación o de procesamiento. Los problemas a nivel de
            campo devuelven el formato estándar de DRF (un array de mensajes por
            cada campo afectado). Los problemas con PDF cifrados devuelven
            `{"detail": ...}`. Una imagen de documento en la que no se puede
            reconocer ningún documento devuelve `{"error":
            "COULD_NOT_RECOGNIZE_DOCUMENT"}`. Las cargas de PDF también pueden
            fallar con "The submitted PDF file is corrupted or invalid." o con
            un error por ausencia de páginas.
          content:
            application/json:
              examples:
                Missing front image:
                  summary: '`front_image` no se incluyó en los datos del formulario'
                  value:
                    front_image:
                      - No file was submitted.
                Unsupported file extension:
                  summary: Extensión de archivo distinta de tiff/jpg/jpeg/png/webp/pdf
                  value:
                    front_image:
                      - >-
                        File extension “txt” is not allowed. Allowed extensions
                        are: tiff, jpg, jpeg, png, webp, pdf.
                File too large:
                  summary: El archivo supera el límite de 10 MB
                  value:
                    front_image:
                      - File size should not exceed 10 MB
                Invalid option value:
                  summary: Las opciones solo aceptan DECLINE o NO_ACTION
                  value:
                    invalid_mrz_action:
                      - '"REVIEW" is not a valid choice.'
                Encrypted PDF:
                  summary: PDF subido sin la contraseña requerida
                  value:
                    detail: >-
                      The PDF is encrypted. Please upload a decrypted PDF or a
                      photo instead.
                Wrong PDF password:
                  summary: >-
                    `front_image_password` / `back_image_password` no descifra
                    el PDF
                  value:
                    detail: >-
                      The PDF password is incorrect. Please provide the correct
                      password.
                Document not recognized:
                  summary: >-
                    No se pudo detectar ningún documento de identidad en la
                    imagen
                  value:
                    error: COULD_NOT_RECOGNIZE_DOCUMENT
                PDF conversion failure:
                  summary: No se pudo convertir el PDF subido en una imagen
                  value:
                    error: Failed to convert front image PDF.
        '403':
          description: >-
            Permiso denegado. Se devuelve cuando falta el encabezado `x-api-key`
            y también cuando el saldo de la organización que realiza la llamada
            no la cubre; una clave incorrecta, revocada o expirada devuelve
            `401`. Si falta la clave, se devuelve `403` con `{"detail": ...}`;
            una clave incorrecta, revocada o expirada devuelve `401`. La falta
            de créditos devuelve `403` con `{"error": ...}` antes de que se
            procese ninguna imagen.
          content:
            application/json:
              examples:
                Missing or invalid API key:
                  summary: >-
                    Falta el encabezado `x-api-key`, o la clave no es válida o
                    está revocada
                  value:
                    detail: You do not have permission to perform this action.
                Not enough credits:
                  summary: El saldo de la organización no cubre la llamada
                  value:
                    error: >-
                      You don't have enough credits to perform this request.
                      Please top up at https://business.didit.me
        '429':
          description: >-
            Límite de solicitudes superado. Todos los endpoints
            POST/PATCH/DELETE comparten un presupuesto de 300 solicitudes de
            escritura por minuto por clave de API. La respuesta incluye los
            encabezados `X-RateLimit-Limit`, `X-RateLimit-Remaining`,
            `X-RateLimit-Reset` y `Retry-After`.
          content:
            application/json:
              examples:
                Write rate limit exceeded:
                  summary: Más de 300 solicitudes de escritura en el minuto actual
                  value:
                    detail: >-
                      Write request rate limit exceeded. You can make up to 300
                      requests per minute.
              schema:
                type: object
                properties:
                  detail:
                    type: string
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: cURL
          source: |-
            curl -X POST 'https://verification.didit.me/v3/id-verification/' \
              -H 'x-api-key: YOUR_API_KEY' \
              -F 'front_image=@./id_front.jpg' \
              -F 'back_image=@./id_back.jpg' \
              -F 'perform_document_liveness=true' \
              -F 'save_api_request=true' \
              -F 'vendor_data=user-123'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.id_verification.verify(
                front_image=open("front_image.jpg", "rb"),
                back_image=open("back_image.jpg", "rb"),
                perform_document_liveness=True,
                save_api_request=True,
                vendor_data="user-123",
                metadata={"flow": "onboarding"},
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: |-
            import Didit, { fileFromPath } from "@didit-protocol/sdk-node";

            // Reads DIDIT_API_KEY.
            const didit = new Didit();

            const result = await didit.idVerification.verify({
              front_image: await fileFromPath("front_image.jpg"),
              back_image: await fileFromPath("back_image.jpg"),
              perform_document_liveness: true,
              save_api_request: true,
              vendor_data: "user-123",
              metadata: { flow: "onboarding" },
            });
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDVerification.Verify(ctx, didit.IDVerificationVerifyParams{\n\tFrontImage:              didit.FileFromPath(\"front_image.jpg\"),\n\tBackImage:               didit.Some(didit.FileFromPath(\"back_image.jpg\")),\n\tPerformDocumentLiveness: didit.Bool(true),\n\tSaveAPIRequest:          didit.Bool(true),\n\tVendorData:              didit.String(\"user-123\"),\n\tMetadata:                didit.Some(map[string]any{\"flow\": \"onboarding\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: >-
            import java.nio.file.Path;

            import java.util.Map;

            import me.didit.Didit;

            import me.didit.types.IdVerificationVerifyParams;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.idVerification().verify(IdVerificationVerifyParams.builder()
                    .frontImage(Path.of("front_image.jpg"))
                    .backImage(Path.of("back_image.jpg"))
                    .performDocumentLiveness(true)
                    .saveApiRequest(true)
                    .vendorData("user-123")
                    .metadata(Map.of("flow", "onboarding"))
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: |-
            <?php

            require 'vendor/autoload.php';

            use Didit\DiditClient;
            use Didit\File;

            // Reads DIDIT_API_KEY.
            $didit = new DiditClient();

            $result = $didit->idVerification->verify([
                'front_image' => File::fromPath('front_image.jpg'),
                'back_image' => File::fromPath('back_image.jpg'),
                'perform_document_liveness' => true,
                'save_api_request' => true,
                'vendor_data' => 'user-123',
                'metadata' => ['flow' => 'onboarding'],
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

            # Reads DIDIT_API_KEY.
            didit = Didit::Client.new

            result = didit.id_verification.verify(
              front_image: Pathname("front_image.jpg"),
              back_image: Pathname("back_image.jpg"),
              perform_document_liveness: true,
              save_api_request: true,
              vendor_data: "user-123",
              metadata: { flow: "onboarding" }
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: >-
            using System;

            using System.Collections.Generic;

            using System.Text.Json;

            using Didit;


            // Reads DIDIT_API_KEY.

            using var client = new DiditClient();


            var result = await client.IdVerification.VerifyAsync(new
            IdVerificationVerifyParams

            {
                FrontImage = FileUpload.FromPath("front_image.jpg"),
                BackImage = FileUpload.FromPath("back_image.jpg"),
                PerformDocumentLiveness = true,
                SaveApiRequest = true,
                VendorData = "user-123",
                Metadata = new Dictionary<string, object> { ["flow"] = "onboarding" },
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        La clave de API de tu aplicación, que encontrarás en Developers -> API
        keys en la Business Console. La clave principal tiene acceso completo.
        Una clave con nombre puede tener un alcance limitado: ninguno, lectura o
        escritura por recurso, limitada a algunos flujos o a sesiones aprobadas,
        a una lista de direcciones IP y a una fecha de caducidad. 401 significa
        que la clave es incorrecta, se revocó o expiró; 403 significa que no se
        envió ninguna clave, que la clave no tiene acceso a este recurso o
        acción, o que la solicitud provino de una dirección fuera de su lista de
        IP; 404 en una ruta de sesión significa que la sesión está fuera de los
        flujos o estados de la clave. Una clave sin acceso a contenido
        multimedia recibe las URL de imágenes, videos y PDF como null, y una
        clave sin permiso de escritura en sesiones recibe los enlaces y tokens
        de sesión como null. Consulta https://docs.didit.me/console/api-keys.

````

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